diff options
author | Michael Buesch <mb@bu3sch.de> | 2009-06-08 15:04:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-06-10 13:28:37 -0400 |
commit | 403a3a136122457165321e90b7569a321cc9ac12 (patch) | |
tree | 55eafd8ccb989d19937d884993326c7d8e135be7 /drivers/net/wireless/b43/main.c | |
parent | 908209c160da8ecb68052111972b7a21310eac3f (diff) |
b43: Add fw capabilities
Add automagic feature flags, so the firmware can tell the driver
about supported features and the driver can switch features on/off as
needed.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: Stefan Lippers-Hollmann <s.l-h@gmx.de>
Tested-by: Stefan Lippers-Hollmann <s.l-h@gmx.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5d9f1981f2ce..6456afebdba1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -80,8 +80,8 @@ static int modparam_nohwcrypt; | |||
80 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | 80 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); |
81 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 81 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
82 | 82 | ||
83 | int b43_modparam_qos = 1; | 83 | static int modparam_qos = 1; |
84 | module_param_named(qos, b43_modparam_qos, int, 0444); | 84 | module_param_named(qos, modparam_qos, int, 0444); |
85 | MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); | 85 | MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); |
86 | 86 | ||
87 | static int modparam_btcoex = 1; | 87 | static int modparam_btcoex = 1; |
@@ -538,6 +538,13 @@ void b43_hf_write(struct b43_wldev *dev, u64 value) | |||
538 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); | 538 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); |
539 | } | 539 | } |
540 | 540 | ||
541 | /* Read the firmware capabilities bitmask (Opensource firmware only) */ | ||
542 | static u16 b43_fwcapa_read(struct b43_wldev *dev) | ||
543 | { | ||
544 | B43_WARN_ON(!dev->fw.opensource); | ||
545 | return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA); | ||
546 | } | ||
547 | |||
541 | void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) | 548 | void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) |
542 | { | 549 | { |
543 | u32 low, high; | 550 | u32 low, high; |
@@ -2307,12 +2314,34 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2307 | dev->fw.patch = fwpatch; | 2314 | dev->fw.patch = fwpatch; |
2308 | dev->fw.opensource = (fwdate == 0xFFFF); | 2315 | dev->fw.opensource = (fwdate == 0xFFFF); |
2309 | 2316 | ||
2317 | /* Default to use-all-queues. */ | ||
2318 | dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues; | ||
2319 | dev->qos_enabled = !!modparam_qos; | ||
2320 | /* Default to firmware/hardware crypto acceleration. */ | ||
2321 | dev->hwcrypto_enabled = 1; | ||
2322 | |||
2310 | if (dev->fw.opensource) { | 2323 | if (dev->fw.opensource) { |
2324 | u16 fwcapa; | ||
2325 | |||
2311 | /* Patchlevel info is encoded in the "time" field. */ | 2326 | /* Patchlevel info is encoded in the "time" field. */ |
2312 | dev->fw.patch = fwtime; | 2327 | dev->fw.patch = fwtime; |
2313 | b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n", | 2328 | b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n", |
2314 | dev->fw.rev, dev->fw.patch, | 2329 | dev->fw.rev, dev->fw.patch); |
2315 | dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : ""); | 2330 | |
2331 | fwcapa = b43_fwcapa_read(dev); | ||
2332 | if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) { | ||
2333 | b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n"); | ||
2334 | /* Disable hardware crypto and fall back to software crypto. */ | ||
2335 | dev->hwcrypto_enabled = 0; | ||
2336 | } | ||
2337 | if (!(fwcapa & B43_FWCAPA_QOS)) { | ||
2338 | b43info(dev->wl, "QoS not supported by firmware\n"); | ||
2339 | /* Disable QoS. Tweak hw->queues to 1. It will be restored before | ||
2340 | * ieee80211_unregister to make sure the networking core can | ||
2341 | * properly free possible resources. */ | ||
2342 | dev->wl->hw->queues = 1; | ||
2343 | dev->qos_enabled = 0; | ||
2344 | } | ||
2316 | } else { | 2345 | } else { |
2317 | b43info(dev->wl, "Loading firmware version %u.%u " | 2346 | b43info(dev->wl, "Loading firmware version %u.%u " |
2318 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", | 2347 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", |
@@ -3627,7 +3656,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3627 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) | 3656 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) |
3628 | goto out_unlock; | 3657 | goto out_unlock; |
3629 | 3658 | ||
3630 | if (dev->fw.pcm_request_failed) { | 3659 | if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) { |
3631 | /* We don't have firmware for the crypto engine. | 3660 | /* We don't have firmware for the crypto engine. |
3632 | * Must use software-crypto. */ | 3661 | * Must use software-crypto. */ |
3633 | err = -EOPNOTSUPP; | 3662 | err = -EOPNOTSUPP; |
@@ -4727,6 +4756,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4727 | b43err(NULL, "Could not allocate ieee80211 device\n"); | 4756 | b43err(NULL, "Could not allocate ieee80211 device\n"); |
4728 | goto out; | 4757 | goto out; |
4729 | } | 4758 | } |
4759 | wl = hw_to_b43_wl(hw); | ||
4730 | 4760 | ||
4731 | /* fill hw info */ | 4761 | /* fill hw info */ |
4732 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 4762 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
@@ -4740,7 +4770,8 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4740 | BIT(NL80211_IFTYPE_WDS) | | 4770 | BIT(NL80211_IFTYPE_WDS) | |
4741 | BIT(NL80211_IFTYPE_ADHOC); | 4771 | BIT(NL80211_IFTYPE_ADHOC); |
4742 | 4772 | ||
4743 | hw->queues = b43_modparam_qos ? 4 : 1; | 4773 | hw->queues = modparam_qos ? 4 : 1; |
4774 | wl->mac80211_initially_registered_queues = hw->queues; | ||
4744 | hw->max_rates = 2; | 4775 | hw->max_rates = 2; |
4745 | SET_IEEE80211_DEV(hw, dev->dev); | 4776 | SET_IEEE80211_DEV(hw, dev->dev); |
4746 | if (is_valid_ether_addr(sprom->et1mac)) | 4777 | if (is_valid_ether_addr(sprom->et1mac)) |
@@ -4748,9 +4779,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4748 | else | 4779 | else |
4749 | SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); | 4780 | SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); |
4750 | 4781 | ||
4751 | /* Get and initialize struct b43_wl */ | 4782 | /* Initialize struct b43_wl */ |
4752 | wl = hw_to_b43_wl(hw); | ||
4753 | memset(wl, 0, sizeof(*wl)); | ||
4754 | wl->hw = hw; | 4783 | wl->hw = hw; |
4755 | spin_lock_init(&wl->irq_lock); | 4784 | spin_lock_init(&wl->irq_lock); |
4756 | rwlock_init(&wl->tx_lock); | 4785 | rwlock_init(&wl->tx_lock); |
@@ -4816,8 +4845,13 @@ static void b43_remove(struct ssb_device *dev) | |||
4816 | cancel_work_sync(&wldev->restart_work); | 4845 | cancel_work_sync(&wldev->restart_work); |
4817 | 4846 | ||
4818 | B43_WARN_ON(!wl); | 4847 | B43_WARN_ON(!wl); |
4819 | if (wl->current_dev == wldev) | 4848 | if (wl->current_dev == wldev) { |
4849 | /* Restore the queues count before unregistering, because firmware detect | ||
4850 | * might have modified it. Restoring is important, so the networking | ||
4851 | * stack can properly free resources. */ | ||
4852 | wl->hw->queues = wl->mac80211_initially_registered_queues; | ||
4820 | ieee80211_unregister_hw(wl->hw); | 4853 | ieee80211_unregister_hw(wl->hw); |
4854 | } | ||
4821 | 4855 | ||
4822 | b43_one_core_detach(dev); | 4856 | b43_one_core_detach(dev); |
4823 | 4857 | ||