OLD | NEW |
1 /* | 1 /* |
2 * drivers/net/wireless/mwl8k.c | 2 * drivers/net/wireless/mwl8k.c |
3 * Driver for Marvell TOPDOG 802.11 Wireless cards | 3 * Driver for Marvell TOPDOG 802.11 Wireless cards |
4 * | 4 * |
5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc. | 5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc. |
6 * | 6 * |
7 * This file is licensed under the terms of the GNU General Public | 7 * This file is licensed under the terms of the GNU General Public |
8 * License version 2. This program is licensed "as is" without any | 8 * License version 2. This program is licensed "as is" without any |
9 * warranty of any kind, whether express or implied. | 9 * warranty of any kind, whether express or implied. |
10 */ | 10 */ |
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 int i; | 903 int i; |
904 | 904 |
905 rxq->rxd_count = 0; | 905 rxq->rxd_count = 0; |
906 rxq->head = 0; | 906 rxq->head = 0; |
907 rxq->tail = 0; | 907 rxq->tail = 0; |
908 | 908 |
909 size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size; | 909 size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size; |
910 | 910 |
911 rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); | 911 rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); |
912 if (rxq->rxd == NULL) { | 912 if (rxq->rxd == NULL) { |
913 » » wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n"); | 913 » » wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n"); |
914 return -ENOMEM; | 914 return -ENOMEM; |
915 } | 915 } |
916 memset(rxq->rxd, 0, size); | 916 memset(rxq->rxd, 0, size); |
917 | 917 |
918 rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); | 918 rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); |
919 if (rxq->buf == NULL) { | 919 if (rxq->buf == NULL) { |
920 » » wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n"); | 920 » » wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n"); |
921 pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); | 921 pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); |
922 return -ENOMEM; | 922 return -ENOMEM; |
923 } | 923 } |
924 memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf)); | 924 memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf)); |
925 | 925 |
926 for (i = 0; i < MWL8K_RX_DESCS; i++) { | 926 for (i = 0; i < MWL8K_RX_DESCS; i++) { |
927 int desc_size; | 927 int desc_size; |
928 void *rxd; | 928 void *rxd; |
929 int nexti; | 929 int nexti; |
930 dma_addr_t next_dma_addr; | 930 dma_addr_t next_dma_addr; |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 int i; | 1138 int i; |
1139 | 1139 |
1140 txq->len = 0; | 1140 txq->len = 0; |
1141 txq->head = 0; | 1141 txq->head = 0; |
1142 txq->tail = 0; | 1142 txq->tail = 0; |
1143 | 1143 |
1144 size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc); | 1144 size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc); |
1145 | 1145 |
1146 txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); | 1146 txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); |
1147 if (txq->txd == NULL) { | 1147 if (txq->txd == NULL) { |
1148 » » wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n"); | 1148 » » wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n"); |
1149 return -ENOMEM; | 1149 return -ENOMEM; |
1150 } | 1150 } |
1151 memset(txq->txd, 0, size); | 1151 memset(txq->txd, 0, size); |
1152 | 1152 |
1153 txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); | 1153 txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); |
1154 if (txq->skb == NULL) { | 1154 if (txq->skb == NULL) { |
1155 » » wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n"); | 1155 » » wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n"); |
1156 pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); | 1156 pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); |
1157 return -ENOMEM; | 1157 return -ENOMEM; |
1158 } | 1158 } |
1159 memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb)); | 1159 memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb)); |
1160 | 1160 |
1161 for (i = 0; i < MWL8K_TX_DESCS; i++) { | 1161 for (i = 0; i < MWL8K_TX_DESCS; i++) { |
1162 struct mwl8k_tx_desc *tx_desc; | 1162 struct mwl8k_tx_desc *tx_desc; |
1163 int nexti; | 1163 int nexti; |
1164 | 1164 |
1165 tx_desc = txq->txd + i; | 1165 tx_desc = txq->txd + i; |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS)); | 1566 msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS)); |
1567 | 1567 |
1568 priv->hostcmd_wait = NULL; | 1568 priv->hostcmd_wait = NULL; |
1569 | 1569 |
1570 mwl8k_fw_unlock(hw); | 1570 mwl8k_fw_unlock(hw); |
1571 | 1571 |
1572 pci_unmap_single(priv->pdev, dma_addr, dma_size, | 1572 pci_unmap_single(priv->pdev, dma_addr, dma_size, |
1573 PCI_DMA_BIDIRECTIONAL); | 1573 PCI_DMA_BIDIRECTIONAL); |
1574 | 1574 |
1575 if (!timeout) { | 1575 if (!timeout) { |
1576 » » wiphy_err(hw->wiphy, "command %s timeout after %u ms\n", | 1576 » » wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n", |
1577 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | 1577 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), |
1578 MWL8K_CMD_TIMEOUT_MS); | 1578 MWL8K_CMD_TIMEOUT_MS); |
1579 rc = -ETIMEDOUT; | 1579 rc = -ETIMEDOUT; |
1580 } else { | 1580 } else { |
1581 int ms; | 1581 int ms; |
1582 | 1582 |
1583 ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout); | 1583 ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout); |
1584 | 1584 |
1585 rc = cmd->result ? -EINVAL : 0; | 1585 rc = cmd->result ? -EINVAL : 0; |
1586 if (rc) | 1586 if (rc) |
1587 » » » wiphy_err(hw->wiphy, "command %s error 0x%x\n", | 1587 » » » wiphy_err(hw->wiphy, "Command %s error 0x%x\n", |
1588 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | 1588 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), |
1589 le16_to_cpu(cmd->result)); | 1589 le16_to_cpu(cmd->result)); |
1590 else if (ms > 2000) | 1590 else if (ms > 2000) |
1591 » » » wiphy_notice(hw->wiphy, "command %s took %d ms\n", | 1591 » » » wiphy_notice(hw->wiphy, "Command %s took %d ms\n", |
1592 mwl8k_cmd_name(cmd->code, | 1592 mwl8k_cmd_name(cmd->code, |
1593 buf, sizeof(buf)), | 1593 buf, sizeof(buf)), |
1594 ms); | 1594 ms); |
1595 } | 1595 } |
1596 | 1596 |
1597 return rc; | 1597 return rc; |
1598 } | 1598 } |
1599 | 1599 |
1600 static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw, | 1600 static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw, |
1601 struct ieee80211_vif *vif, | 1601 struct ieee80211_vif *vif, |
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3223 } | 3223 } |
3224 | 3224 |
3225 static int mwl8k_start(struct ieee80211_hw *hw) | 3225 static int mwl8k_start(struct ieee80211_hw *hw) |
3226 { | 3226 { |
3227 struct mwl8k_priv *priv = hw->priv; | 3227 struct mwl8k_priv *priv = hw->priv; |
3228 int rc; | 3228 int rc; |
3229 | 3229 |
3230 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 3230 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
3231 IRQF_SHARED, MWL8K_NAME, hw); | 3231 IRQF_SHARED, MWL8K_NAME, hw); |
3232 if (rc) { | 3232 if (rc) { |
3233 » » wiphy_err(hw->wiphy, "failed to register irq handler\n"); | 3233 » » wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); |
3234 return -EIO; | 3234 return -EIO; |
3235 } | 3235 } |
3236 | 3236 |
3237 /* Enable TX reclaim and RX tasklets. */ | 3237 /* Enable TX reclaim and RX tasklets. */ |
3238 tasklet_enable(&priv->poll_tx_task); | 3238 tasklet_enable(&priv->poll_tx_task); |
3239 tasklet_enable(&priv->poll_rx_task); | 3239 tasklet_enable(&priv->poll_rx_task); |
3240 | 3240 |
3241 /* Enable interrupts */ | 3241 /* Enable interrupts */ |
3242 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); | 3242 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
3243 | 3243 |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3951 pci_set_drvdata(pdev, hw); | 3951 pci_set_drvdata(pdev, hw); |
3952 | 3952 |
3953 priv = hw->priv; | 3953 priv = hw->priv; |
3954 priv->hw = hw; | 3954 priv->hw = hw; |
3955 priv->pdev = pdev; | 3955 priv->pdev = pdev; |
3956 priv->device_info = &mwl8k_info_tbl[id->driver_data]; | 3956 priv->device_info = &mwl8k_info_tbl[id->driver_data]; |
3957 | 3957 |
3958 | 3958 |
3959 priv->sram = pci_iomap(pdev, 0, 0x10000); | 3959 priv->sram = pci_iomap(pdev, 0, 0x10000); |
3960 if (priv->sram == NULL) { | 3960 if (priv->sram == NULL) { |
3961 » » wiphy_err(hw->wiphy, "cannot map device sram\n"); | 3961 » » wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); |
3962 goto err_iounmap; | 3962 goto err_iounmap; |
3963 } | 3963 } |
3964 | 3964 |
3965 /* | 3965 /* |
3966 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1. | 3966 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1. |
3967 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2. | 3967 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2. |
3968 */ | 3968 */ |
3969 priv->regs = pci_iomap(pdev, 1, 0x10000); | 3969 priv->regs = pci_iomap(pdev, 1, 0x10000); |
3970 if (priv->regs == NULL) { | 3970 if (priv->regs == NULL) { |
3971 priv->regs = pci_iomap(pdev, 2, 0x10000); | 3971 priv->regs = pci_iomap(pdev, 2, 0x10000); |
3972 if (priv->regs == NULL) { | 3972 if (priv->regs == NULL) { |
3973 » » » wiphy_err(hw->wiphy, "cannot map device registers\n"); | 3973 » » » wiphy_err(hw->wiphy, "Cannot map device registers\n"); |
3974 goto err_iounmap; | 3974 goto err_iounmap; |
3975 } | 3975 } |
3976 } | 3976 } |
3977 | 3977 |
3978 | 3978 |
3979 /* Reset firmware and hardware */ | 3979 /* Reset firmware and hardware */ |
3980 mwl8k_hw_reset(priv); | 3980 mwl8k_hw_reset(priv); |
3981 | 3981 |
3982 /* Ask userland hotplug daemon for the device firmware */ | 3982 /* Ask userland hotplug daemon for the device firmware */ |
3983 rc = mwl8k_request_firmware(priv); | 3983 rc = mwl8k_request_firmware(priv); |
3984 if (rc) { | 3984 if (rc) { |
3985 » » wiphy_err(hw->wiphy, "firmware files not found\n"); | 3985 » » wiphy_err(hw->wiphy, "Firmware files not found\n"); |
3986 goto err_stop_firmware; | 3986 goto err_stop_firmware; |
3987 } | 3987 } |
3988 | 3988 |
3989 /* Load firmware into hardware */ | 3989 /* Load firmware into hardware */ |
3990 rc = mwl8k_load_firmware(hw); | 3990 rc = mwl8k_load_firmware(hw); |
3991 if (rc) { | 3991 if (rc) { |
3992 » » wiphy_err(hw->wiphy, "cannot start firmware\n"); | 3992 » » wiphy_err(hw->wiphy, "Cannot start firmware\n"); |
3993 goto err_stop_firmware; | 3993 goto err_stop_firmware; |
3994 } | 3994 } |
3995 | 3995 |
3996 /* Reclaim memory once firmware is successfully loaded */ | 3996 /* Reclaim memory once firmware is successfully loaded */ |
3997 mwl8k_release_firmware(priv); | 3997 mwl8k_release_firmware(priv); |
3998 | 3998 |
3999 | 3999 |
4000 if (priv->ap_fw) { | 4000 if (priv->ap_fw) { |
4001 priv->rxd_ops = priv->device_info->ap_rxd_ops; | 4001 priv->rxd_ops = priv->device_info->ap_rxd_ops; |
4002 if (priv->rxd_ops == NULL) { | 4002 if (priv->rxd_ops == NULL) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4072 | 4072 |
4073 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); | 4073 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); |
4074 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); | 4074 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
4075 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY, | 4075 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY, |
4076 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); | 4076 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); |
4077 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | 4077 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); |
4078 | 4078 |
4079 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 4079 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
4080 IRQF_SHARED, MWL8K_NAME, hw); | 4080 IRQF_SHARED, MWL8K_NAME, hw); |
4081 if (rc) { | 4081 if (rc) { |
4082 » » wiphy_err(hw->wiphy, "failed to register irq handler\n"); | 4082 » » wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); |
4083 goto err_free_queues; | 4083 goto err_free_queues; |
4084 } | 4084 } |
4085 | 4085 |
4086 /* | 4086 /* |
4087 * Temporarily enable interrupts. Initial firmware host | 4087 * Temporarily enable interrupts. Initial firmware host |
4088 * commands use interrupts and avoid polling. Disable | 4088 * commands use interrupts and avoid polling. Disable |
4089 * interrupts when done. | 4089 * interrupts when done. |
4090 */ | 4090 */ |
4091 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); | 4091 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
4092 | 4092 |
4093 /* Get config data, mac addrs etc */ | 4093 /* Get config data, mac addrs etc */ |
4094 if (priv->ap_fw) { | 4094 if (priv->ap_fw) { |
4095 rc = mwl8k_cmd_get_hw_spec_ap(hw); | 4095 rc = mwl8k_cmd_get_hw_spec_ap(hw); |
4096 if (!rc) | 4096 if (!rc) |
4097 rc = mwl8k_cmd_set_hw_spec(hw); | 4097 rc = mwl8k_cmd_set_hw_spec(hw); |
4098 } else { | 4098 } else { |
4099 rc = mwl8k_cmd_get_hw_spec_sta(hw); | 4099 rc = mwl8k_cmd_get_hw_spec_sta(hw); |
4100 } | 4100 } |
4101 if (rc) { | 4101 if (rc) { |
4102 » » wiphy_err(hw->wiphy, "cannot initialise firmware\n"); | 4102 » » wiphy_err(hw->wiphy, "Cannot initialise firmware\n"); |
4103 goto err_free_irq; | 4103 goto err_free_irq; |
4104 } | 4104 } |
4105 | 4105 |
4106 hw->wiphy->interface_modes = 0; | 4106 hw->wiphy->interface_modes = 0; |
4107 if (priv->ap_macids_supported) | 4107 if (priv->ap_macids_supported) |
4108 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); | 4108 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); |
4109 if (priv->sta_macids_supported) | 4109 if (priv->sta_macids_supported) |
4110 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); | 4110 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); |
4111 | 4111 |
4112 | 4112 |
4113 /* Turn radio off */ | 4113 /* Turn radio off */ |
4114 rc = mwl8k_cmd_radio_disable(hw); | 4114 rc = mwl8k_cmd_radio_disable(hw); |
4115 if (rc) { | 4115 if (rc) { |
4116 » » wiphy_err(hw->wiphy, "cannot disable\n"); | 4116 » » wiphy_err(hw->wiphy, "Cannot disable\n"); |
4117 goto err_free_irq; | 4117 goto err_free_irq; |
4118 } | 4118 } |
4119 | 4119 |
4120 /* Clear MAC address */ | 4120 /* Clear MAC address */ |
4121 rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); | 4121 rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); |
4122 if (rc) { | 4122 if (rc) { |
4123 » » wiphy_err(hw->wiphy, "cannot clear mac address\n"); | 4123 » » wiphy_err(hw->wiphy, "Cannot clear MAC address\n"); |
4124 goto err_free_irq; | 4124 goto err_free_irq; |
4125 } | 4125 } |
4126 | 4126 |
4127 /* Disable interrupts */ | 4127 /* Disable interrupts */ |
4128 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); | 4128 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
4129 free_irq(priv->pdev->irq, hw); | 4129 free_irq(priv->pdev->irq, hw); |
4130 | 4130 |
4131 rc = ieee80211_register_hw(hw); | 4131 rc = ieee80211_register_hw(hw); |
4132 if (rc) { | 4132 if (rc) { |
4133 » » wiphy_err(hw->wiphy, "cannot register device\n"); | 4133 » » wiphy_err(hw->wiphy, "Cannot register device\n"); |
4134 goto err_free_queues; | 4134 goto err_free_queues; |
4135 } | 4135 } |
4136 | 4136 |
4137 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", | 4137 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", |
4138 priv->device_info->part_name, | 4138 priv->device_info->part_name, |
4139 priv->hw_rev, hw->wiphy->perm_addr, | 4139 priv->hw_rev, hw->wiphy->perm_addr, |
4140 priv->ap_fw ? "AP" : "STA", | 4140 priv->ap_fw ? "AP" : "STA", |
4141 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, | 4141 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, |
4142 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); | 4142 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); |
4143 | 4143 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4243 pci_unregister_driver(&mwl8k_driver); | 4243 pci_unregister_driver(&mwl8k_driver); |
4244 } | 4244 } |
4245 | 4245 |
4246 module_init(mwl8k_init); | 4246 module_init(mwl8k_init); |
4247 module_exit(mwl8k_exit); | 4247 module_exit(mwl8k_exit); |
4248 | 4248 |
4249 MODULE_DESCRIPTION(MWL8K_DESC); | 4249 MODULE_DESCRIPTION(MWL8K_DESC); |
4250 MODULE_VERSION(MWL8K_VERSION); | 4250 MODULE_VERSION(MWL8K_VERSION); |
4251 MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>"); | 4251 MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>"); |
4252 MODULE_LICENSE("GPL"); | 4252 MODULE_LICENSE("GPL"); |
OLD | NEW |