diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2009-11-30 12:32:46 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-28 16:31:27 -0500 |
commit | be695fc4f0a7ff9c9f91d59536b029b781cfea62 (patch) | |
tree | 3efb9ebebe4c97ec988b49e342307127bc2841ef /drivers/net/wireless/mwl8k.c | |
parent | 22be40d9c53faa10d03a679160e0854ad115b610 (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 104 |
1 files changed, 57 insertions, 47 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 19fe7124d93a..0ae56cb6b0b3 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -127,20 +127,22 @@ struct mwl8k_tx_queue { | |||
127 | }; | 127 | }; |
128 | 128 | ||
129 | struct mwl8k_priv { | 129 | struct mwl8k_priv { |
130 | void __iomem *sram; | ||
131 | void __iomem *regs; | ||
132 | struct ieee80211_hw *hw; | 130 | struct ieee80211_hw *hw; |
133 | |||
134 | struct pci_dev *pdev; | 131 | struct pci_dev *pdev; |
135 | 132 | ||
136 | struct mwl8k_device_info *device_info; | 133 | struct mwl8k_device_info *device_info; |
137 | bool ap_fw; | ||
138 | struct rxd_ops *rxd_ops; | ||
139 | 134 | ||
140 | /* firmware files and meta data */ | 135 | void __iomem *sram; |
136 | void __iomem *regs; | ||
137 | |||
138 | /* firmware */ | ||
141 | struct firmware *fw_helper; | 139 | struct firmware *fw_helper; |
142 | struct firmware *fw_ucode; | 140 | struct firmware *fw_ucode; |
143 | 141 | ||
142 | /* hardware/firmware parameters */ | ||
143 | bool ap_fw; | ||
144 | struct rxd_ops *rxd_ops; | ||
145 | |||
144 | /* firmware access */ | 146 | /* firmware access */ |
145 | struct mutex fw_mutex; | 147 | struct mutex fw_mutex; |
146 | struct task_struct *fw_mutex_owner; | 148 | struct task_struct *fw_mutex_owner; |
@@ -547,7 +549,6 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) | |||
547 | { | 549 | { |
548 | struct mwl8k_priv *priv = hw->priv; | 550 | struct mwl8k_priv *priv = hw->priv; |
549 | struct firmware *fw = priv->fw_ucode; | 551 | struct firmware *fw = priv->fw_ucode; |
550 | struct mwl8k_device_info *di = priv->device_info; | ||
551 | int rc; | 552 | int rc; |
552 | int loops; | 553 | int loops; |
553 | 554 | ||
@@ -579,7 +580,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) | |||
579 | return rc; | 580 | return rc; |
580 | } | 581 | } |
581 | 582 | ||
582 | if (di->modes & BIT(NL80211_IFTYPE_AP)) | 583 | if (priv->device_info->modes & BIT(NL80211_IFTYPE_AP)) |
583 | iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR); | 584 | iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR); |
584 | else | 585 | else |
585 | iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); | 586 | iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); |
@@ -3300,6 +3301,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3300 | printed_version = 1; | 3301 | printed_version = 1; |
3301 | } | 3302 | } |
3302 | 3303 | ||
3304 | |||
3303 | rc = pci_enable_device(pdev); | 3305 | rc = pci_enable_device(pdev); |
3304 | if (rc) { | 3306 | if (rc) { |
3305 | printk(KERN_ERR "%s: Cannot enable new PCI device\n", | 3307 | printk(KERN_ERR "%s: Cannot enable new PCI device\n", |
@@ -3316,6 +3318,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3316 | 3318 | ||
3317 | pci_set_master(pdev); | 3319 | pci_set_master(pdev); |
3318 | 3320 | ||
3321 | |||
3319 | hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); | 3322 | hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); |
3320 | if (hw == NULL) { | 3323 | if (hw == NULL) { |
3321 | printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); | 3324 | printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); |
@@ -3323,17 +3326,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3323 | goto err_free_reg; | 3326 | goto err_free_reg; |
3324 | } | 3327 | } |
3325 | 3328 | ||
3329 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
3330 | pci_set_drvdata(pdev, hw); | ||
3331 | |||
3326 | priv = hw->priv; | 3332 | priv = hw->priv; |
3327 | priv->hw = hw; | 3333 | priv->hw = hw; |
3328 | priv->pdev = pdev; | 3334 | priv->pdev = pdev; |
3329 | priv->device_info = &mwl8k_info_tbl[id->driver_data]; | 3335 | priv->device_info = &mwl8k_info_tbl[id->driver_data]; |
3330 | priv->rxd_ops = priv->device_info->rxd_ops; | ||
3331 | priv->sniffer_enabled = false; | ||
3332 | priv->wmm_enabled = false; | ||
3333 | priv->pending_tx_pkts = 0; | ||
3334 | 3336 | ||
3335 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
3336 | pci_set_drvdata(pdev, hw); | ||
3337 | 3337 | ||
3338 | priv->sram = pci_iomap(pdev, 0, 0x10000); | 3338 | priv->sram = pci_iomap(pdev, 0, 0x10000); |
3339 | if (priv->sram == NULL) { | 3339 | if (priv->sram == NULL) { |
@@ -3356,6 +3356,37 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3356 | } | 3356 | } |
3357 | } | 3357 | } |
3358 | 3358 | ||
3359 | |||
3360 | /* Reset firmware and hardware */ | ||
3361 | mwl8k_hw_reset(priv); | ||
3362 | |||
3363 | /* Ask userland hotplug daemon for the device firmware */ | ||
3364 | rc = mwl8k_request_firmware(priv); | ||
3365 | if (rc) { | ||
3366 | printk(KERN_ERR "%s: Firmware files not found\n", | ||
3367 | wiphy_name(hw->wiphy)); | ||
3368 | goto err_stop_firmware; | ||
3369 | } | ||
3370 | |||
3371 | /* Load firmware into hardware */ | ||
3372 | rc = mwl8k_load_firmware(hw); | ||
3373 | if (rc) { | ||
3374 | printk(KERN_ERR "%s: Cannot start firmware\n", | ||
3375 | wiphy_name(hw->wiphy)); | ||
3376 | goto err_stop_firmware; | ||
3377 | } | ||
3378 | |||
3379 | /* Reclaim memory once firmware is successfully loaded */ | ||
3380 | mwl8k_release_firmware(priv); | ||
3381 | |||
3382 | |||
3383 | priv->rxd_ops = priv->device_info->rxd_ops; | ||
3384 | |||
3385 | priv->sniffer_enabled = false; | ||
3386 | priv->wmm_enabled = false; | ||
3387 | priv->pending_tx_pkts = 0; | ||
3388 | |||
3389 | |||
3359 | memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels)); | 3390 | memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels)); |
3360 | priv->band.band = IEEE80211_BAND_2GHZ; | 3391 | priv->band.band = IEEE80211_BAND_2GHZ; |
3361 | priv->band.channels = priv->channels; | 3392 | priv->band.channels = priv->channels; |
@@ -3400,11 +3431,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3400 | /* Power management cookie */ | 3431 | /* Power management cookie */ |
3401 | priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); | 3432 | priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); |
3402 | if (priv->cookie == NULL) | 3433 | if (priv->cookie == NULL) |
3403 | goto err_iounmap; | 3434 | goto err_stop_firmware; |
3404 | 3435 | ||
3405 | rc = mwl8k_rxq_init(hw, 0); | 3436 | rc = mwl8k_rxq_init(hw, 0); |
3406 | if (rc) | 3437 | if (rc) |
3407 | goto err_iounmap; | 3438 | goto err_free_cookie; |
3408 | rxq_refill(hw, 0, INT_MAX); | 3439 | rxq_refill(hw, 0, INT_MAX); |
3409 | 3440 | ||
3410 | mutex_init(&priv->fw_mutex); | 3441 | mutex_init(&priv->fw_mutex); |
@@ -3435,28 +3466,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3435 | goto err_free_queues; | 3466 | goto err_free_queues; |
3436 | } | 3467 | } |
3437 | 3468 | ||
3438 | /* Reset firmware and hardware */ | ||
3439 | mwl8k_hw_reset(priv); | ||
3440 | |||
3441 | /* Ask userland hotplug daemon for the device firmware */ | ||
3442 | rc = mwl8k_request_firmware(priv); | ||
3443 | if (rc) { | ||
3444 | printk(KERN_ERR "%s: Firmware files not found\n", | ||
3445 | wiphy_name(hw->wiphy)); | ||
3446 | goto err_free_irq; | ||
3447 | } | ||
3448 | |||
3449 | /* Load firmware into hardware */ | ||
3450 | rc = mwl8k_load_firmware(hw); | ||
3451 | if (rc) { | ||
3452 | printk(KERN_ERR "%s: Cannot start firmware\n", | ||
3453 | wiphy_name(hw->wiphy)); | ||
3454 | goto err_stop_firmware; | ||
3455 | } | ||
3456 | |||
3457 | /* Reclaim memory once firmware is successfully loaded */ | ||
3458 | mwl8k_release_firmware(priv); | ||
3459 | |||
3460 | /* | 3469 | /* |
3461 | * Temporarily enable interrupts. Initial firmware host | 3470 | * Temporarily enable interrupts. Initial firmware host |
3462 | * commands use interrupts and avoids polling. Disable | 3471 | * commands use interrupts and avoids polling. Disable |
@@ -3475,14 +3484,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3475 | if (rc) { | 3484 | if (rc) { |
3476 | printk(KERN_ERR "%s: Cannot initialise firmware\n", | 3485 | printk(KERN_ERR "%s: Cannot initialise firmware\n", |
3477 | wiphy_name(hw->wiphy)); | 3486 | wiphy_name(hw->wiphy)); |
3478 | goto err_stop_firmware; | 3487 | goto err_free_irq; |
3479 | } | 3488 | } |
3480 | 3489 | ||
3481 | /* Turn radio off */ | 3490 | /* Turn radio off */ |
3482 | rc = mwl8k_cmd_radio_disable(hw); | 3491 | rc = mwl8k_cmd_radio_disable(hw); |
3483 | if (rc) { | 3492 | if (rc) { |
3484 | printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy)); | 3493 | printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy)); |
3485 | goto err_stop_firmware; | 3494 | goto err_free_irq; |
3486 | } | 3495 | } |
3487 | 3496 | ||
3488 | /* Clear MAC address */ | 3497 | /* Clear MAC address */ |
@@ -3490,7 +3499,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3490 | if (rc) { | 3499 | if (rc) { |
3491 | printk(KERN_ERR "%s: Cannot clear MAC address\n", | 3500 | printk(KERN_ERR "%s: Cannot clear MAC address\n", |
3492 | wiphy_name(hw->wiphy)); | 3501 | wiphy_name(hw->wiphy)); |
3493 | goto err_stop_firmware; | 3502 | goto err_free_irq; |
3494 | } | 3503 | } |
3495 | 3504 | ||
3496 | /* Disable interrupts */ | 3505 | /* Disable interrupts */ |
@@ -3501,7 +3510,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3501 | if (rc) { | 3510 | if (rc) { |
3502 | printk(KERN_ERR "%s: Cannot register device\n", | 3511 | printk(KERN_ERR "%s: Cannot register device\n", |
3503 | wiphy_name(hw->wiphy)); | 3512 | wiphy_name(hw->wiphy)); |
3504 | goto err_stop_firmware; | 3513 | goto err_free_irq; |
3505 | } | 3514 | } |
3506 | 3515 | ||
3507 | printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n", | 3516 | 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, | |||
3513 | 3522 | ||
3514 | return 0; | 3523 | return 0; |
3515 | 3524 | ||
3516 | err_stop_firmware: | ||
3517 | mwl8k_hw_reset(priv); | ||
3518 | mwl8k_release_firmware(priv); | ||
3519 | |||
3520 | err_free_irq: | 3525 | err_free_irq: |
3521 | iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); | 3526 | iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
3522 | free_irq(priv->pdev->irq, hw); | 3527 | free_irq(priv->pdev->irq, hw); |
@@ -3526,11 +3531,16 @@ err_free_queues: | |||
3526 | mwl8k_txq_deinit(hw, i); | 3531 | mwl8k_txq_deinit(hw, i); |
3527 | mwl8k_rxq_deinit(hw, 0); | 3532 | mwl8k_rxq_deinit(hw, 0); |
3528 | 3533 | ||
3529 | err_iounmap: | 3534 | err_free_cookie: |
3530 | if (priv->cookie != NULL) | 3535 | if (priv->cookie != NULL) |
3531 | pci_free_consistent(priv->pdev, 4, | 3536 | pci_free_consistent(priv->pdev, 4, |
3532 | priv->cookie, priv->cookie_dma); | 3537 | priv->cookie, priv->cookie_dma); |
3533 | 3538 | ||
3539 | err_stop_firmware: | ||
3540 | mwl8k_hw_reset(priv); | ||
3541 | mwl8k_release_firmware(priv); | ||
3542 | |||
3543 | err_iounmap: | ||
3534 | if (priv->regs != NULL) | 3544 | if (priv->regs != NULL) |
3535 | pci_iounmap(pdev, priv->regs); | 3545 | pci_iounmap(pdev, priv->regs); |
3536 | 3546 | ||