aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorBrian Cavagnolo <brian@cozybit.com>2010-11-12 20:23:49 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-16 16:37:02 -0500
commit3cc7772c0a3cc193fa9873816168bd34d4f16837 (patch)
tree1c87d998fd922f0f18d2694759513b2fcc454ed5 /drivers/net/wireless/mwl8k.c
parent41fdf0974d9eb81215cb578211a6d8f8a022a9eb (diff)
mwl8k: factor out firmware loading and hw init code
This is in preparation for supporting different fw images for different interface types, and for supporting asynchronous firmware loading. Based on a patch from Pradeep Nemavat <pnemavat@marvell.com> and Yogesh Powar <yogeshp@marvell.com> Signed-off-by: Brian Cavagnolo <brian@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c345
1 files changed, 214 insertions, 131 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index cfda87a595e3..7bd861586983 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -3942,73 +3942,10 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
3942}; 3942};
3943MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); 3943MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
3944 3944
3945static int __devinit mwl8k_probe(struct pci_dev *pdev, 3945static int mwl8k_init_firmware(struct ieee80211_hw *hw)
3946 const struct pci_device_id *id)
3947{ 3946{
3948 static int printed_version = 0; 3947 struct mwl8k_priv *priv = hw->priv;
3949 struct ieee80211_hw *hw;
3950 struct mwl8k_priv *priv;
3951 int rc; 3948 int rc;
3952 int i;
3953
3954 if (!printed_version) {
3955 printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
3956 printed_version = 1;
3957 }
3958
3959
3960 rc = pci_enable_device(pdev);
3961 if (rc) {
3962 printk(KERN_ERR "%s: Cannot enable new PCI device\n",
3963 MWL8K_NAME);
3964 return rc;
3965 }
3966
3967 rc = pci_request_regions(pdev, MWL8K_NAME);
3968 if (rc) {
3969 printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
3970 MWL8K_NAME);
3971 goto err_disable_device;
3972 }
3973
3974 pci_set_master(pdev);
3975
3976
3977 hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
3978 if (hw == NULL) {
3979 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
3980 rc = -ENOMEM;
3981 goto err_free_reg;
3982 }
3983
3984 SET_IEEE80211_DEV(hw, &pdev->dev);
3985 pci_set_drvdata(pdev, hw);
3986
3987 priv = hw->priv;
3988 priv->hw = hw;
3989 priv->pdev = pdev;
3990 priv->device_info = &mwl8k_info_tbl[id->driver_data];
3991
3992
3993 priv->sram = pci_iomap(pdev, 0, 0x10000);
3994 if (priv->sram == NULL) {
3995 wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
3996 goto err_iounmap;
3997 }
3998
3999 /*
4000 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
4001 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
4002 */
4003 priv->regs = pci_iomap(pdev, 1, 0x10000);
4004 if (priv->regs == NULL) {
4005 priv->regs = pci_iomap(pdev, 2, 0x10000);
4006 if (priv->regs == NULL) {
4007 wiphy_err(hw->wiphy, "Cannot map device registers\n");
4008 goto err_iounmap;
4009 }
4010 }
4011
4012 3949
4013 /* Reset firmware and hardware */ 3950 /* Reset firmware and hardware */
4014 mwl8k_hw_reset(priv); 3951 mwl8k_hw_reset(priv);
@@ -4017,19 +3954,26 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
4017 rc = mwl8k_request_firmware(priv); 3954 rc = mwl8k_request_firmware(priv);
4018 if (rc) { 3955 if (rc) {
4019 wiphy_err(hw->wiphy, "Firmware files not found\n"); 3956 wiphy_err(hw->wiphy, "Firmware files not found\n");
4020 goto err_stop_firmware; 3957 return rc;
4021 } 3958 }
4022 3959
4023 /* Load firmware into hardware */ 3960 /* Load firmware into hardware */
4024 rc = mwl8k_load_firmware(hw); 3961 rc = mwl8k_load_firmware(hw);
4025 if (rc) { 3962 if (rc)
4026 wiphy_err(hw->wiphy, "Cannot start firmware\n"); 3963 wiphy_err(hw->wiphy, "Cannot start firmware\n");
4027 goto err_stop_firmware;
4028 }
4029 3964
4030 /* Reclaim memory once firmware is successfully loaded */ 3965 /* Reclaim memory once firmware is successfully loaded */
4031 mwl8k_release_firmware(priv); 3966 mwl8k_release_firmware(priv);
4032 3967
3968 return rc;
3969}
3970
3971/* initialize hw after successfully loading a firmware image */
3972static int mwl8k_probe_hw(struct ieee80211_hw *hw)
3973{
3974 struct mwl8k_priv *priv = hw->priv;
3975 int rc = 0;
3976 int i;
4033 3977
4034 if (priv->ap_fw) { 3978 if (priv->ap_fw) {
4035 priv->rxd_ops = priv->device_info->ap_rxd_ops; 3979 priv->rxd_ops = priv->device_info->ap_rxd_ops;
@@ -4046,58 +3990,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
4046 priv->wmm_enabled = false; 3990 priv->wmm_enabled = false;
4047 priv->pending_tx_pkts = 0; 3991 priv->pending_tx_pkts = 0;
4048 3992
4049
4050 /*
4051 * Extra headroom is the size of the required DMA header
4052 * minus the size of the smallest 802.11 frame (CTS frame).
4053 */
4054 hw->extra_tx_headroom =
4055 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
4056
4057 hw->channel_change_time = 10;
4058
4059 hw->queues = MWL8K_TX_QUEUES;
4060
4061 /* Set rssi values to dBm */
4062 hw->flags |= IEEE80211_HW_SIGNAL_DBM;
4063 hw->vif_data_size = sizeof(struct mwl8k_vif);
4064 hw->sta_data_size = sizeof(struct mwl8k_sta);
4065
4066 priv->macids_used = 0;
4067 INIT_LIST_HEAD(&priv->vif_list);
4068
4069 /* Set default radio state and preamble */
4070 priv->radio_on = 0;
4071 priv->radio_short_preamble = 0;
4072
4073 /* Finalize join worker */
4074 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
4075
4076 /* TX reclaim and RX tasklets. */
4077 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
4078 tasklet_disable(&priv->poll_tx_task);
4079 tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
4080 tasklet_disable(&priv->poll_rx_task);
4081
4082 /* Power management cookie */
4083 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
4084 if (priv->cookie == NULL)
4085 goto err_stop_firmware;
4086
4087 rc = mwl8k_rxq_init(hw, 0); 3993 rc = mwl8k_rxq_init(hw, 0);
4088 if (rc) 3994 if (rc)
4089 goto err_free_cookie; 3995 goto err_stop_firmware;
4090 rxq_refill(hw, 0, INT_MAX); 3996 rxq_refill(hw, 0, INT_MAX);
4091 3997
4092 mutex_init(&priv->fw_mutex);
4093 priv->fw_mutex_owner = NULL;
4094 priv->fw_mutex_depth = 0;
4095 priv->hostcmd_wait = NULL;
4096
4097 spin_lock_init(&priv->tx_lock);
4098
4099 priv->tx_wait = NULL;
4100
4101 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 3998 for (i = 0; i < MWL8K_TX_QUEUES; i++) {
4102 rc = mwl8k_txq_init(hw, i); 3999 rc = mwl8k_txq_init(hw, i);
4103 if (rc) 4000 if (rc)
@@ -4137,13 +4034,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
4137 goto err_free_irq; 4034 goto err_free_irq;
4138 } 4035 }
4139 4036
4140 hw->wiphy->interface_modes = 0;
4141 if (priv->ap_macids_supported)
4142 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
4143 if (priv->sta_macids_supported)
4144 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
4145
4146
4147 /* Turn radio off */ 4037 /* Turn radio off */
4148 rc = mwl8k_cmd_radio_disable(hw); 4038 rc = mwl8k_cmd_radio_disable(hw);
4149 if (rc) { 4039 if (rc) {
@@ -4162,12 +4052,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
4162 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4052 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4163 free_irq(priv->pdev->irq, hw); 4053 free_irq(priv->pdev->irq, hw);
4164 4054
4165 rc = ieee80211_register_hw(hw);
4166 if (rc) {
4167 wiphy_err(hw->wiphy, "Cannot register device\n");
4168 goto err_free_queues;
4169 }
4170
4171 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", 4055 wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n",
4172 priv->device_info->part_name, 4056 priv->device_info->part_name,
4173 priv->hw_rev, hw->wiphy->perm_addr, 4057 priv->hw_rev, hw->wiphy->perm_addr,
@@ -4186,14 +4070,213 @@ err_free_queues:
4186 mwl8k_txq_deinit(hw, i); 4070 mwl8k_txq_deinit(hw, i);
4187 mwl8k_rxq_deinit(hw, 0); 4071 mwl8k_rxq_deinit(hw, 0);
4188 4072
4073err_stop_firmware:
4074 mwl8k_hw_reset(priv);
4075
4076 return rc;
4077}
4078
4079/*
4080 * invoke mwl8k_reload_firmware to change the firmware image after the device
4081 * has already been registered
4082 */
4083static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
4084{
4085 int i, rc = 0;
4086 struct mwl8k_priv *priv = hw->priv;
4087
4088 mwl8k_stop(hw);
4089 mwl8k_rxq_deinit(hw, 0);
4090
4091 for (i = 0; i < MWL8K_TX_QUEUES; i++)
4092 mwl8k_txq_deinit(hw, i);
4093
4094 rc = mwl8k_init_firmware(hw, fw_image);
4095 if (rc)
4096 goto fail;
4097
4098 rc = mwl8k_probe_hw(hw);
4099 if (rc)
4100 goto fail;
4101
4102 rc = mwl8k_start(hw);
4103 if (rc)
4104 goto fail;
4105
4106 rc = mwl8k_config(hw, ~0);
4107 if (rc)
4108 goto fail;
4109
4110 for (i = 0; i < MWL8K_TX_QUEUES; i++) {
4111 rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
4112 if (rc)
4113 goto fail;
4114 }
4115
4116 return rc;
4117
4118fail:
4119 printk(KERN_WARNING "mwl8k: Failed to reload firmware image.\n");
4120 return rc;
4121}
4122
4123static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4124{
4125 struct ieee80211_hw *hw = priv->hw;
4126 int i, rc;
4127
4128 /*
4129 * Extra headroom is the size of the required DMA header
4130 * minus the size of the smallest 802.11 frame (CTS frame).
4131 */
4132 hw->extra_tx_headroom =
4133 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
4134
4135 hw->channel_change_time = 10;
4136
4137 hw->queues = MWL8K_TX_QUEUES;
4138
4139 /* Set rssi values to dBm */
4140 hw->flags |= IEEE80211_HW_SIGNAL_DBM;
4141 hw->vif_data_size = sizeof(struct mwl8k_vif);
4142 hw->sta_data_size = sizeof(struct mwl8k_sta);
4143
4144 priv->macids_used = 0;
4145 INIT_LIST_HEAD(&priv->vif_list);
4146
4147 /* Set default radio state and preamble */
4148 priv->radio_on = 0;
4149 priv->radio_short_preamble = 0;
4150
4151 /* Finalize join worker */
4152 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
4153
4154 /* TX reclaim and RX tasklets. */
4155 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
4156 tasklet_disable(&priv->poll_tx_task);
4157 tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
4158 tasklet_disable(&priv->poll_rx_task);
4159
4160 /* Power management cookie */
4161 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
4162 if (priv->cookie == NULL)
4163 return -ENOMEM;
4164
4165 mutex_init(&priv->fw_mutex);
4166 priv->fw_mutex_owner = NULL;
4167 priv->fw_mutex_depth = 0;
4168 priv->hostcmd_wait = NULL;
4169
4170 spin_lock_init(&priv->tx_lock);
4171
4172 priv->tx_wait = NULL;
4173
4174 rc = mwl8k_probe_hw(hw);
4175 if (rc)
4176 goto err_free_cookie;
4177
4178 hw->wiphy->interface_modes = 0;
4179 if (priv->ap_macids_supported || priv->device_info->fw_image_ap)
4180 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
4181 if (priv->sta_macids_supported || priv->device_info->fw_image_sta)
4182 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
4183
4184 rc = ieee80211_register_hw(hw);
4185 if (rc) {
4186 wiphy_err(hw->wiphy, "Cannot register device\n");
4187 goto err_unprobe_hw;
4188 }
4189
4190 return 0;
4191
4192err_unprobe_hw:
4193 for (i = 0; i < MWL8K_TX_QUEUES; i++)
4194 mwl8k_txq_deinit(hw, i);
4195 mwl8k_rxq_deinit(hw, 0);
4196
4189err_free_cookie: 4197err_free_cookie:
4190 if (priv->cookie != NULL) 4198 if (priv->cookie != NULL)
4191 pci_free_consistent(priv->pdev, 4, 4199 pci_free_consistent(priv->pdev, 4,
4192 priv->cookie, priv->cookie_dma); 4200 priv->cookie, priv->cookie_dma);
4193 4201
4202 return rc;
4203}
4204static int __devinit mwl8k_probe(struct pci_dev *pdev,
4205 const struct pci_device_id *id)
4206{
4207 static int printed_version;
4208 struct ieee80211_hw *hw;
4209 struct mwl8k_priv *priv;
4210 int rc;
4211
4212 if (!printed_version) {
4213 printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
4214 printed_version = 1;
4215 }
4216
4217
4218 rc = pci_enable_device(pdev);
4219 if (rc) {
4220 printk(KERN_ERR "%s: Cannot enable new PCI device\n",
4221 MWL8K_NAME);
4222 return rc;
4223 }
4224
4225 rc = pci_request_regions(pdev, MWL8K_NAME);
4226 if (rc) {
4227 printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
4228 MWL8K_NAME);
4229 goto err_disable_device;
4230 }
4231
4232 pci_set_master(pdev);
4233
4234
4235 hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
4236 if (hw == NULL) {
4237 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
4238 rc = -ENOMEM;
4239 goto err_free_reg;
4240 }
4241
4242 SET_IEEE80211_DEV(hw, &pdev->dev);
4243 pci_set_drvdata(pdev, hw);
4244
4245 priv = hw->priv;
4246 priv->hw = hw;
4247 priv->pdev = pdev;
4248 priv->device_info = &mwl8k_info_tbl[id->driver_data];
4249
4250
4251 priv->sram = pci_iomap(pdev, 0, 0x10000);
4252 if (priv->sram == NULL) {
4253 wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
4254 goto err_iounmap;
4255 }
4256
4257 /*
4258 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
4259 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
4260 */
4261 priv->regs = pci_iomap(pdev, 1, 0x10000);
4262 if (priv->regs == NULL) {
4263 priv->regs = pci_iomap(pdev, 2, 0x10000);
4264 if (priv->regs == NULL) {
4265 wiphy_err(hw->wiphy, "Cannot map device registers\n");
4266 goto err_iounmap;
4267 }
4268 }
4269
4270 rc = mwl8k_init_firmware(hw);
4271 if (rc)
4272 goto err_stop_firmware;
4273
4274 rc = mwl8k_firmware_load_success(priv);
4275 if (!rc)
4276 return rc;
4277
4194err_stop_firmware: 4278err_stop_firmware:
4195 mwl8k_hw_reset(priv); 4279 mwl8k_hw_reset(priv);
4196 mwl8k_release_firmware(priv);
4197 4280
4198err_iounmap: 4281err_iounmap:
4199 if (priv->regs != NULL) 4282 if (priv->regs != NULL)