My apologies. This is also a V2 patch despite the subject. On Fri, Nov 12, 2010 at 5:23 PM, Brian Cavagnolo <brian@xxxxxxxxxxx> wrote: > 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@xxxxxxxxxxx> > and Yogesh Powar <yogeshp@xxxxxxxxxxx> > > Signed-off-by: Brian Cavagnolo <brian@xxxxxxxxxxx> > --- > drivers/net/wireless/mwl8k.c | 345 ++++++++++++++++++++++++++---------------- > 1 files changed, 214 insertions(+), 131 deletions(-) > > diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c > index cfda87a..7bd8615 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) = { > }; > MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); > > -static int __devinit mwl8k_probe(struct pci_dev *pdev, > - const struct pci_device_id *id) > +static int mwl8k_init_firmware(struct ieee80211_hw *hw) > { > - static int printed_version = 0; > - struct ieee80211_hw *hw; > - struct mwl8k_priv *priv; > + struct mwl8k_priv *priv = hw->priv; > int rc; > - int i; > - > - if (!printed_version) { > - printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION); > - printed_version = 1; > - } > - > - > - rc = pci_enable_device(pdev); > - if (rc) { > - printk(KERN_ERR "%s: Cannot enable new PCI device\n", > - MWL8K_NAME); > - return rc; > - } > - > - rc = pci_request_regions(pdev, MWL8K_NAME); > - if (rc) { > - printk(KERN_ERR "%s: Cannot obtain PCI resources\n", > - MWL8K_NAME); > - goto err_disable_device; > - } > - > - pci_set_master(pdev); > - > - > - hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); > - if (hw == NULL) { > - printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); > - rc = -ENOMEM; > - goto err_free_reg; > - } > - > - SET_IEEE80211_DEV(hw, &pdev->dev); > - pci_set_drvdata(pdev, hw); > - > - priv = hw->priv; > - priv->hw = hw; > - priv->pdev = pdev; > - priv->device_info = &mwl8k_info_tbl[id->driver_data]; > - > - > - priv->sram = pci_iomap(pdev, 0, 0x10000); > - if (priv->sram == NULL) { > - wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); > - goto err_iounmap; > - } > - > - /* > - * If BAR0 is a 32 bit BAR, the register BAR will be BAR1. > - * If BAR0 is a 64 bit BAR, the register BAR will be BAR2. > - */ > - priv->regs = pci_iomap(pdev, 1, 0x10000); > - if (priv->regs == NULL) { > - priv->regs = pci_iomap(pdev, 2, 0x10000); > - if (priv->regs == NULL) { > - wiphy_err(hw->wiphy, "Cannot map device registers\n"); > - goto err_iounmap; > - } > - } > - > > /* Reset firmware and hardware */ > mwl8k_hw_reset(priv); > @@ -4017,19 +3954,26 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, > rc = mwl8k_request_firmware(priv); > if (rc) { > wiphy_err(hw->wiphy, "Firmware files not found\n"); > - goto err_stop_firmware; > + return rc; > } > > /* Load firmware into hardware */ > rc = mwl8k_load_firmware(hw); > - if (rc) { > + if (rc) > wiphy_err(hw->wiphy, "Cannot start firmware\n"); > - goto err_stop_firmware; > - } > > /* Reclaim memory once firmware is successfully loaded */ > mwl8k_release_firmware(priv); > > + return rc; > +} > + > +/* initialize hw after successfully loading a firmware image */ > +static int mwl8k_probe_hw(struct ieee80211_hw *hw) > +{ > + struct mwl8k_priv *priv = hw->priv; > + int rc = 0; > + int i; > > if (priv->ap_fw) { > priv->rxd_ops = priv->device_info->ap_rxd_ops; > @@ -4046,58 +3990,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, > priv->wmm_enabled = false; > priv->pending_tx_pkts = 0; > > - > - /* > - * Extra headroom is the size of the required DMA header > - * minus the size of the smallest 802.11 frame (CTS frame). > - */ > - hw->extra_tx_headroom = > - sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); > - > - hw->channel_change_time = 10; > - > - hw->queues = MWL8K_TX_QUEUES; > - > - /* Set rssi values to dBm */ > - hw->flags |= IEEE80211_HW_SIGNAL_DBM; > - hw->vif_data_size = sizeof(struct mwl8k_vif); > - hw->sta_data_size = sizeof(struct mwl8k_sta); > - > - priv->macids_used = 0; > - INIT_LIST_HEAD(&priv->vif_list); > - > - /* Set default radio state and preamble */ > - priv->radio_on = 0; > - priv->radio_short_preamble = 0; > - > - /* Finalize join worker */ > - INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); > - > - /* TX reclaim and RX tasklets. */ > - tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); > - tasklet_disable(&priv->poll_tx_task); > - tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw); > - tasklet_disable(&priv->poll_rx_task); > - > - /* Power management cookie */ > - priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); > - if (priv->cookie == NULL) > - goto err_stop_firmware; > - > rc = mwl8k_rxq_init(hw, 0); > if (rc) > - goto err_free_cookie; > + goto err_stop_firmware; > rxq_refill(hw, 0, INT_MAX); > > - mutex_init(&priv->fw_mutex); > - priv->fw_mutex_owner = NULL; > - priv->fw_mutex_depth = 0; > - priv->hostcmd_wait = NULL; > - > - spin_lock_init(&priv->tx_lock); > - > - priv->tx_wait = NULL; > - > for (i = 0; i < MWL8K_TX_QUEUES; i++) { > rc = mwl8k_txq_init(hw, i); > if (rc) > @@ -4137,13 +4034,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, > goto err_free_irq; > } > > - hw->wiphy->interface_modes = 0; > - if (priv->ap_macids_supported) > - hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); > - if (priv->sta_macids_supported) > - hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); > - > - > /* Turn radio off */ > rc = mwl8k_cmd_radio_disable(hw); > if (rc) { > @@ -4162,12 +4052,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, > iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); > free_irq(priv->pdev->irq, hw); > > - rc = ieee80211_register_hw(hw); > - if (rc) { > - wiphy_err(hw->wiphy, "Cannot register device\n"); > - goto err_free_queues; > - } > - > wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", > priv->device_info->part_name, > priv->hw_rev, hw->wiphy->perm_addr, > @@ -4186,14 +4070,213 @@ err_free_queues: > mwl8k_txq_deinit(hw, i); > mwl8k_rxq_deinit(hw, 0); > > +err_stop_firmware: > + mwl8k_hw_reset(priv); > + > + return rc; > +} > + > +/* > + * invoke mwl8k_reload_firmware to change the firmware image after the device > + * has already been registered > + */ > +static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) > +{ > + int i, rc = 0; > + struct mwl8k_priv *priv = hw->priv; > + > + mwl8k_stop(hw); > + mwl8k_rxq_deinit(hw, 0); > + > + for (i = 0; i < MWL8K_TX_QUEUES; i++) > + mwl8k_txq_deinit(hw, i); > + > + rc = mwl8k_init_firmware(hw, fw_image); > + if (rc) > + goto fail; > + > + rc = mwl8k_probe_hw(hw); > + if (rc) > + goto fail; > + > + rc = mwl8k_start(hw); > + if (rc) > + goto fail; > + > + rc = mwl8k_config(hw, ~0); > + if (rc) > + goto fail; > + > + for (i = 0; i < MWL8K_TX_QUEUES; i++) { > + rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]); > + if (rc) > + goto fail; > + } > + > + return rc; > + > +fail: > + printk(KERN_WARNING "mwl8k: Failed to reload firmware image.\n"); > + return rc; > +} > + > +static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) > +{ > + struct ieee80211_hw *hw = priv->hw; > + int i, rc; > + > + /* > + * Extra headroom is the size of the required DMA header > + * minus the size of the smallest 802.11 frame (CTS frame). > + */ > + hw->extra_tx_headroom = > + sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); > + > + hw->channel_change_time = 10; > + > + hw->queues = MWL8K_TX_QUEUES; > + > + /* Set rssi values to dBm */ > + hw->flags |= IEEE80211_HW_SIGNAL_DBM; > + hw->vif_data_size = sizeof(struct mwl8k_vif); > + hw->sta_data_size = sizeof(struct mwl8k_sta); > + > + priv->macids_used = 0; > + INIT_LIST_HEAD(&priv->vif_list); > + > + /* Set default radio state and preamble */ > + priv->radio_on = 0; > + priv->radio_short_preamble = 0; > + > + /* Finalize join worker */ > + INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); > + > + /* TX reclaim and RX tasklets. */ > + tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); > + tasklet_disable(&priv->poll_tx_task); > + tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw); > + tasklet_disable(&priv->poll_rx_task); > + > + /* Power management cookie */ > + priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); > + if (priv->cookie == NULL) > + return -ENOMEM; > + > + mutex_init(&priv->fw_mutex); > + priv->fw_mutex_owner = NULL; > + priv->fw_mutex_depth = 0; > + priv->hostcmd_wait = NULL; > + > + spin_lock_init(&priv->tx_lock); > + > + priv->tx_wait = NULL; > + > + rc = mwl8k_probe_hw(hw); > + if (rc) > + goto err_free_cookie; > + > + hw->wiphy->interface_modes = 0; > + if (priv->ap_macids_supported || priv->device_info->fw_image_ap) > + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); > + if (priv->sta_macids_supported || priv->device_info->fw_image_sta) > + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); > + > + rc = ieee80211_register_hw(hw); > + if (rc) { > + wiphy_err(hw->wiphy, "Cannot register device\n"); > + goto err_unprobe_hw; > + } > + > + return 0; > + > +err_unprobe_hw: > + for (i = 0; i < MWL8K_TX_QUEUES; i++) > + mwl8k_txq_deinit(hw, i); > + mwl8k_rxq_deinit(hw, 0); > + > err_free_cookie: > if (priv->cookie != NULL) > pci_free_consistent(priv->pdev, 4, > priv->cookie, priv->cookie_dma); > > + return rc; > +} > +static int __devinit mwl8k_probe(struct pci_dev *pdev, > + const struct pci_device_id *id) > +{ > + static int printed_version; > + struct ieee80211_hw *hw; > + struct mwl8k_priv *priv; > + int rc; > + > + if (!printed_version) { > + printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION); > + printed_version = 1; > + } > + > + > + rc = pci_enable_device(pdev); > + if (rc) { > + printk(KERN_ERR "%s: Cannot enable new PCI device\n", > + MWL8K_NAME); > + return rc; > + } > + > + rc = pci_request_regions(pdev, MWL8K_NAME); > + if (rc) { > + printk(KERN_ERR "%s: Cannot obtain PCI resources\n", > + MWL8K_NAME); > + goto err_disable_device; > + } > + > + pci_set_master(pdev); > + > + > + hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); > + if (hw == NULL) { > + printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); > + rc = -ENOMEM; > + goto err_free_reg; > + } > + > + SET_IEEE80211_DEV(hw, &pdev->dev); > + pci_set_drvdata(pdev, hw); > + > + priv = hw->priv; > + priv->hw = hw; > + priv->pdev = pdev; > + priv->device_info = &mwl8k_info_tbl[id->driver_data]; > + > + > + priv->sram = pci_iomap(pdev, 0, 0x10000); > + if (priv->sram == NULL) { > + wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); > + goto err_iounmap; > + } > + > + /* > + * If BAR0 is a 32 bit BAR, the register BAR will be BAR1. > + * If BAR0 is a 64 bit BAR, the register BAR will be BAR2. > + */ > + priv->regs = pci_iomap(pdev, 1, 0x10000); > + if (priv->regs == NULL) { > + priv->regs = pci_iomap(pdev, 2, 0x10000); > + if (priv->regs == NULL) { > + wiphy_err(hw->wiphy, "Cannot map device registers\n"); > + goto err_iounmap; > + } > + } > + > + rc = mwl8k_init_firmware(hw); > + if (rc) > + goto err_stop_firmware; > + > + rc = mwl8k_firmware_load_success(priv); > + if (!rc) > + return rc; > + > err_stop_firmware: > mwl8k_hw_reset(priv); > - mwl8k_release_firmware(priv); > > err_iounmap: > if (priv->regs != NULL) > -- > 1.7.1.1 > > -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html