mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-07 03:18:31 +00:00
mwl8k: do rx/tx ring initialisation after loading firmware
Whether the firmware we have loaded is AP or STA firmware decides which receive descriptor format we have to use. Therefore, move rx/tx ring initialisation to be after firmware loading. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
22be40d9c5
commit
be695fc4f0
1 changed files with 57 additions and 47 deletions
|
@ -127,20 +127,22 @@ struct mwl8k_tx_queue {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mwl8k_priv {
|
struct mwl8k_priv {
|
||||||
void __iomem *sram;
|
|
||||||
void __iomem *regs;
|
|
||||||
struct ieee80211_hw *hw;
|
struct ieee80211_hw *hw;
|
||||||
|
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
|
|
||||||
struct mwl8k_device_info *device_info;
|
struct mwl8k_device_info *device_info;
|
||||||
bool ap_fw;
|
|
||||||
struct rxd_ops *rxd_ops;
|
|
||||||
|
|
||||||
/* firmware files and meta data */
|
void __iomem *sram;
|
||||||
|
void __iomem *regs;
|
||||||
|
|
||||||
|
/* firmware */
|
||||||
struct firmware *fw_helper;
|
struct firmware *fw_helper;
|
||||||
struct firmware *fw_ucode;
|
struct firmware *fw_ucode;
|
||||||
|
|
||||||
|
/* hardware/firmware parameters */
|
||||||
|
bool ap_fw;
|
||||||
|
struct rxd_ops *rxd_ops;
|
||||||
|
|
||||||
/* firmware access */
|
/* firmware access */
|
||||||
struct mutex fw_mutex;
|
struct mutex fw_mutex;
|
||||||
struct task_struct *fw_mutex_owner;
|
struct task_struct *fw_mutex_owner;
|
||||||
|
@ -547,7 +549,6 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
struct mwl8k_priv *priv = hw->priv;
|
struct mwl8k_priv *priv = hw->priv;
|
||||||
struct firmware *fw = priv->fw_ucode;
|
struct firmware *fw = priv->fw_ucode;
|
||||||
struct mwl8k_device_info *di = priv->device_info;
|
|
||||||
int rc;
|
int rc;
|
||||||
int loops;
|
int loops;
|
||||||
|
|
||||||
|
@ -579,7 +580,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (di->modes & BIT(NL80211_IFTYPE_AP))
|
if (priv->device_info->modes & BIT(NL80211_IFTYPE_AP))
|
||||||
iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR);
|
iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR);
|
||||||
else
|
else
|
||||||
iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
|
iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
|
||||||
|
@ -3300,6 +3301,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
printed_version = 1;
|
printed_version = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rc = pci_enable_device(pdev);
|
rc = pci_enable_device(pdev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "%s: Cannot enable new PCI device\n",
|
printk(KERN_ERR "%s: Cannot enable new PCI device\n",
|
||||||
|
@ -3316,6 +3318,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
|
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
|
|
||||||
|
|
||||||
hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
|
hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
|
||||||
if (hw == NULL) {
|
if (hw == NULL) {
|
||||||
printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
|
printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
|
||||||
|
@ -3323,17 +3326,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
goto err_free_reg;
|
goto err_free_reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SET_IEEE80211_DEV(hw, &pdev->dev);
|
||||||
|
pci_set_drvdata(pdev, hw);
|
||||||
|
|
||||||
priv = hw->priv;
|
priv = hw->priv;
|
||||||
priv->hw = hw;
|
priv->hw = hw;
|
||||||
priv->pdev = pdev;
|
priv->pdev = pdev;
|
||||||
priv->device_info = &mwl8k_info_tbl[id->driver_data];
|
priv->device_info = &mwl8k_info_tbl[id->driver_data];
|
||||||
priv->rxd_ops = priv->device_info->rxd_ops;
|
|
||||||
priv->sniffer_enabled = false;
|
|
||||||
priv->wmm_enabled = false;
|
|
||||||
priv->pending_tx_pkts = 0;
|
|
||||||
|
|
||||||
SET_IEEE80211_DEV(hw, &pdev->dev);
|
|
||||||
pci_set_drvdata(pdev, hw);
|
|
||||||
|
|
||||||
priv->sram = pci_iomap(pdev, 0, 0x10000);
|
priv->sram = pci_iomap(pdev, 0, 0x10000);
|
||||||
if (priv->sram == NULL) {
|
if (priv->sram == NULL) {
|
||||||
|
@ -3356,6 +3356,37 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Reset firmware and hardware */
|
||||||
|
mwl8k_hw_reset(priv);
|
||||||
|
|
||||||
|
/* Ask userland hotplug daemon for the device firmware */
|
||||||
|
rc = mwl8k_request_firmware(priv);
|
||||||
|
if (rc) {
|
||||||
|
printk(KERN_ERR "%s: Firmware files not found\n",
|
||||||
|
wiphy_name(hw->wiphy));
|
||||||
|
goto err_stop_firmware;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load firmware into hardware */
|
||||||
|
rc = mwl8k_load_firmware(hw);
|
||||||
|
if (rc) {
|
||||||
|
printk(KERN_ERR "%s: Cannot start firmware\n",
|
||||||
|
wiphy_name(hw->wiphy));
|
||||||
|
goto err_stop_firmware;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reclaim memory once firmware is successfully loaded */
|
||||||
|
mwl8k_release_firmware(priv);
|
||||||
|
|
||||||
|
|
||||||
|
priv->rxd_ops = priv->device_info->rxd_ops;
|
||||||
|
|
||||||
|
priv->sniffer_enabled = false;
|
||||||
|
priv->wmm_enabled = false;
|
||||||
|
priv->pending_tx_pkts = 0;
|
||||||
|
|
||||||
|
|
||||||
memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
|
memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
|
||||||
priv->band.band = IEEE80211_BAND_2GHZ;
|
priv->band.band = IEEE80211_BAND_2GHZ;
|
||||||
priv->band.channels = priv->channels;
|
priv->band.channels = priv->channels;
|
||||||
|
@ -3400,11 +3431,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
/* Power management cookie */
|
/* Power management cookie */
|
||||||
priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
|
priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
|
||||||
if (priv->cookie == NULL)
|
if (priv->cookie == NULL)
|
||||||
goto err_iounmap;
|
goto err_stop_firmware;
|
||||||
|
|
||||||
rc = mwl8k_rxq_init(hw, 0);
|
rc = mwl8k_rxq_init(hw, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_iounmap;
|
goto err_free_cookie;
|
||||||
rxq_refill(hw, 0, INT_MAX);
|
rxq_refill(hw, 0, INT_MAX);
|
||||||
|
|
||||||
mutex_init(&priv->fw_mutex);
|
mutex_init(&priv->fw_mutex);
|
||||||
|
@ -3435,28 +3466,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
goto err_free_queues;
|
goto err_free_queues;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset firmware and hardware */
|
|
||||||
mwl8k_hw_reset(priv);
|
|
||||||
|
|
||||||
/* Ask userland hotplug daemon for the device firmware */
|
|
||||||
rc = mwl8k_request_firmware(priv);
|
|
||||||
if (rc) {
|
|
||||||
printk(KERN_ERR "%s: Firmware files not found\n",
|
|
||||||
wiphy_name(hw->wiphy));
|
|
||||||
goto err_free_irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load firmware into hardware */
|
|
||||||
rc = mwl8k_load_firmware(hw);
|
|
||||||
if (rc) {
|
|
||||||
printk(KERN_ERR "%s: Cannot start firmware\n",
|
|
||||||
wiphy_name(hw->wiphy));
|
|
||||||
goto err_stop_firmware;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reclaim memory once firmware is successfully loaded */
|
|
||||||
mwl8k_release_firmware(priv);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Temporarily enable interrupts. Initial firmware host
|
* Temporarily enable interrupts. Initial firmware host
|
||||||
* commands use interrupts and avoids polling. Disable
|
* commands use interrupts and avoids polling. Disable
|
||||||
|
@ -3475,14 +3484,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "%s: Cannot initialise firmware\n",
|
printk(KERN_ERR "%s: Cannot initialise firmware\n",
|
||||||
wiphy_name(hw->wiphy));
|
wiphy_name(hw->wiphy));
|
||||||
goto err_stop_firmware;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn radio off */
|
/* Turn radio off */
|
||||||
rc = mwl8k_cmd_radio_disable(hw);
|
rc = mwl8k_cmd_radio_disable(hw);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
|
printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
|
||||||
goto err_stop_firmware;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear MAC address */
|
/* Clear MAC address */
|
||||||
|
@ -3490,7 +3499,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "%s: Cannot clear MAC address\n",
|
printk(KERN_ERR "%s: Cannot clear MAC address\n",
|
||||||
wiphy_name(hw->wiphy));
|
wiphy_name(hw->wiphy));
|
||||||
goto err_stop_firmware;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
|
@ -3501,7 +3510,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "%s: Cannot register device\n",
|
printk(KERN_ERR "%s: Cannot register device\n",
|
||||||
wiphy_name(hw->wiphy));
|
wiphy_name(hw->wiphy));
|
||||||
goto err_stop_firmware;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
|
printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
|
||||||
|
@ -3513,10 +3522,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_stop_firmware:
|
|
||||||
mwl8k_hw_reset(priv);
|
|
||||||
mwl8k_release_firmware(priv);
|
|
||||||
|
|
||||||
err_free_irq:
|
err_free_irq:
|
||||||
iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
|
iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
|
||||||
free_irq(priv->pdev->irq, hw);
|
free_irq(priv->pdev->irq, hw);
|
||||||
|
@ -3526,11 +3531,16 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||||
mwl8k_txq_deinit(hw, i);
|
mwl8k_txq_deinit(hw, i);
|
||||||
mwl8k_rxq_deinit(hw, 0);
|
mwl8k_rxq_deinit(hw, 0);
|
||||||
|
|
||||||
err_iounmap:
|
err_free_cookie:
|
||||||
if (priv->cookie != NULL)
|
if (priv->cookie != NULL)
|
||||||
pci_free_consistent(priv->pdev, 4,
|
pci_free_consistent(priv->pdev, 4,
|
||||||
priv->cookie, priv->cookie_dma);
|
priv->cookie, priv->cookie_dma);
|
||||||
|
|
||||||
|
err_stop_firmware:
|
||||||
|
mwl8k_hw_reset(priv);
|
||||||
|
mwl8k_release_firmware(priv);
|
||||||
|
|
||||||
|
err_iounmap:
|
||||||
if (priv->regs != NULL)
|
if (priv->regs != NULL)
|
||||||
pci_iounmap(pdev, priv->regs);
|
pci_iounmap(pdev, priv->regs);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue