diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-03-11 14:11:11 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-03-11 14:11:11 -0500 |
commit | 409ec36c320d580a036045e603f96286c362c609 (patch) | |
tree | 3dd9b3569799f7962b523a068052445e2d2c51aa /drivers/net/wireless | |
parent | 1b7fe59322bef9e7a2c05b64a07a66b875299736 (diff) | |
parent | 8d5eab5aa676378b4c9daa62d10d08a0bca04677 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless')
58 files changed, 1875 insertions, 1398 deletions
diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h index 4a37447dfc01..f14a65473fe8 100644 --- a/drivers/net/wireless/at76c50x-usb.h +++ b/drivers/net/wireless/at76c50x-usb.h | |||
@@ -290,7 +290,7 @@ struct mib_mac_mgmt { | |||
290 | u8 res; | 290 | u8 res; |
291 | u8 multi_domain_capability_implemented; | 291 | u8 multi_domain_capability_implemented; |
292 | u8 multi_domain_capability_enabled; | 292 | u8 multi_domain_capability_enabled; |
293 | u8 country_string[3]; | 293 | u8 country_string[IEEE80211_COUNTRY_STRING_LEN]; |
294 | u8 reserved[3]; | 294 | u8 reserved[3]; |
295 | } __packed; | 295 | } __packed; |
296 | 296 | ||
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index ae84b86c3bf2..82324e98efef 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -93,7 +93,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
93 | goto err_out; | 93 | goto err_out; |
94 | } | 94 | } |
95 | 95 | ||
96 | mem = ioremap_nocache(res->start, res->end - res->start + 1); | 96 | mem = ioremap_nocache(res->start, resource_size(res)); |
97 | if (mem == NULL) { | 97 | if (mem == NULL) { |
98 | dev_err(&pdev->dev, "ioremap failed\n"); | 98 | dev_err(&pdev->dev, "ioremap failed\n"); |
99 | ret = -ENOMEM; | 99 | ret = -ENOMEM; |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 0ee54eb333de..8a06dbd39629 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -513,7 +513,7 @@ enum ath5k_tx_queue_id { | |||
513 | AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, | 513 | AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, |
514 | AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, | 514 | AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, |
515 | AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ | 515 | AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ |
516 | AR5K_TX_QUEUE_ID_DATA_MAX = 4, /*IEEE80211_TX_QUEUE_DATA4*/ | 516 | AR5K_TX_QUEUE_ID_DATA_MAX = 3, /*IEEE80211_TX_QUEUE_DATA3*/ |
517 | AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ | 517 | AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ |
518 | AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ | 518 | AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ |
519 | AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ | 519 | AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 91411e9b4b68..e6ff62e60a79 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -442,19 +442,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
442 | return ath5k_reset(sc, chan, true); | 442 | return ath5k_reset(sc, chan, true); |
443 | } | 443 | } |
444 | 444 | ||
445 | struct ath_vif_iter_data { | 445 | void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
446 | const u8 *hw_macaddr; | ||
447 | u8 mask[ETH_ALEN]; | ||
448 | u8 active_mac[ETH_ALEN]; /* first active MAC */ | ||
449 | bool need_set_hw_addr; | ||
450 | bool found_active; | ||
451 | bool any_assoc; | ||
452 | enum nl80211_iftype opmode; | ||
453 | }; | ||
454 | |||
455 | static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
456 | { | 446 | { |
457 | struct ath_vif_iter_data *iter_data = data; | 447 | struct ath5k_vif_iter_data *iter_data = data; |
458 | int i; | 448 | int i; |
459 | struct ath5k_vif *avf = (void *)vif->drv_priv; | 449 | struct ath5k_vif *avf = (void *)vif->drv_priv; |
460 | 450 | ||
@@ -484,9 +474,12 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
484 | */ | 474 | */ |
485 | if (avf->opmode == NL80211_IFTYPE_AP) | 475 | if (avf->opmode == NL80211_IFTYPE_AP) |
486 | iter_data->opmode = NL80211_IFTYPE_AP; | 476 | iter_data->opmode = NL80211_IFTYPE_AP; |
487 | else | 477 | else { |
478 | if (avf->opmode == NL80211_IFTYPE_STATION) | ||
479 | iter_data->n_stas++; | ||
488 | if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) | 480 | if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) |
489 | iter_data->opmode = avf->opmode; | 481 | iter_data->opmode = avf->opmode; |
482 | } | ||
490 | } | 483 | } |
491 | 484 | ||
492 | void | 485 | void |
@@ -494,7 +487,8 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | |||
494 | struct ieee80211_vif *vif) | 487 | struct ieee80211_vif *vif) |
495 | { | 488 | { |
496 | struct ath_common *common = ath5k_hw_common(sc->ah); | 489 | struct ath_common *common = ath5k_hw_common(sc->ah); |
497 | struct ath_vif_iter_data iter_data; | 490 | struct ath5k_vif_iter_data iter_data; |
491 | u32 rfilt; | ||
498 | 492 | ||
499 | /* | 493 | /* |
500 | * Use the hardware MAC address as reference, the hardware uses it | 494 | * Use the hardware MAC address as reference, the hardware uses it |
@@ -505,12 +499,13 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | |||
505 | iter_data.found_active = false; | 499 | iter_data.found_active = false; |
506 | iter_data.need_set_hw_addr = true; | 500 | iter_data.need_set_hw_addr = true; |
507 | iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; | 501 | iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; |
502 | iter_data.n_stas = 0; | ||
508 | 503 | ||
509 | if (vif) | 504 | if (vif) |
510 | ath_vif_iter(&iter_data, vif->addr, vif); | 505 | ath5k_vif_iter(&iter_data, vif->addr, vif); |
511 | 506 | ||
512 | /* Get list of all active MAC addresses */ | 507 | /* Get list of all active MAC addresses */ |
513 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, | 508 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, |
514 | &iter_data); | 509 | &iter_data); |
515 | memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); | 510 | memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); |
516 | 511 | ||
@@ -528,20 +523,19 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | |||
528 | 523 | ||
529 | if (ath5k_hw_hasbssidmask(sc->ah)) | 524 | if (ath5k_hw_hasbssidmask(sc->ah)) |
530 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); | 525 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); |
531 | } | ||
532 | 526 | ||
533 | void | 527 | /* Set up RX Filter */ |
534 | ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) | 528 | if (iter_data.n_stas > 1) { |
535 | { | 529 | /* If you have multiple STA interfaces connected to |
536 | struct ath5k_hw *ah = sc->ah; | 530 | * different APs, ARPs are not received (most of the time?) |
537 | u32 rfilt; | 531 | * Enabling PROMISC appears to fix that probem. |
532 | */ | ||
533 | sc->filter_flags |= AR5K_RX_FILTER_PROM; | ||
534 | } | ||
538 | 535 | ||
539 | /* configure rx filter */ | ||
540 | rfilt = sc->filter_flags; | 536 | rfilt = sc->filter_flags; |
541 | ath5k_hw_set_rx_filter(ah, rfilt); | 537 | ath5k_hw_set_rx_filter(sc->ah, rfilt); |
542 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 538 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
543 | |||
544 | ath5k_update_bssid_mask_and_opmode(sc, vif); | ||
545 | } | 539 | } |
546 | 540 | ||
547 | static inline int | 541 | static inline int |
@@ -1117,7 +1111,7 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1117 | spin_unlock_bh(&sc->rxbuflock); | 1111 | spin_unlock_bh(&sc->rxbuflock); |
1118 | 1112 | ||
1119 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ | 1113 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ |
1120 | ath5k_mode_setup(sc, NULL); /* set filters, etc. */ | 1114 | ath5k_update_bssid_mask_and_opmode(sc, NULL); /* set filters, etc. */ |
1121 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ | 1115 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ |
1122 | 1116 | ||
1123 | return 0; | 1117 | return 0; |
@@ -2923,13 +2917,13 @@ ath5k_deinit_softc(struct ath5k_softc *sc) | |||
2923 | bool | 2917 | bool |
2924 | ath_any_vif_assoc(struct ath5k_softc *sc) | 2918 | ath_any_vif_assoc(struct ath5k_softc *sc) |
2925 | { | 2919 | { |
2926 | struct ath_vif_iter_data iter_data; | 2920 | struct ath5k_vif_iter_data iter_data; |
2927 | iter_data.hw_macaddr = NULL; | 2921 | iter_data.hw_macaddr = NULL; |
2928 | iter_data.any_assoc = false; | 2922 | iter_data.any_assoc = false; |
2929 | iter_data.need_set_hw_addr = false; | 2923 | iter_data.need_set_hw_addr = false; |
2930 | iter_data.found_active = true; | 2924 | iter_data.found_active = true; |
2931 | 2925 | ||
2932 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, | 2926 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, |
2933 | &iter_data); | 2927 | &iter_data); |
2934 | return iter_data.any_assoc; | 2928 | return iter_data.any_assoc; |
2935 | } | 2929 | } |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 8f919dca95f1..8d1df1fa2351 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -259,6 +259,19 @@ struct ath5k_softc { | |||
259 | struct survey_info survey; /* collected survey info */ | 259 | struct survey_info survey; /* collected survey info */ |
260 | }; | 260 | }; |
261 | 261 | ||
262 | struct ath5k_vif_iter_data { | ||
263 | const u8 *hw_macaddr; | ||
264 | u8 mask[ETH_ALEN]; | ||
265 | u8 active_mac[ETH_ALEN]; /* first active MAC */ | ||
266 | bool need_set_hw_addr; | ||
267 | bool found_active; | ||
268 | bool any_assoc; | ||
269 | enum nl80211_iftype opmode; | ||
270 | int n_stas; | ||
271 | }; | ||
272 | void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif); | ||
273 | |||
274 | |||
262 | #define ath5k_hw_hasbssidmask(_ah) \ | 275 | #define ath5k_hw_hasbssidmask(_ah) \ |
263 | (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) | 276 | (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) |
264 | #define ath5k_hw_hasveol(_ah) \ | 277 | #define ath5k_hw_hasveol(_ah) \ |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 1fbe3c0b9f08..c9b0b676adda 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -158,8 +158,7 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
158 | 158 | ||
159 | memcpy(&avf->lladdr, vif->addr, ETH_ALEN); | 159 | memcpy(&avf->lladdr, vif->addr, ETH_ALEN); |
160 | 160 | ||
161 | ath5k_mode_setup(sc, vif); | 161 | ath5k_update_bssid_mask_and_opmode(sc, vif); |
162 | |||
163 | ret = 0; | 162 | ret = 0; |
164 | end: | 163 | end: |
165 | mutex_unlock(&sc->lock); | 164 | mutex_unlock(&sc->lock); |
@@ -381,6 +380,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
381 | struct ath5k_softc *sc = hw->priv; | 380 | struct ath5k_softc *sc = hw->priv; |
382 | struct ath5k_hw *ah = sc->ah; | 381 | struct ath5k_hw *ah = sc->ah; |
383 | u32 mfilt[2], rfilt; | 382 | u32 mfilt[2], rfilt; |
383 | struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */ | ||
384 | 384 | ||
385 | mutex_lock(&sc->lock); | 385 | mutex_lock(&sc->lock); |
386 | 386 | ||
@@ -454,6 +454,21 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
454 | break; | 454 | break; |
455 | } | 455 | } |
456 | 456 | ||
457 | iter_data.hw_macaddr = NULL; | ||
458 | iter_data.n_stas = 0; | ||
459 | iter_data.need_set_hw_addr = false; | ||
460 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, | ||
461 | &iter_data); | ||
462 | |||
463 | /* Set up RX Filter */ | ||
464 | if (iter_data.n_stas > 1) { | ||
465 | /* If you have multiple STA interfaces connected to | ||
466 | * different APs, ARPs are not received (most of the time?) | ||
467 | * Enabling PROMISC appears to fix that probem. | ||
468 | */ | ||
469 | rfilt |= AR5K_RX_FILTER_PROM; | ||
470 | } | ||
471 | |||
457 | /* Set filters */ | 472 | /* Set filters */ |
458 | ath5k_hw_set_rx_filter(ah, rfilt); | 473 | ath5k_hw_set_rx_filter(ah, rfilt); |
459 | 474 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 993672105963..9cb0efa9b4c0 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -75,7 +75,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
75 | goto err_out; | 75 | goto err_out; |
76 | } | 76 | } |
77 | 77 | ||
78 | mem = ioremap_nocache(res->start, res->end - res->start + 1); | 78 | mem = ioremap_nocache(res->start, resource_size(res)); |
79 | if (mem == NULL) { | 79 | if (mem == NULL) { |
80 | dev_err(&pdev->dev, "ioremap failed\n"); | 80 | dev_err(&pdev->dev, "ioremap failed\n"); |
81 | ret = -ENOMEM; | 81 | ret = -ENOMEM; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 8d60f4f09acc..eb250d6b8038 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -1020,28 +1020,29 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
1020 | static void ar9003_hw_do_getnf(struct ath_hw *ah, | 1020 | static void ar9003_hw_do_getnf(struct ath_hw *ah, |
1021 | int16_t nfarray[NUM_NF_READINGS]) | 1021 | int16_t nfarray[NUM_NF_READINGS]) |
1022 | { | 1022 | { |
1023 | int16_t nf; | 1023 | #define AR_PHY_CH_MINCCA_PWR 0x1FF00000 |
1024 | 1024 | #define AR_PHY_CH_MINCCA_PWR_S 20 | |
1025 | nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); | 1025 | #define AR_PHY_CH_EXT_MINCCA_PWR 0x01FF0000 |
1026 | nfarray[0] = sign_extend32(nf, 8); | 1026 | #define AR_PHY_CH_EXT_MINCCA_PWR_S 16 |
1027 | |||
1028 | nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); | ||
1029 | nfarray[1] = sign_extend32(nf, 8); | ||
1030 | 1027 | ||
1031 | nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); | 1028 | int16_t nf; |
1032 | nfarray[2] = sign_extend32(nf, 8); | 1029 | int i; |
1033 | |||
1034 | if (!IS_CHAN_HT40(ah->curchan)) | ||
1035 | return; | ||
1036 | 1030 | ||
1037 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); | 1031 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
1038 | nfarray[3] = sign_extend32(nf, 8); | 1032 | if (ah->rxchainmask & BIT(i)) { |
1033 | nf = MS(REG_READ(ah, ah->nf_regs[i]), | ||
1034 | AR_PHY_CH_MINCCA_PWR); | ||
1035 | nfarray[i] = sign_extend32(nf, 8); | ||
1039 | 1036 | ||
1040 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); | 1037 | if (IS_CHAN_HT40(ah->curchan)) { |
1041 | nfarray[4] = sign_extend32(nf, 8); | 1038 | u8 ext_idx = AR9300_MAX_CHAINS + i; |
1042 | 1039 | ||
1043 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); | 1040 | nf = MS(REG_READ(ah, ah->nf_regs[ext_idx]), |
1044 | nfarray[5] = sign_extend32(nf, 8); | 1041 | AR_PHY_CH_EXT_MINCCA_PWR); |
1042 | nfarray[ext_idx] = sign_extend32(nf, 8); | ||
1043 | } | ||
1044 | } | ||
1045 | } | ||
1045 | } | 1046 | } |
1046 | 1047 | ||
1047 | static void ar9003_hw_set_nf_limits(struct ath_hw *ah) | 1048 | static void ar9003_hw_set_nf_limits(struct ath_hw *ah) |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 5cfcf8c235a4..8df5a92a20f1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/vmalloc.h> | ||
18 | #include <asm/unaligned.h> | 19 | #include <asm/unaligned.h> |
19 | 20 | ||
20 | #include "ath9k.h" | 21 | #include "ath9k.h" |
@@ -30,6 +31,19 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) | |||
30 | return 0; | 31 | return 0; |
31 | } | 32 | } |
32 | 33 | ||
34 | static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, | ||
35 | size_t count, loff_t *ppos) | ||
36 | { | ||
37 | u8 *buf = file->private_data; | ||
38 | return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); | ||
39 | } | ||
40 | |||
41 | static int ath9k_debugfs_release_buf(struct inode *inode, struct file *file) | ||
42 | { | ||
43 | vfree(file->private_data); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
33 | #ifdef CONFIG_ATH_DEBUG | 47 | #ifdef CONFIG_ATH_DEBUG |
34 | 48 | ||
35 | static ssize_t read_file_debug(struct file *file, char __user *user_buf, | 49 | static ssize_t read_file_debug(struct file *file, char __user *user_buf, |
@@ -548,10 +562,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
548 | PR("hw-tx-proc-desc: ", txprocdesc); | 562 | PR("hw-tx-proc-desc: ", txprocdesc); |
549 | len += snprintf(buf + len, size - len, | 563 | len += snprintf(buf + len, size - len, |
550 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", | 564 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", |
551 | &(sc->tx.txq_map[WME_AC_BE]), | 565 | sc->tx.txq_map[WME_AC_BE], |
552 | &(sc->tx.txq_map[WME_AC_BK]), | 566 | sc->tx.txq_map[WME_AC_BK], |
553 | &(sc->tx.txq_map[WME_AC_VI]), | 567 | sc->tx.txq_map[WME_AC_VI], |
554 | &(sc->tx.txq_map[WME_AC_VO])); | 568 | sc->tx.txq_map[WME_AC_VO]); |
555 | if (len >= size) | 569 | if (len >= size) |
556 | goto done; | 570 | goto done; |
557 | 571 | ||
@@ -1027,6 +1041,42 @@ static const struct file_operations fops_regval = { | |||
1027 | .llseek = default_llseek, | 1041 | .llseek = default_llseek, |
1028 | }; | 1042 | }; |
1029 | 1043 | ||
1044 | #define REGDUMP_LINE_SIZE 20 | ||
1045 | |||
1046 | static int open_file_regdump(struct inode *inode, struct file *file) | ||
1047 | { | ||
1048 | struct ath_softc *sc = inode->i_private; | ||
1049 | unsigned int len = 0; | ||
1050 | u8 *buf; | ||
1051 | int i; | ||
1052 | unsigned long num_regs, regdump_len, max_reg_offset; | ||
1053 | |||
1054 | max_reg_offset = AR_SREV_9300_20_OR_LATER(sc->sc_ah) ? 0x16bd4 : 0xb500; | ||
1055 | num_regs = max_reg_offset / 4 + 1; | ||
1056 | regdump_len = num_regs * REGDUMP_LINE_SIZE + 1; | ||
1057 | buf = vmalloc(regdump_len); | ||
1058 | if (!buf) | ||
1059 | return -ENOMEM; | ||
1060 | |||
1061 | ath9k_ps_wakeup(sc); | ||
1062 | for (i = 0; i < num_regs; i++) | ||
1063 | len += scnprintf(buf + len, regdump_len - len, | ||
1064 | "0x%06x 0x%08x\n", i << 2, REG_READ(sc->sc_ah, i << 2)); | ||
1065 | ath9k_ps_restore(sc); | ||
1066 | |||
1067 | file->private_data = buf; | ||
1068 | |||
1069 | return 0; | ||
1070 | } | ||
1071 | |||
1072 | static const struct file_operations fops_regdump = { | ||
1073 | .open = open_file_regdump, | ||
1074 | .read = ath9k_debugfs_read_buf, | ||
1075 | .release = ath9k_debugfs_release_buf, | ||
1076 | .owner = THIS_MODULE, | ||
1077 | .llseek = default_llseek,/* read accesses f_pos */ | ||
1078 | }; | ||
1079 | |||
1030 | int ath9k_init_debug(struct ath_hw *ah) | 1080 | int ath9k_init_debug(struct ath_hw *ah) |
1031 | { | 1081 | { |
1032 | struct ath_common *common = ath9k_hw_common(ah); | 1082 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1091,6 +1141,10 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1091 | sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) | 1141 | sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) |
1092 | goto err; | 1142 | goto err; |
1093 | 1143 | ||
1144 | if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, | ||
1145 | sc, &fops_regdump)) | ||
1146 | goto err; | ||
1147 | |||
1094 | sc->debug.regidx = 0; | 1148 | sc->debug.regidx = 0; |
1095 | return 0; | 1149 | return 0; |
1096 | err: | 1150 | err: |
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 47033f6a1c2b..480595f04411 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -92,7 +92,7 @@ config B43_PHY_N | |||
92 | ---help--- | 92 | ---help--- |
93 | Support for the N-PHY. | 93 | Support for the N-PHY. |
94 | 94 | ||
95 | This enables support for devices with N-PHY revision up to 2. | 95 | This enables support for devices with N-PHY. |
96 | 96 | ||
97 | Say N if you expect high stability and performance. Saying Y will not | 97 | Say N if you expect high stability and performance. Saying Y will not |
98 | affect other devices support and may provide support for basic needs. | 98 | affect other devices support and may provide support for basic needs. |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 9f5a3c993239..8a00f9a95dbb 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -1168,23 +1168,98 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) | |||
1168 | static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) | 1168 | static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) |
1169 | { | 1169 | { |
1170 | struct b43_phy_n *nphy = dev->phy.n; | 1170 | struct b43_phy_n *nphy = dev->phy.n; |
1171 | struct ssb_sprom *sprom = &(dev->dev->bus->sprom); | ||
1172 | |||
1173 | /* PHY rev 0, 1, 2 */ | ||
1171 | u8 i, j; | 1174 | u8 i, j; |
1172 | u8 code; | 1175 | u8 code; |
1173 | u16 tmp; | 1176 | u16 tmp; |
1177 | u8 rfseq_events[3] = { 6, 8, 7 }; | ||
1178 | u8 rfseq_delays[3] = { 10, 30, 1 }; | ||
1174 | 1179 | ||
1175 | /* TODO: for PHY >= 3 | 1180 | /* PHY rev >= 3 */ |
1176 | s8 *lna1_gain, *lna2_gain; | 1181 | bool ghz5; |
1177 | u8 *gain_db, *gain_bits; | 1182 | bool ext_lna; |
1178 | u16 *rfseq_init; | 1183 | u16 rssi_gain; |
1184 | struct nphy_gain_ctl_workaround_entry *e; | ||
1179 | u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; | 1185 | u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; |
1180 | u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; | 1186 | u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; |
1181 | */ | ||
1182 | |||
1183 | u8 rfseq_events[3] = { 6, 8, 7 }; | ||
1184 | u8 rfseq_delays[3] = { 10, 30, 1 }; | ||
1185 | 1187 | ||
1186 | if (dev->phy.rev >= 3) { | 1188 | if (dev->phy.rev >= 3) { |
1187 | /* TODO */ | 1189 | /* Prepare values */ |
1190 | ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL) | ||
1191 | & B43_NPHY_BANDCTL_5GHZ; | ||
1192 | ext_lna = sprom->boardflags_lo & B43_BFL_EXTLNA; | ||
1193 | e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna); | ||
1194 | if (ghz5 && dev->phy.rev >= 5) | ||
1195 | rssi_gain = 0x90; | ||
1196 | else | ||
1197 | rssi_gain = 0x50; | ||
1198 | |||
1199 | b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040); | ||
1200 | |||
1201 | /* Set Clip 2 detect */ | ||
1202 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
1203 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
1204 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
1205 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
1206 | |||
1207 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC, | ||
1208 | 0x17); | ||
1209 | b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAG1_IDAC, | ||
1210 | 0x17); | ||
1211 | b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG2_IDAC, 0xF0); | ||
1212 | b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG2_IDAC, 0xF0); | ||
1213 | b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_POLE, 0x00); | ||
1214 | b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_POLE, 0x00); | ||
1215 | b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_GAIN, | ||
1216 | rssi_gain); | ||
1217 | b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_GAIN, | ||
1218 | rssi_gain); | ||
1219 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAA1_IDAC, | ||
1220 | 0x17); | ||
1221 | b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAA1_IDAC, | ||
1222 | 0x17); | ||
1223 | b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA2_IDAC, 0xFF); | ||
1224 | b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA2_IDAC, 0xFF); | ||
1225 | |||
1226 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 8), 4, e->lna1_gain); | ||
1227 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 8), 4, e->lna1_gain); | ||
1228 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 16), 4, e->lna2_gain); | ||
1229 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 16), 4, e->lna2_gain); | ||
1230 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 32), 10, e->gain_db); | ||
1231 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 32), 10, e->gain_db); | ||
1232 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 32), 10, e->gain_bits); | ||
1233 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 32), 10, e->gain_bits); | ||
1234 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 0x40), 6, lpf_gain); | ||
1235 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 0x40), 6, lpf_gain); | ||
1236 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits); | ||
1237 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits); | ||
1238 | |||
1239 | b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); | ||
1240 | b43_phy_write(dev, 0x2A7, e->init_gain); | ||
1241 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, | ||
1242 | e->rfseq_init); | ||
1243 | b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); | ||
1244 | |||
1245 | /* TODO: check defines. Do not match variables names */ | ||
1246 | b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); | ||
1247 | b43_phy_write(dev, 0x2A9, e->cliphi_gain); | ||
1248 | b43_phy_write(dev, B43_NPHY_C1_CLIP2_GAIN, e->clipmd_gain); | ||
1249 | b43_phy_write(dev, 0x2AB, e->clipmd_gain); | ||
1250 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_HIGAIN, e->cliplo_gain); | ||
1251 | b43_phy_write(dev, 0x2AD, e->cliplo_gain); | ||
1252 | |||
1253 | b43_phy_maskset(dev, 0x27D, 0xFF00, e->crsmin); | ||
1254 | b43_phy_maskset(dev, 0x280, 0xFF00, e->crsminl); | ||
1255 | b43_phy_maskset(dev, 0x283, 0xFF00, e->crsminu); | ||
1256 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip); | ||
1257 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip); | ||
1258 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
1259 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, e->wlclip); | ||
1260 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
1261 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, e->wlclip); | ||
1262 | b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); | ||
1188 | } else { | 1263 | } else { |
1189 | /* Set Clip 2 detect */ | 1264 | /* Set Clip 2 detect */ |
1190 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | 1265 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, |
@@ -1308,6 +1383,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) | |||
1308 | u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; | 1383 | u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; |
1309 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | 1384 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; |
1310 | 1385 | ||
1386 | u16 tmp16; | ||
1387 | u32 tmp32; | ||
1388 | |||
1311 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | 1389 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) |
1312 | b43_nphy_classifier(dev, 1, 0); | 1390 | b43_nphy_classifier(dev, 1, 0); |
1313 | else | 1391 | else |
@@ -1320,7 +1398,82 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) | |||
1320 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | 1398 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); |
1321 | 1399 | ||
1322 | if (dev->phy.rev >= 3) { | 1400 | if (dev->phy.rev >= 3) { |
1401 | tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); | ||
1402 | tmp32 &= 0xffffff; | ||
1403 | b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32); | ||
1404 | |||
1405 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125); | ||
1406 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3); | ||
1407 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105); | ||
1408 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E); | ||
1409 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); | ||
1410 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); | ||
1411 | |||
1412 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); | ||
1413 | b43_phy_write(dev, 0x2AE, 0x000C); | ||
1414 | |||
1323 | /* TODO */ | 1415 | /* TODO */ |
1416 | |||
1417 | tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? | ||
1418 | 0x2 : 0x9C40; | ||
1419 | b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); | ||
1420 | |||
1421 | b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); | ||
1422 | |||
1423 | b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); | ||
1424 | b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); | ||
1425 | |||
1426 | b43_nphy_gain_ctrl_workarounds(dev); | ||
1427 | |||
1428 | b43_ntab_write(dev, B43_NTAB32(8, 0), 2); | ||
1429 | b43_ntab_write(dev, B43_NTAB32(8, 16), 2); | ||
1430 | |||
1431 | /* TODO */ | ||
1432 | |||
1433 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00); | ||
1434 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00); | ||
1435 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06); | ||
1436 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06); | ||
1437 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07); | ||
1438 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07); | ||
1439 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88); | ||
1440 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); | ||
1441 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||
1442 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||
1443 | |||
1444 | /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ | ||
1445 | |||
1446 | if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR && | ||
1447 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || | ||
1448 | (bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR && | ||
1449 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) | ||
1450 | tmp32 = 0x00088888; | ||
1451 | else | ||
1452 | tmp32 = 0x88888888; | ||
1453 | b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32); | ||
1454 | b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32); | ||
1455 | b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32); | ||
1456 | |||
1457 | if (dev->phy.rev == 4 && | ||
1458 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
1459 | b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC, | ||
1460 | 0x70); | ||
1461 | b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC, | ||
1462 | 0x70); | ||
1463 | } | ||
1464 | |||
1465 | b43_phy_write(dev, 0x224, 0x039C); | ||
1466 | b43_phy_write(dev, 0x225, 0x0357); | ||
1467 | b43_phy_write(dev, 0x226, 0x0317); | ||
1468 | b43_phy_write(dev, 0x227, 0x02D7); | ||
1469 | b43_phy_write(dev, 0x228, 0x039C); | ||
1470 | b43_phy_write(dev, 0x229, 0x0357); | ||
1471 | b43_phy_write(dev, 0x22A, 0x0317); | ||
1472 | b43_phy_write(dev, 0x22B, 0x02D7); | ||
1473 | b43_phy_write(dev, 0x22C, 0x039C); | ||
1474 | b43_phy_write(dev, 0x22D, 0x0357); | ||
1475 | b43_phy_write(dev, 0x22E, 0x0317); | ||
1476 | b43_phy_write(dev, 0x22F, 0x02D7); | ||
1324 | } else { | 1477 | } else { |
1325 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && | 1478 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && |
1326 | nphy->band5g_pwrgain) { | 1479 | nphy->band5g_pwrgain) { |
@@ -3878,10 +4031,14 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, | |||
3878 | } | 4031 | } |
3879 | } | 4032 | } |
3880 | 4033 | ||
4034 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */ | ||
3881 | static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) | 4035 | static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) |
3882 | { | 4036 | { |
3883 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, | 4037 | u16 val = on ? 0 : 0x7FFF; |
3884 | on ? 0 : 0x7FFF); | 4038 | |
4039 | if (dev->phy.rev >= 3) | ||
4040 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, val); | ||
4041 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, val); | ||
3885 | } | 4042 | } |
3886 | 4043 | ||
3887 | static int b43_nphy_op_switch_channel(struct b43_wldev *dev, | 4044 | static int b43_nphy_op_switch_channel(struct b43_wldev *dev, |
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index c42b2acea24e..2de483b3d3ba 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c | |||
@@ -2709,6 +2709,79 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { | |||
2709 | { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ | 2709 | { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ |
2710 | }; | 2710 | }; |
2711 | 2711 | ||
2712 | struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = { | ||
2713 | { /* 2GHz */ | ||
2714 | { /* PHY rev 3 */ | ||
2715 | { 7, 11, 16, 23 }, | ||
2716 | { -5, 6, 10, 14 }, | ||
2717 | { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, | ||
2718 | { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | ||
2719 | 0x627E, | ||
2720 | { 0x613F, 0x613F, 0x613F, 0x613F }, | ||
2721 | 0x107E, 0x0066, 0x0074, | ||
2722 | 0x18, 0x18, 0x18, | ||
2723 | 0x020D, 0x5, | ||
2724 | }, | ||
2725 | { /* PHY rev 4 */ | ||
2726 | { 8, 12, 17, 25 }, | ||
2727 | { -5, 6, 10, 14 }, | ||
2728 | { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, | ||
2729 | { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | ||
2730 | 0x527E, | ||
2731 | { 0x513F, 0x513F, 0x513F, 0x513F }, | ||
2732 | 0x007E, 0x0066, 0x0074, | ||
2733 | 0x18, 0x18, 0x18, | ||
2734 | 0x01A1, 0x5, | ||
2735 | }, | ||
2736 | { /* PHY rev 5+ */ | ||
2737 | { 9, 13, 18, 26 }, | ||
2738 | { -3, 7, 11, 16 }, | ||
2739 | { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, | ||
2740 | { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | ||
2741 | 0x427E, /* invalid for external LNA! */ | ||
2742 | { 0x413F, 0x413F, 0x413F, 0x413F }, /* invalid for external LNA! */ | ||
2743 | 0x1076, 0x0066, 0x106A, | ||
2744 | 0xC, 0xC, 0xC, | ||
2745 | 0x01D0, 0x5, | ||
2746 | }, | ||
2747 | }, | ||
2748 | { /* 5GHz */ | ||
2749 | { /* PHY rev 3 */ | ||
2750 | { 7, 11, 17, 23 }, | ||
2751 | { -6, 2, 6, 10 }, | ||
2752 | { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }, | ||
2753 | { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, | ||
2754 | 0x52DE, | ||
2755 | { 0x516F, 0x516F, 0x516F, 0x516F }, | ||
2756 | 0x00DE, 0x00CA, 0x00CC, | ||
2757 | 0x1E, 0x1E, 0x1E, | ||
2758 | 0x01A1, 25, | ||
2759 | }, | ||
2760 | { /* PHY rev 4 */ | ||
2761 | { 8, 12, 18, 23 }, | ||
2762 | { -5, 2, 6, 10 }, | ||
2763 | { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD }, | ||
2764 | { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, | ||
2765 | 0x629E, | ||
2766 | { 0x614F, 0x614F, 0x614F, 0x614F }, | ||
2767 | 0x029E, 0x1084, 0x0086, | ||
2768 | 0x24, 0x24, 0x24, | ||
2769 | 0x0107, 25, | ||
2770 | }, | ||
2771 | { /* PHY rev 5+ */ | ||
2772 | { 6, 10, 16, 21 }, | ||
2773 | { -7, 0, 4, 8 }, | ||
2774 | { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD }, | ||
2775 | { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, | ||
2776 | 0x729E, | ||
2777 | { 0x714F, 0x714F, 0x714F, 0x714F }, | ||
2778 | 0x029E, 0x2084, 0x2086, | ||
2779 | 0x24, 0x24, 0x24, | ||
2780 | 0x00A9, 25, | ||
2781 | }, | ||
2782 | }, | ||
2783 | }; | ||
2784 | |||
2712 | static inline void assert_ntab_array_sizes(void) | 2785 | static inline void assert_ntab_array_sizes(void) |
2713 | { | 2786 | { |
2714 | #undef check | 2787 | #undef check |
@@ -2957,3 +3030,33 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) | |||
2957 | /* Volatile tables */ | 3030 | /* Volatile tables */ |
2958 | /* TODO */ | 3031 | /* TODO */ |
2959 | } | 3032 | } |
3033 | |||
3034 | struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | ||
3035 | struct b43_wldev *dev, bool ghz5, bool ext_lna) | ||
3036 | { | ||
3037 | struct nphy_gain_ctl_workaround_entry *e; | ||
3038 | u8 phy_idx; | ||
3039 | |||
3040 | B43_WARN_ON(dev->phy.rev < 3); | ||
3041 | if (dev->phy.rev >= 5) | ||
3042 | phy_idx = 2; | ||
3043 | else if (dev->phy.rev == 4) | ||
3044 | phy_idx = 1; | ||
3045 | else | ||
3046 | phy_idx = 0; | ||
3047 | |||
3048 | e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; | ||
3049 | |||
3050 | /* Only one entry differs for external LNA, so instead making whole | ||
3051 | * table 2 times bigger, hack is here | ||
3052 | */ | ||
3053 | if (!ghz5 && dev->phy.rev >= 5 && ext_lna) { | ||
3054 | e->rfseq_init[0] &= 0x0FFF; | ||
3055 | e->rfseq_init[1] &= 0x0FFF; | ||
3056 | e->rfseq_init[2] &= 0x0FFF; | ||
3057 | e->rfseq_init[3] &= 0x0FFF; | ||
3058 | e->init_gain &= 0x0FFF; | ||
3059 | } | ||
3060 | |||
3061 | return e; | ||
3062 | } | ||
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 016a480b2dc6..18569367ce43 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h | |||
@@ -35,6 +35,31 @@ struct nphy_rf_control_override_rev3 { | |||
35 | u8 val_addr1; | 35 | u8 val_addr1; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct nphy_gain_ctl_workaround_entry { | ||
39 | s8 lna1_gain[4]; | ||
40 | s8 lna2_gain[4]; | ||
41 | u8 gain_db[10]; | ||
42 | u8 gain_bits[10]; | ||
43 | |||
44 | u16 init_gain; | ||
45 | u16 rfseq_init[4]; | ||
46 | |||
47 | u16 cliphi_gain; | ||
48 | u16 clipmd_gain; | ||
49 | u16 cliplo_gain; | ||
50 | |||
51 | u16 crsmin; | ||
52 | u16 crsminl; | ||
53 | u16 crsminu; | ||
54 | |||
55 | u16 nbclip; | ||
56 | u16 wlclip; | ||
57 | }; | ||
58 | |||
59 | /* Get entry with workaround values for gain ctl. Does not return NULL. */ | ||
60 | struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | ||
61 | struct b43_wldev *dev, bool ghz5, bool ext_lna); | ||
62 | |||
38 | /* Get the NPHY Channel Switch Table entry for a channel. | 63 | /* Get the NPHY Channel Switch Table entry for a channel. |
39 | * Returns NULL on failure to find an entry. */ | 64 | * Returns NULL on failure to find an entry. */ |
40 | const struct b43_nphy_channeltab_entry_rev2 * | 65 | const struct b43_nphy_channeltab_entry_rev2 * |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index d7d049c7a4fa..d9e1d9bad581 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h | |||
@@ -961,7 +961,7 @@ struct ipw_country_channel_info { | |||
961 | struct ipw_country_info { | 961 | struct ipw_country_info { |
962 | u8 id; | 962 | u8 id; |
963 | u8 length; | 963 | u8 length; |
964 | u8 country_str[3]; | 964 | u8 country_str[IEEE80211_COUNTRY_STRING_LEN]; |
965 | struct ipw_country_channel_info groups[7]; | 965 | struct ipw_country_channel_info groups[7]; |
966 | } __packed; | 966 | } __packed; |
967 | 967 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index fd142bee9189..25fccf9a3001 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -533,9 +533,10 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
533 | 533 | ||
534 | void iwlagn_temperature(struct iwl_priv *priv) | 534 | void iwlagn_temperature(struct iwl_priv *priv) |
535 | { | 535 | { |
536 | /* store temperature from statistics (in Celsius) */ | 536 | /* store temperature from correct statistics (in Celsius) */ |
537 | priv->temperature = | 537 | priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ? |
538 | le32_to_cpu(priv->_agn.statistics.general.common.temperature); | 538 | priv->_agn.statistics_bt.general.common.temperature : |
539 | priv->_agn.statistics.general.common.temperature); | ||
539 | iwl_tt_handler(priv); | 540 | iwl_tt_handler(priv); |
540 | } | 541 | } |
541 | 542 | ||
@@ -994,241 +995,6 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) | |||
994 | return -1; | 995 | return -1; |
995 | } | 996 | } |
996 | 997 | ||
997 | /* Calc max signal level (dBm) among 3 possible receivers */ | ||
998 | static inline int iwlagn_calc_rssi(struct iwl_priv *priv, | ||
999 | struct iwl_rx_phy_res *rx_resp) | ||
1000 | { | ||
1001 | return priv->cfg->ops->utils->calc_rssi(priv, rx_resp); | ||
1002 | } | ||
1003 | |||
1004 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | ||
1005 | { | ||
1006 | u32 decrypt_out = 0; | ||
1007 | |||
1008 | if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == | ||
1009 | RX_RES_STATUS_STATION_FOUND) | ||
1010 | decrypt_out |= (RX_RES_STATUS_STATION_FOUND | | ||
1011 | RX_RES_STATUS_NO_STATION_INFO_MISMATCH); | ||
1012 | |||
1013 | decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); | ||
1014 | |||
1015 | /* packet was not encrypted */ | ||
1016 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
1017 | RX_RES_STATUS_SEC_TYPE_NONE) | ||
1018 | return decrypt_out; | ||
1019 | |||
1020 | /* packet was encrypted with unknown alg */ | ||
1021 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
1022 | RX_RES_STATUS_SEC_TYPE_ERR) | ||
1023 | return decrypt_out; | ||
1024 | |||
1025 | /* decryption was not done in HW */ | ||
1026 | if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != | ||
1027 | RX_MPDU_RES_STATUS_DEC_DONE_MSK) | ||
1028 | return decrypt_out; | ||
1029 | |||
1030 | switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { | ||
1031 | |||
1032 | case RX_RES_STATUS_SEC_TYPE_CCMP: | ||
1033 | /* alg is CCM: check MIC only */ | ||
1034 | if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) | ||
1035 | /* Bad MIC */ | ||
1036 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
1037 | else | ||
1038 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
1039 | |||
1040 | break; | ||
1041 | |||
1042 | case RX_RES_STATUS_SEC_TYPE_TKIP: | ||
1043 | if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { | ||
1044 | /* Bad TTAK */ | ||
1045 | decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; | ||
1046 | break; | ||
1047 | } | ||
1048 | /* fall through if TTAK OK */ | ||
1049 | default: | ||
1050 | if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) | ||
1051 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
1052 | else | ||
1053 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
1054 | break; | ||
1055 | } | ||
1056 | |||
1057 | IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n", | ||
1058 | decrypt_in, decrypt_out); | ||
1059 | |||
1060 | return decrypt_out; | ||
1061 | } | ||
1062 | |||
1063 | static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | ||
1064 | struct ieee80211_hdr *hdr, | ||
1065 | u16 len, | ||
1066 | u32 ampdu_status, | ||
1067 | struct iwl_rx_mem_buffer *rxb, | ||
1068 | struct ieee80211_rx_status *stats) | ||
1069 | { | ||
1070 | struct sk_buff *skb; | ||
1071 | __le16 fc = hdr->frame_control; | ||
1072 | |||
1073 | /* We only process data packets if the interface is open */ | ||
1074 | if (unlikely(!priv->is_open)) { | ||
1075 | IWL_DEBUG_DROP_LIMIT(priv, | ||
1076 | "Dropping packet while interface is not open.\n"); | ||
1077 | return; | ||
1078 | } | ||
1079 | |||
1080 | /* In case of HW accelerated crypto and bad decryption, drop */ | ||
1081 | if (!priv->cfg->mod_params->sw_crypto && | ||
1082 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | ||
1083 | return; | ||
1084 | |||
1085 | skb = dev_alloc_skb(128); | ||
1086 | if (!skb) { | ||
1087 | IWL_ERR(priv, "dev_alloc_skb failed\n"); | ||
1088 | return; | ||
1089 | } | ||
1090 | |||
1091 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | ||
1092 | |||
1093 | iwl_update_stats(priv, false, fc, len); | ||
1094 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | ||
1095 | |||
1096 | ieee80211_rx(priv->hw, skb); | ||
1097 | priv->alloc_rxb_page--; | ||
1098 | rxb->page = NULL; | ||
1099 | } | ||
1100 | |||
1101 | /* Called for REPLY_RX (legacy ABG frames), or | ||
1102 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | ||
1103 | void iwlagn_rx_reply_rx(struct iwl_priv *priv, | ||
1104 | struct iwl_rx_mem_buffer *rxb) | ||
1105 | { | ||
1106 | struct ieee80211_hdr *header; | ||
1107 | struct ieee80211_rx_status rx_status; | ||
1108 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1109 | struct iwl_rx_phy_res *phy_res; | ||
1110 | __le32 rx_pkt_status; | ||
1111 | struct iwl_rx_mpdu_res_start *amsdu; | ||
1112 | u32 len; | ||
1113 | u32 ampdu_status; | ||
1114 | u32 rate_n_flags; | ||
1115 | |||
1116 | /** | ||
1117 | * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently. | ||
1118 | * REPLY_RX: physical layer info is in this buffer | ||
1119 | * REPLY_RX_MPDU_CMD: physical layer info was sent in separate | ||
1120 | * command and cached in priv->last_phy_res | ||
1121 | * | ||
1122 | * Here we set up local variables depending on which command is | ||
1123 | * received. | ||
1124 | */ | ||
1125 | if (pkt->hdr.cmd == REPLY_RX) { | ||
1126 | phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; | ||
1127 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) | ||
1128 | + phy_res->cfg_phy_cnt); | ||
1129 | |||
1130 | len = le16_to_cpu(phy_res->byte_count); | ||
1131 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + | ||
1132 | phy_res->cfg_phy_cnt + len); | ||
1133 | ampdu_status = le32_to_cpu(rx_pkt_status); | ||
1134 | } else { | ||
1135 | if (!priv->_agn.last_phy_res_valid) { | ||
1136 | IWL_ERR(priv, "MPDU frame without cached PHY data\n"); | ||
1137 | return; | ||
1138 | } | ||
1139 | phy_res = &priv->_agn.last_phy_res; | ||
1140 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; | ||
1141 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); | ||
1142 | len = le16_to_cpu(amsdu->byte_count); | ||
1143 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); | ||
1144 | ampdu_status = iwlagn_translate_rx_status(priv, | ||
1145 | le32_to_cpu(rx_pkt_status)); | ||
1146 | } | ||
1147 | |||
1148 | if ((unlikely(phy_res->cfg_phy_cnt > 20))) { | ||
1149 | IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", | ||
1150 | phy_res->cfg_phy_cnt); | ||
1151 | return; | ||
1152 | } | ||
1153 | |||
1154 | if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || | ||
1155 | !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { | ||
1156 | IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", | ||
1157 | le32_to_cpu(rx_pkt_status)); | ||
1158 | return; | ||
1159 | } | ||
1160 | |||
1161 | /* This will be used in several places later */ | ||
1162 | rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); | ||
1163 | |||
1164 | /* rx_status carries information about the packet to mac80211 */ | ||
1165 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); | ||
1166 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | ||
1167 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
1168 | rx_status.freq = | ||
1169 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), | ||
1170 | rx_status.band); | ||
1171 | rx_status.rate_idx = | ||
1172 | iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); | ||
1173 | rx_status.flag = 0; | ||
1174 | |||
1175 | /* TSF isn't reliable. In order to allow smooth user experience, | ||
1176 | * this W/A doesn't propagate it to the mac80211 */ | ||
1177 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ | ||
1178 | |||
1179 | priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); | ||
1180 | |||
1181 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | ||
1182 | rx_status.signal = iwlagn_calc_rssi(priv, phy_res); | ||
1183 | |||
1184 | iwl_dbg_log_rx_data_frame(priv, len, header); | ||
1185 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", | ||
1186 | rx_status.signal, (unsigned long long)rx_status.mactime); | ||
1187 | |||
1188 | /* | ||
1189 | * "antenna number" | ||
1190 | * | ||
1191 | * It seems that the antenna field in the phy flags value | ||
1192 | * is actually a bit field. This is undefined by radiotap, | ||
1193 | * it wants an actual antenna number but I always get "7" | ||
1194 | * for most legacy frames I receive indicating that the | ||
1195 | * same frame was received on all three RX chains. | ||
1196 | * | ||
1197 | * I think this field should be removed in favor of a | ||
1198 | * new 802.11n radiotap field "RX chains" that is defined | ||
1199 | * as a bitmask. | ||
1200 | */ | ||
1201 | rx_status.antenna = | ||
1202 | (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) | ||
1203 | >> RX_RES_PHY_FLAGS_ANTENNA_POS; | ||
1204 | |||
1205 | /* set the preamble flag if appropriate */ | ||
1206 | if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) | ||
1207 | rx_status.flag |= RX_FLAG_SHORTPRE; | ||
1208 | |||
1209 | /* Set up the HT phy flags */ | ||
1210 | if (rate_n_flags & RATE_MCS_HT_MSK) | ||
1211 | rx_status.flag |= RX_FLAG_HT; | ||
1212 | if (rate_n_flags & RATE_MCS_HT40_MSK) | ||
1213 | rx_status.flag |= RX_FLAG_40MHZ; | ||
1214 | if (rate_n_flags & RATE_MCS_SGI_MSK) | ||
1215 | rx_status.flag |= RX_FLAG_SHORT_GI; | ||
1216 | |||
1217 | iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, | ||
1218 | rxb, &rx_status); | ||
1219 | } | ||
1220 | |||
1221 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | ||
1222 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | ||
1223 | void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, | ||
1224 | struct iwl_rx_mem_buffer *rxb) | ||
1225 | { | ||
1226 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1227 | priv->_agn.last_phy_res_valid = true; | ||
1228 | memcpy(&priv->_agn.last_phy_res, pkt->u.raw, | ||
1229 | sizeof(struct iwl_rx_phy_res)); | ||
1230 | } | ||
1231 | |||
1232 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, | 998 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, |
1233 | struct ieee80211_vif *vif, | 999 | struct ieee80211_vif *vif, |
1234 | enum ieee80211_band band, | 1000 | enum ieee80211_band band, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f189bbe78fa6..e0cd3e27a0d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -424,60 +424,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | /****************************************************************************** | ||
428 | * | ||
429 | * Generic RX handler implementations | ||
430 | * | ||
431 | ******************************************************************************/ | ||
432 | static void iwl_rx_reply_alive(struct iwl_priv *priv, | ||
433 | struct iwl_rx_mem_buffer *rxb) | ||
434 | { | ||
435 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
436 | struct iwl_alive_resp *palive; | ||
437 | struct delayed_work *pwork; | ||
438 | |||
439 | palive = &pkt->u.alive_frame; | ||
440 | |||
441 | IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | ||
442 | "0x%01X 0x%01X\n", | ||
443 | palive->is_valid, palive->ver_type, | ||
444 | palive->ver_subtype); | ||
445 | |||
446 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) { | ||
447 | IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); | ||
448 | memcpy(&priv->card_alive_init, | ||
449 | &pkt->u.alive_frame, | ||
450 | sizeof(struct iwl_init_alive_resp)); | ||
451 | pwork = &priv->init_alive_start; | ||
452 | } else { | ||
453 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||
454 | memcpy(&priv->card_alive, &pkt->u.alive_frame, | ||
455 | sizeof(struct iwl_alive_resp)); | ||
456 | pwork = &priv->alive_start; | ||
457 | } | ||
458 | |||
459 | /* We delay the ALIVE response by 5ms to | ||
460 | * give the HW RF Kill time to activate... */ | ||
461 | if (palive->is_valid == UCODE_VALID_OK) | ||
462 | queue_delayed_work(priv->workqueue, pwork, | ||
463 | msecs_to_jiffies(5)); | ||
464 | else { | ||
465 | IWL_WARN(priv, "%s uCode did not respond OK.\n", | ||
466 | (palive->ver_subtype == INITIALIZE_SUBTYPE) ? | ||
467 | "init" : "runtime"); | ||
468 | /* | ||
469 | * If fail to load init uCode, | ||
470 | * let's try to load the init uCode again. | ||
471 | * We should not get into this situation, but if it | ||
472 | * does happen, we should not move on and loading "runtime" | ||
473 | * without proper calibrate the device. | ||
474 | */ | ||
475 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) | ||
476 | priv->ucode_type = UCODE_NONE; | ||
477 | queue_work(priv->workqueue, &priv->restart); | ||
478 | } | ||
479 | } | ||
480 | |||
481 | static void iwl_bg_beacon_update(struct work_struct *work) | 427 | static void iwl_bg_beacon_update(struct work_struct *work) |
482 | { | 428 | { |
483 | struct iwl_priv *priv = | 429 | struct iwl_priv *priv = |
@@ -712,83 +658,6 @@ static void iwl_bg_ucode_trace(unsigned long data) | |||
712 | } | 658 | } |
713 | } | 659 | } |
714 | 660 | ||
715 | static void iwlagn_rx_beacon_notif(struct iwl_priv *priv, | ||
716 | struct iwl_rx_mem_buffer *rxb) | ||
717 | { | ||
718 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
719 | struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; | ||
720 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
721 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); | ||
722 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | ||
723 | |||
724 | IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " | ||
725 | "tsf:0x%.8x%.8x rate:%d\n", | ||
726 | status & TX_STATUS_MSK, | ||
727 | beacon->beacon_notify_hdr.failure_frame, | ||
728 | le32_to_cpu(beacon->ibss_mgr_status), | ||
729 | le32_to_cpu(beacon->high_tsf), | ||
730 | le32_to_cpu(beacon->low_tsf), rate); | ||
731 | #endif | ||
732 | |||
733 | priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); | ||
734 | |||
735 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
736 | queue_work(priv->workqueue, &priv->beacon_update); | ||
737 | } | ||
738 | |||
739 | /* Handle notification from uCode that card's power state is changing | ||
740 | * due to software, hardware, or critical temperature RFKILL */ | ||
741 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, | ||
742 | struct iwl_rx_mem_buffer *rxb) | ||
743 | { | ||
744 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
745 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | ||
746 | unsigned long status = priv->status; | ||
747 | |||
748 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", | ||
749 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | ||
750 | (flags & SW_CARD_DISABLED) ? "Kill" : "On", | ||
751 | (flags & CT_CARD_DISABLED) ? | ||
752 | "Reached" : "Not reached"); | ||
753 | |||
754 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | | ||
755 | CT_CARD_DISABLED)) { | ||
756 | |||
757 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
758 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
759 | |||
760 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, | ||
761 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | ||
762 | |||
763 | if (!(flags & RXON_CARD_DISABLED)) { | ||
764 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||
765 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
766 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, | ||
767 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | ||
768 | } | ||
769 | if (flags & CT_CARD_DISABLED) | ||
770 | iwl_tt_enter_ct_kill(priv); | ||
771 | } | ||
772 | if (!(flags & CT_CARD_DISABLED)) | ||
773 | iwl_tt_exit_ct_kill(priv); | ||
774 | |||
775 | if (flags & HW_CARD_DISABLED) | ||
776 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
777 | else | ||
778 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
779 | |||
780 | |||
781 | if (!(flags & RXON_CARD_DISABLED)) | ||
782 | iwl_scan_cancel(priv); | ||
783 | |||
784 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | ||
785 | test_bit(STATUS_RF_KILL_HW, &priv->status))) | ||
786 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | ||
787 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | ||
788 | else | ||
789 | wake_up_interruptible(&priv->wait_command_queue); | ||
790 | } | ||
791 | |||
792 | static void iwl_bg_tx_flush(struct work_struct *work) | 661 | static void iwl_bg_tx_flush(struct work_struct *work) |
793 | { | 662 | { |
794 | struct iwl_priv *priv = | 663 | struct iwl_priv *priv = |
@@ -808,51 +677,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
808 | } | 677 | } |
809 | 678 | ||
810 | /** | 679 | /** |
811 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks | ||
812 | * | ||
813 | * Setup the RX handlers for each of the reply types sent from the uCode | ||
814 | * to the host. | ||
815 | * | ||
816 | * This function chains into the hardware specific files for them to setup | ||
817 | * any hardware specific handlers as well. | ||
818 | */ | ||
819 | static void iwl_setup_rx_handlers(struct iwl_priv *priv) | ||
820 | { | ||
821 | priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; | ||
822 | priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; | ||
823 | priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; | ||
824 | priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = | ||
825 | iwl_rx_spectrum_measure_notif; | ||
826 | priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; | ||
827 | priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = | ||
828 | iwl_rx_pm_debug_statistics_notif; | ||
829 | priv->rx_handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; | ||
830 | |||
831 | /* | ||
832 | * The same handler is used for both the REPLY to a discrete | ||
833 | * statistics request from the host as well as for the periodic | ||
834 | * statistics notifications (after received beacons) from the uCode. | ||
835 | */ | ||
836 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; | ||
837 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; | ||
838 | |||
839 | iwl_setup_rx_scan_handlers(priv); | ||
840 | |||
841 | /* status change handler */ | ||
842 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; | ||
843 | |||
844 | priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = | ||
845 | iwl_rx_missed_beacon_notif; | ||
846 | /* Rx handlers */ | ||
847 | priv->rx_handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy; | ||
848 | priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx; | ||
849 | /* block ack */ | ||
850 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba; | ||
851 | /* Set up hardware specific Rx handlers */ | ||
852 | priv->cfg->ops->lib->rx_handler_setup(priv); | ||
853 | } | ||
854 | |||
855 | /** | ||
856 | * iwl_rx_handle - Main entry function for receiving responses from uCode | 680 | * iwl_rx_handle - Main entry function for receiving responses from uCode |
857 | * | 681 | * |
858 | * Uses the priv->rx_handlers callback function array to invoke | 682 | * Uses the priv->rx_handlers callback function array to invoke |
@@ -3913,6 +3737,8 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3913 | priv->force_reset[IWL_FW_RESET].reset_duration = | 3737 | priv->force_reset[IWL_FW_RESET].reset_duration = |
3914 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; | 3738 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; |
3915 | 3739 | ||
3740 | priv->rx_statistics_jiffies = jiffies; | ||
3741 | |||
3916 | /* Choose which receivers/antennas to use */ | 3742 | /* Choose which receivers/antennas to use */ |
3917 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 3743 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
3918 | priv->cfg->ops->hcmd->set_rxon_chain(priv, | 3744 | priv->cfg->ops->hcmd->set_rxon_chain(priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index b5a169be48e2..20f8e4188994 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -190,10 +190,7 @@ void iwlagn_rx_replenish_now(struct iwl_priv *priv); | |||
190 | void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 190 | void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
191 | int iwlagn_rxq_stop(struct iwl_priv *priv); | 191 | int iwlagn_rxq_stop(struct iwl_priv *priv); |
192 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | 192 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); |
193 | void iwlagn_rx_reply_rx(struct iwl_priv *priv, | 193 | void iwl_setup_rx_handlers(struct iwl_priv *priv); |
194 | struct iwl_rx_mem_buffer *rxb); | ||
195 | void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, | ||
196 | struct iwl_rx_mem_buffer *rxb); | ||
197 | 194 | ||
198 | /* tx */ | 195 | /* tx */ |
199 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 196 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
@@ -243,14 +240,6 @@ static inline bool iwl_is_tx_success(u32 status) | |||
243 | 240 | ||
244 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); | 241 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); |
245 | 242 | ||
246 | /* rx */ | ||
247 | void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | ||
248 | struct iwl_rx_mem_buffer *rxb); | ||
249 | void iwl_rx_statistics(struct iwl_priv *priv, | ||
250 | struct iwl_rx_mem_buffer *rxb); | ||
251 | void iwl_reply_statistics(struct iwl_priv *priv, | ||
252 | struct iwl_rx_mem_buffer *rxb); | ||
253 | |||
254 | /* scan */ | 243 | /* scan */ |
255 | int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); | 244 | int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); |
256 | void iwlagn_post_scan(struct iwl_priv *priv); | 245 | void iwlagn_post_scan(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4bd342060254..6c30fa652e27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -869,33 +869,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | |||
869 | } | 869 | } |
870 | } | 870 | } |
871 | 871 | ||
872 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | ||
873 | { | ||
874 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
875 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | ||
876 | /* | ||
877 | * MULTI-FIXME | ||
878 | * See iwl_mac_channel_switch. | ||
879 | */ | ||
880 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
881 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; | ||
882 | |||
883 | if (priv->switch_rxon.switch_in_progress) { | ||
884 | if (!le32_to_cpu(csa->status) && | ||
885 | (csa->channel == priv->switch_rxon.channel)) { | ||
886 | rxon->channel = csa->channel; | ||
887 | ctx->staging.channel = csa->channel; | ||
888 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", | ||
889 | le16_to_cpu(csa->channel)); | ||
890 | iwl_chswitch_done(priv, true); | ||
891 | } else { | ||
892 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | ||
893 | le16_to_cpu(csa->channel)); | ||
894 | iwl_chswitch_done(priv, false); | ||
895 | } | ||
896 | } | ||
897 | } | ||
898 | |||
899 | #ifdef CONFIG_IWLWIFI_DEBUG | 872 | #ifdef CONFIG_IWLWIFI_DEBUG |
900 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, | 873 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, |
901 | struct iwl_rxon_context *ctx) | 874 | struct iwl_rxon_context *ctx) |
@@ -1245,42 +1218,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | |||
1245 | &statistics_cmd); | 1218 | &statistics_cmd); |
1246 | } | 1219 | } |
1247 | 1220 | ||
1248 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | ||
1249 | struct iwl_rx_mem_buffer *rxb) | ||
1250 | { | ||
1251 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1252 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1253 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); | ||
1254 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | ||
1255 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | ||
1256 | #endif | ||
1257 | } | ||
1258 | |||
1259 | void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | ||
1260 | struct iwl_rx_mem_buffer *rxb) | ||
1261 | { | ||
1262 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1263 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
1264 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | ||
1265 | "notification for %s:\n", len, | ||
1266 | get_cmd_string(pkt->hdr.cmd)); | ||
1267 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); | ||
1268 | } | ||
1269 | |||
1270 | void iwl_rx_reply_error(struct iwl_priv *priv, | ||
1271 | struct iwl_rx_mem_buffer *rxb) | ||
1272 | { | ||
1273 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1274 | |||
1275 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | ||
1276 | "seq 0x%04X ser 0x%08X\n", | ||
1277 | le32_to_cpu(pkt->u.err_resp.error_type), | ||
1278 | get_cmd_string(pkt->u.err_resp.cmd_id), | ||
1279 | pkt->u.err_resp.cmd_id, | ||
1280 | le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), | ||
1281 | le32_to_cpu(pkt->u.err_resp.error_info)); | ||
1282 | } | ||
1283 | |||
1284 | void iwl_clear_isr_stats(struct iwl_priv *priv) | 1221 | void iwl_clear_isr_stats(struct iwl_priv *priv) |
1285 | { | 1222 | { |
1286 | memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); | 1223 | memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d47f3a87fce4..af47750f8985 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -441,10 +441,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | |||
441 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | 441 | void iwl_connection_init_rx_config(struct iwl_priv *priv, |
442 | struct iwl_rxon_context *ctx); | 442 | struct iwl_rxon_context *ctx); |
443 | void iwl_set_rate(struct iwl_priv *priv); | 443 | void iwl_set_rate(struct iwl_priv *priv); |
444 | int iwl_set_decrypted_flag(struct iwl_priv *priv, | ||
445 | struct ieee80211_hdr *hdr, | ||
446 | u32 decrypt_res, | ||
447 | struct ieee80211_rx_status *stats); | ||
448 | void iwl_irq_handle_error(struct iwl_priv *priv); | 444 | void iwl_irq_handle_error(struct iwl_priv *priv); |
449 | int iwl_mac_add_interface(struct ieee80211_hw *hw, | 445 | int iwl_mac_add_interface(struct ieee80211_hw *hw, |
450 | struct ieee80211_vif *vif); | 446 | struct ieee80211_vif *vif); |
@@ -493,15 +489,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, | |||
493 | { | 489 | { |
494 | } | 490 | } |
495 | #endif | 491 | #endif |
496 | /***************************************************** | ||
497 | * RX handlers. | ||
498 | * **************************************************/ | ||
499 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | ||
500 | struct iwl_rx_mem_buffer *rxb); | ||
501 | void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | ||
502 | struct iwl_rx_mem_buffer *rxb); | ||
503 | void iwl_rx_reply_error(struct iwl_priv *priv, | ||
504 | struct iwl_rx_mem_buffer *rxb); | ||
505 | 492 | ||
506 | /***************************************************** | 493 | /***************************************************** |
507 | * RX | 494 | * RX |
@@ -513,11 +500,8 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | |||
513 | struct iwl_rx_queue *q); | 500 | struct iwl_rx_queue *q); |
514 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); | 501 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); |
515 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | 502 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); |
516 | /* Handlers */ | 503 | |
517 | void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, | ||
518 | struct iwl_rx_mem_buffer *rxb); | ||
519 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); | 504 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); |
520 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | ||
521 | 505 | ||
522 | /* TX helpers */ | 506 | /* TX helpers */ |
523 | 507 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 58165c769cf1..6a41deba6863 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1261,8 +1261,8 @@ struct iwl_priv { | |||
1261 | /* track IBSS manager (last beacon) status */ | 1261 | /* track IBSS manager (last beacon) status */ |
1262 | u32 ibss_manager; | 1262 | u32 ibss_manager; |
1263 | 1263 | ||
1264 | /* storing the jiffies when the plcp error rate is received */ | 1264 | /* jiffies when last recovery from statistics was performed */ |
1265 | unsigned long plcp_jiffies; | 1265 | unsigned long rx_statistics_jiffies; |
1266 | 1266 | ||
1267 | /* force reset */ | 1267 | /* force reset */ |
1268 | struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; | 1268 | struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 566e2d979ce3..6f9a2fa04763 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/sched.h> | ||
32 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
33 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
34 | #include "iwl-eeprom.h" | 35 | #include "iwl-eeprom.h" |
@@ -38,7 +39,14 @@ | |||
38 | #include "iwl-io.h" | 39 | #include "iwl-io.h" |
39 | #include "iwl-helpers.h" | 40 | #include "iwl-helpers.h" |
40 | #include "iwl-agn-calib.h" | 41 | #include "iwl-agn-calib.h" |
41 | /************************** RX-FUNCTIONS ****************************/ | 42 | #include "iwl-agn.h" |
43 | |||
44 | /****************************************************************************** | ||
45 | * | ||
46 | * RX path functions | ||
47 | * | ||
48 | ******************************************************************************/ | ||
49 | |||
42 | /* | 50 | /* |
43 | * Rx theory of operation | 51 | * Rx theory of operation |
44 | * | 52 | * |
@@ -211,7 +219,104 @@ err_bd: | |||
211 | return -ENOMEM; | 219 | return -ENOMEM; |
212 | } | 220 | } |
213 | 221 | ||
214 | void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, | 222 | /****************************************************************************** |
223 | * | ||
224 | * Generic RX handler implementations | ||
225 | * | ||
226 | ******************************************************************************/ | ||
227 | |||
228 | static void iwl_rx_reply_alive(struct iwl_priv *priv, | ||
229 | struct iwl_rx_mem_buffer *rxb) | ||
230 | { | ||
231 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
232 | struct iwl_alive_resp *palive; | ||
233 | struct delayed_work *pwork; | ||
234 | |||
235 | palive = &pkt->u.alive_frame; | ||
236 | |||
237 | IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | ||
238 | "0x%01X 0x%01X\n", | ||
239 | palive->is_valid, palive->ver_type, | ||
240 | palive->ver_subtype); | ||
241 | |||
242 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) { | ||
243 | IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); | ||
244 | memcpy(&priv->card_alive_init, | ||
245 | &pkt->u.alive_frame, | ||
246 | sizeof(struct iwl_init_alive_resp)); | ||
247 | pwork = &priv->init_alive_start; | ||
248 | } else { | ||
249 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||
250 | memcpy(&priv->card_alive, &pkt->u.alive_frame, | ||
251 | sizeof(struct iwl_alive_resp)); | ||
252 | pwork = &priv->alive_start; | ||
253 | } | ||
254 | |||
255 | /* We delay the ALIVE response by 5ms to | ||
256 | * give the HW RF Kill time to activate... */ | ||
257 | if (palive->is_valid == UCODE_VALID_OK) | ||
258 | queue_delayed_work(priv->workqueue, pwork, | ||
259 | msecs_to_jiffies(5)); | ||
260 | else { | ||
261 | IWL_WARN(priv, "%s uCode did not respond OK.\n", | ||
262 | (palive->ver_subtype == INITIALIZE_SUBTYPE) ? | ||
263 | "init" : "runtime"); | ||
264 | /* | ||
265 | * If fail to load init uCode, | ||
266 | * let's try to load the init uCode again. | ||
267 | * We should not get into this situation, but if it | ||
268 | * does happen, we should not move on and loading "runtime" | ||
269 | * without proper calibrate the device. | ||
270 | */ | ||
271 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) | ||
272 | priv->ucode_type = UCODE_NONE; | ||
273 | queue_work(priv->workqueue, &priv->restart); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | static void iwl_rx_reply_error(struct iwl_priv *priv, | ||
278 | struct iwl_rx_mem_buffer *rxb) | ||
279 | { | ||
280 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
281 | |||
282 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | ||
283 | "seq 0x%04X ser 0x%08X\n", | ||
284 | le32_to_cpu(pkt->u.err_resp.error_type), | ||
285 | get_cmd_string(pkt->u.err_resp.cmd_id), | ||
286 | pkt->u.err_resp.cmd_id, | ||
287 | le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), | ||
288 | le32_to_cpu(pkt->u.err_resp.error_info)); | ||
289 | } | ||
290 | |||
291 | static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | ||
292 | { | ||
293 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
294 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | ||
295 | /* | ||
296 | * MULTI-FIXME | ||
297 | * See iwl_mac_channel_switch. | ||
298 | */ | ||
299 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
300 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; | ||
301 | |||
302 | if (priv->switch_rxon.switch_in_progress) { | ||
303 | if (!le32_to_cpu(csa->status) && | ||
304 | (csa->channel == priv->switch_rxon.channel)) { | ||
305 | rxon->channel = csa->channel; | ||
306 | ctx->staging.channel = csa->channel; | ||
307 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", | ||
308 | le16_to_cpu(csa->channel)); | ||
309 | iwl_chswitch_done(priv, true); | ||
310 | } else { | ||
311 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | ||
312 | le16_to_cpu(csa->channel)); | ||
313 | iwl_chswitch_done(priv, false); | ||
314 | } | ||
315 | } | ||
316 | } | ||
317 | |||
318 | |||
319 | static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, | ||
215 | struct iwl_rx_mem_buffer *rxb) | 320 | struct iwl_rx_mem_buffer *rxb) |
216 | { | 321 | { |
217 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 322 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
@@ -227,6 +332,52 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
227 | priv->measurement_status |= MEASUREMENT_READY; | 332 | priv->measurement_status |= MEASUREMENT_READY; |
228 | } | 333 | } |
229 | 334 | ||
335 | static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | ||
336 | struct iwl_rx_mem_buffer *rxb) | ||
337 | { | ||
338 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
339 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
340 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); | ||
341 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | ||
342 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | ||
343 | #endif | ||
344 | } | ||
345 | |||
346 | static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | ||
347 | struct iwl_rx_mem_buffer *rxb) | ||
348 | { | ||
349 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
350 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
351 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | ||
352 | "notification for %s:\n", len, | ||
353 | get_cmd_string(pkt->hdr.cmd)); | ||
354 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); | ||
355 | } | ||
356 | |||
357 | static void iwl_rx_beacon_notif(struct iwl_priv *priv, | ||
358 | struct iwl_rx_mem_buffer *rxb) | ||
359 | { | ||
360 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
361 | struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; | ||
362 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
363 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); | ||
364 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | ||
365 | |||
366 | IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " | ||
367 | "tsf:0x%.8x%.8x rate:%d\n", | ||
368 | status & TX_STATUS_MSK, | ||
369 | beacon->beacon_notify_hdr.failure_frame, | ||
370 | le32_to_cpu(beacon->ibss_mgr_status), | ||
371 | le32_to_cpu(beacon->high_tsf), | ||
372 | le32_to_cpu(beacon->low_tsf), rate); | ||
373 | #endif | ||
374 | |||
375 | priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); | ||
376 | |||
377 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
378 | queue_work(priv->workqueue, &priv->beacon_update); | ||
379 | } | ||
380 | |||
230 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ | 381 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ |
231 | #define ACK_CNT_RATIO (50) | 382 | #define ACK_CNT_RATIO (50) |
232 | #define BA_TIMEOUT_CNT (5) | 383 | #define BA_TIMEOUT_CNT (5) |
@@ -298,92 +449,72 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt | |||
298 | * When the plcp error is exceeding the thresholds, reset the radio | 449 | * When the plcp error is exceeding the thresholds, reset the radio |
299 | * to improve the throughput. | 450 | * to improve the throughput. |
300 | */ | 451 | */ |
301 | static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) | 452 | static bool iwl_good_plcp_health(struct iwl_priv *priv, |
453 | struct iwl_rx_packet *pkt, unsigned int msecs) | ||
302 | { | 454 | { |
303 | bool rc = true; | 455 | int delta; |
304 | int combined_plcp_delta; | 456 | int threshold = priv->cfg->base_params->plcp_delta_threshold; |
305 | unsigned int plcp_msec; | ||
306 | unsigned long plcp_received_jiffies; | ||
307 | 457 | ||
308 | if (priv->cfg->base_params->plcp_delta_threshold == | 458 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { |
309 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | ||
310 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | 459 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); |
311 | return rc; | 460 | return true; |
312 | } | 461 | } |
313 | 462 | ||
314 | /* | 463 | if (iwl_bt_statistics(priv)) { |
315 | * check for plcp_err and trigger radio reset if it exceeds | 464 | struct statistics_rx_bt *cur, *old; |
316 | * the plcp error threshold plcp_delta. | ||
317 | */ | ||
318 | plcp_received_jiffies = jiffies; | ||
319 | plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - | ||
320 | (long) priv->plcp_jiffies); | ||
321 | priv->plcp_jiffies = plcp_received_jiffies; | ||
322 | /* | ||
323 | * check to make sure plcp_msec is not 0 to prevent division | ||
324 | * by zero. | ||
325 | */ | ||
326 | if (plcp_msec) { | ||
327 | struct statistics_rx_phy *ofdm; | ||
328 | struct statistics_rx_ht_phy *ofdm_ht; | ||
329 | |||
330 | if (iwl_bt_statistics(priv)) { | ||
331 | ofdm = &pkt->u.stats_bt.rx.ofdm; | ||
332 | ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; | ||
333 | combined_plcp_delta = | ||
334 | (le32_to_cpu(ofdm->plcp_err) - | ||
335 | le32_to_cpu(priv->_agn.statistics_bt. | ||
336 | rx.ofdm.plcp_err)) + | ||
337 | (le32_to_cpu(ofdm_ht->plcp_err) - | ||
338 | le32_to_cpu(priv->_agn.statistics_bt. | ||
339 | rx.ofdm_ht.plcp_err)); | ||
340 | } else { | ||
341 | ofdm = &pkt->u.stats.rx.ofdm; | ||
342 | ofdm_ht = &pkt->u.stats.rx.ofdm_ht; | ||
343 | combined_plcp_delta = | ||
344 | (le32_to_cpu(ofdm->plcp_err) - | ||
345 | le32_to_cpu(priv->_agn.statistics. | ||
346 | rx.ofdm.plcp_err)) + | ||
347 | (le32_to_cpu(ofdm_ht->plcp_err) - | ||
348 | le32_to_cpu(priv->_agn.statistics. | ||
349 | rx.ofdm_ht.plcp_err)); | ||
350 | } | ||
351 | 465 | ||
352 | if ((combined_plcp_delta > 0) && | 466 | cur = &pkt->u.stats_bt.rx; |
353 | ((combined_plcp_delta * 100) / plcp_msec) > | 467 | old = &priv->_agn.statistics_bt.rx; |
354 | priv->cfg->base_params->plcp_delta_threshold) { | 468 | |
355 | /* | 469 | delta = le32_to_cpu(cur->ofdm.plcp_err) - |
356 | * if plcp_err exceed the threshold, | 470 | le32_to_cpu(old->ofdm.plcp_err) + |
357 | * the following data is printed in csv format: | 471 | le32_to_cpu(cur->ofdm_ht.plcp_err) - |
358 | * Text: plcp_err exceeded %d, | 472 | le32_to_cpu(old->ofdm_ht.plcp_err); |
359 | * Received ofdm.plcp_err, | 473 | } else { |
360 | * Current ofdm.plcp_err, | 474 | struct statistics_rx *cur, *old; |
361 | * Received ofdm_ht.plcp_err, | 475 | |
362 | * Current ofdm_ht.plcp_err, | 476 | cur = &pkt->u.stats.rx; |
363 | * combined_plcp_delta, | 477 | old = &priv->_agn.statistics.rx; |
364 | * plcp_msec | 478 | |
365 | */ | 479 | delta = le32_to_cpu(cur->ofdm.plcp_err) - |
366 | IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | 480 | le32_to_cpu(old->ofdm.plcp_err) + |
367 | "%u, %u, %u, %u, %d, %u mSecs\n", | 481 | le32_to_cpu(cur->ofdm_ht.plcp_err) - |
368 | priv->cfg->base_params->plcp_delta_threshold, | 482 | le32_to_cpu(old->ofdm_ht.plcp_err); |
369 | le32_to_cpu(ofdm->plcp_err), | ||
370 | le32_to_cpu(ofdm->plcp_err), | ||
371 | le32_to_cpu(ofdm_ht->plcp_err), | ||
372 | le32_to_cpu(ofdm_ht->plcp_err), | ||
373 | combined_plcp_delta, plcp_msec); | ||
374 | |||
375 | rc = false; | ||
376 | } | ||
377 | } | 483 | } |
378 | return rc; | 484 | |
485 | /* Can be negative if firmware reseted statistics */ | ||
486 | if (delta <= 0) | ||
487 | return true; | ||
488 | |||
489 | if ((delta * 100 / msecs) > threshold) { | ||
490 | IWL_DEBUG_RADIO(priv, | ||
491 | "plcp health threshold %u delta %d msecs %u\n", | ||
492 | threshold, delta, msecs); | ||
493 | return false; | ||
494 | } | ||
495 | |||
496 | return true; | ||
379 | } | 497 | } |
380 | 498 | ||
381 | static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) | 499 | static void iwl_recover_from_statistics(struct iwl_priv *priv, |
500 | struct iwl_rx_packet *pkt) | ||
382 | { | 501 | { |
383 | const struct iwl_mod_params *mod_params = priv->cfg->mod_params; | 502 | const struct iwl_mod_params *mod_params = priv->cfg->mod_params; |
503 | unsigned int msecs; | ||
504 | unsigned long stamp; | ||
384 | 505 | ||
385 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | 506 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
386 | !iwl_is_any_associated(priv)) | 507 | return; |
508 | |||
509 | stamp = jiffies; | ||
510 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); | ||
511 | |||
512 | /* Only gather statistics and update time stamp when not associated */ | ||
513 | if (!iwl_is_any_associated(priv)) | ||
514 | goto out; | ||
515 | |||
516 | /* Do not check/recover when do not have enough statistics data */ | ||
517 | if (msecs < 99) | ||
387 | return; | 518 | return; |
388 | 519 | ||
389 | if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { | 520 | if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { |
@@ -392,8 +523,18 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_pac | |||
392 | return; | 523 | return; |
393 | } | 524 | } |
394 | 525 | ||
395 | if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt)) | 526 | if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs)) |
396 | iwl_force_reset(priv, IWL_RF_RESET, false); | 527 | iwl_force_reset(priv, IWL_RF_RESET, false); |
528 | |||
529 | out: | ||
530 | if (iwl_bt_statistics(priv)) | ||
531 | memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, | ||
532 | sizeof(priv->_agn.statistics_bt)); | ||
533 | else | ||
534 | memcpy(&priv->_agn.statistics, &pkt->u.stats, | ||
535 | sizeof(priv->_agn.statistics)); | ||
536 | |||
537 | priv->rx_statistics_jiffies = stamp; | ||
397 | } | 538 | } |
398 | 539 | ||
399 | /* Calculate noise level, based on measurements during network silence just | 540 | /* Calculate noise level, based on measurements during network silence just |
@@ -442,7 +583,6 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) | |||
442 | last_rx_noise); | 583 | last_rx_noise); |
443 | } | 584 | } |
444 | 585 | ||
445 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
446 | /* | 586 | /* |
447 | * based on the assumption of all statistics counter are in DWORD | 587 | * based on the assumption of all statistics counter are in DWORD |
448 | * FIXME: This function is for debugging, do not deal with | 588 | * FIXME: This function is for debugging, do not deal with |
@@ -451,6 +591,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) | |||
451 | static void iwl_accumulative_statistics(struct iwl_priv *priv, | 591 | static void iwl_accumulative_statistics(struct iwl_priv *priv, |
452 | __le32 *stats) | 592 | __le32 *stats) |
453 | { | 593 | { |
594 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
454 | int i, size; | 595 | int i, size; |
455 | __le32 *prev_stats; | 596 | __le32 *prev_stats; |
456 | u32 *accum_stats; | 597 | u32 *accum_stats; |
@@ -498,14 +639,13 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, | |||
498 | accum_tx->tx_power.ant_a = tx->tx_power.ant_a; | 639 | accum_tx->tx_power.ant_a = tx->tx_power.ant_a; |
499 | accum_tx->tx_power.ant_b = tx->tx_power.ant_b; | 640 | accum_tx->tx_power.ant_b = tx->tx_power.ant_b; |
500 | accum_tx->tx_power.ant_c = tx->tx_power.ant_c; | 641 | accum_tx->tx_power.ant_c = tx->tx_power.ant_c; |
501 | } | ||
502 | #endif | 642 | #endif |
643 | } | ||
503 | 644 | ||
504 | #define REG_RECALIB_PERIOD (60) | 645 | static void iwl_rx_statistics(struct iwl_priv *priv, |
505 | |||
506 | void iwl_rx_statistics(struct iwl_priv *priv, | ||
507 | struct iwl_rx_mem_buffer *rxb) | 646 | struct iwl_rx_mem_buffer *rxb) |
508 | { | 647 | { |
648 | const int reg_recalib_period = 60; | ||
509 | int change; | 649 | int change; |
510 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 650 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
511 | 651 | ||
@@ -522,10 +662,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
522 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | 662 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != |
523 | (pkt->u.stats_bt.flag & | 663 | (pkt->u.stats_bt.flag & |
524 | STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | 664 | STATISTICS_REPLY_FLG_HT40_MODE_MSK))); |
525 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
526 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); | ||
527 | #endif | ||
528 | 665 | ||
666 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); | ||
529 | } else { | 667 | } else { |
530 | IWL_DEBUG_RX(priv, | 668 | IWL_DEBUG_RX(priv, |
531 | "Statistics notification received (%d vs %d).\n", | 669 | "Statistics notification received (%d vs %d).\n", |
@@ -539,29 +677,20 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
539 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | 677 | STATISTICS_REPLY_FLG_HT40_MODE_MSK) != |
540 | (pkt->u.stats.flag & | 678 | (pkt->u.stats.flag & |
541 | STATISTICS_REPLY_FLG_HT40_MODE_MSK))); | 679 | STATISTICS_REPLY_FLG_HT40_MODE_MSK))); |
542 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
543 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | ||
544 | #endif | ||
545 | 680 | ||
681 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | ||
546 | } | 682 | } |
547 | 683 | ||
548 | iwl_recover_from_statistics(priv, pkt); | 684 | iwl_recover_from_statistics(priv, pkt); |
549 | 685 | ||
550 | if (iwl_bt_statistics(priv)) | ||
551 | memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, | ||
552 | sizeof(priv->_agn.statistics_bt)); | ||
553 | else | ||
554 | memcpy(&priv->_agn.statistics, &pkt->u.stats, | ||
555 | sizeof(priv->_agn.statistics)); | ||
556 | |||
557 | set_bit(STATUS_STATISTICS, &priv->status); | 686 | set_bit(STATUS_STATISTICS, &priv->status); |
558 | 687 | ||
559 | /* Reschedule the statistics timer to occur in | 688 | /* Reschedule the statistics timer to occur in |
560 | * REG_RECALIB_PERIOD seconds to ensure we get a | 689 | * reg_recalib_period seconds to ensure we get a |
561 | * thermal update even if the uCode doesn't give | 690 | * thermal update even if the uCode doesn't give |
562 | * us one */ | 691 | * us one */ |
563 | mod_timer(&priv->statistics_periodic, jiffies + | 692 | mod_timer(&priv->statistics_periodic, jiffies + |
564 | msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); | 693 | msecs_to_jiffies(reg_recalib_period * 1000)); |
565 | 694 | ||
566 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && | 695 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && |
567 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | 696 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { |
@@ -572,8 +701,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
572 | priv->cfg->ops->lib->temp_ops.temperature(priv); | 701 | priv->cfg->ops->lib->temp_ops.temperature(priv); |
573 | } | 702 | } |
574 | 703 | ||
575 | void iwl_reply_statistics(struct iwl_priv *priv, | 704 | static void iwl_rx_reply_statistics(struct iwl_priv *priv, |
576 | struct iwl_rx_mem_buffer *rxb) | 705 | struct iwl_rx_mem_buffer *rxb) |
577 | { | 706 | { |
578 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 707 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
579 | 708 | ||
@@ -597,8 +726,61 @@ void iwl_reply_statistics(struct iwl_priv *priv, | |||
597 | iwl_rx_statistics(priv, rxb); | 726 | iwl_rx_statistics(priv, rxb); |
598 | } | 727 | } |
599 | 728 | ||
600 | void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | 729 | /* Handle notification from uCode that card's power state is changing |
601 | struct iwl_rx_mem_buffer *rxb) | 730 | * due to software, hardware, or critical temperature RFKILL */ |
731 | static void iwl_rx_card_state_notif(struct iwl_priv *priv, | ||
732 | struct iwl_rx_mem_buffer *rxb) | ||
733 | { | ||
734 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
735 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | ||
736 | unsigned long status = priv->status; | ||
737 | |||
738 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", | ||
739 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | ||
740 | (flags & SW_CARD_DISABLED) ? "Kill" : "On", | ||
741 | (flags & CT_CARD_DISABLED) ? | ||
742 | "Reached" : "Not reached"); | ||
743 | |||
744 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | | ||
745 | CT_CARD_DISABLED)) { | ||
746 | |||
747 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
748 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
749 | |||
750 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, | ||
751 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | ||
752 | |||
753 | if (!(flags & RXON_CARD_DISABLED)) { | ||
754 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||
755 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
756 | iwl_write_direct32(priv, HBUS_TARG_MBX_C, | ||
757 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | ||
758 | } | ||
759 | if (flags & CT_CARD_DISABLED) | ||
760 | iwl_tt_enter_ct_kill(priv); | ||
761 | } | ||
762 | if (!(flags & CT_CARD_DISABLED)) | ||
763 | iwl_tt_exit_ct_kill(priv); | ||
764 | |||
765 | if (flags & HW_CARD_DISABLED) | ||
766 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
767 | else | ||
768 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
769 | |||
770 | |||
771 | if (!(flags & RXON_CARD_DISABLED)) | ||
772 | iwl_scan_cancel(priv); | ||
773 | |||
774 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | ||
775 | test_bit(STATUS_RF_KILL_HW, &priv->status))) | ||
776 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | ||
777 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | ||
778 | else | ||
779 | wake_up_interruptible(&priv->wait_command_queue); | ||
780 | } | ||
781 | |||
782 | static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | ||
783 | struct iwl_rx_mem_buffer *rxb) | ||
602 | 784 | ||
603 | { | 785 | { |
604 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 786 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
@@ -618,13 +800,25 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
618 | } | 800 | } |
619 | } | 801 | } |
620 | 802 | ||
803 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | ||
804 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | ||
805 | static void iwl_rx_reply_rx_phy(struct iwl_priv *priv, | ||
806 | struct iwl_rx_mem_buffer *rxb) | ||
807 | { | ||
808 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
809 | |||
810 | priv->_agn.last_phy_res_valid = true; | ||
811 | memcpy(&priv->_agn.last_phy_res, pkt->u.raw, | ||
812 | sizeof(struct iwl_rx_phy_res)); | ||
813 | } | ||
814 | |||
621 | /* | 815 | /* |
622 | * returns non-zero if packet should be dropped | 816 | * returns non-zero if packet should be dropped |
623 | */ | 817 | */ |
624 | int iwl_set_decrypted_flag(struct iwl_priv *priv, | 818 | static int iwl_set_decrypted_flag(struct iwl_priv *priv, |
625 | struct ieee80211_hdr *hdr, | 819 | struct ieee80211_hdr *hdr, |
626 | u32 decrypt_res, | 820 | u32 decrypt_res, |
627 | struct ieee80211_rx_status *stats) | 821 | struct ieee80211_rx_status *stats) |
628 | { | 822 | { |
629 | u16 fc = le16_to_cpu(hdr->frame_control); | 823 | u16 fc = le16_to_cpu(hdr->frame_control); |
630 | 824 | ||
@@ -669,3 +863,264 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, | |||
669 | } | 863 | } |
670 | return 0; | 864 | return 0; |
671 | } | 865 | } |
866 | |||
867 | static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | ||
868 | struct ieee80211_hdr *hdr, | ||
869 | u16 len, | ||
870 | u32 ampdu_status, | ||
871 | struct iwl_rx_mem_buffer *rxb, | ||
872 | struct ieee80211_rx_status *stats) | ||
873 | { | ||
874 | struct sk_buff *skb; | ||
875 | __le16 fc = hdr->frame_control; | ||
876 | |||
877 | /* We only process data packets if the interface is open */ | ||
878 | if (unlikely(!priv->is_open)) { | ||
879 | IWL_DEBUG_DROP_LIMIT(priv, | ||
880 | "Dropping packet while interface is not open.\n"); | ||
881 | return; | ||
882 | } | ||
883 | |||
884 | /* In case of HW accelerated crypto and bad decryption, drop */ | ||
885 | if (!priv->cfg->mod_params->sw_crypto && | ||
886 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | ||
887 | return; | ||
888 | |||
889 | skb = dev_alloc_skb(128); | ||
890 | if (!skb) { | ||
891 | IWL_ERR(priv, "dev_alloc_skb failed\n"); | ||
892 | return; | ||
893 | } | ||
894 | |||
895 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | ||
896 | |||
897 | iwl_update_stats(priv, false, fc, len); | ||
898 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | ||
899 | |||
900 | ieee80211_rx(priv->hw, skb); | ||
901 | priv->alloc_rxb_page--; | ||
902 | rxb->page = NULL; | ||
903 | } | ||
904 | |||
905 | static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | ||
906 | { | ||
907 | u32 decrypt_out = 0; | ||
908 | |||
909 | if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == | ||
910 | RX_RES_STATUS_STATION_FOUND) | ||
911 | decrypt_out |= (RX_RES_STATUS_STATION_FOUND | | ||
912 | RX_RES_STATUS_NO_STATION_INFO_MISMATCH); | ||
913 | |||
914 | decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); | ||
915 | |||
916 | /* packet was not encrypted */ | ||
917 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
918 | RX_RES_STATUS_SEC_TYPE_NONE) | ||
919 | return decrypt_out; | ||
920 | |||
921 | /* packet was encrypted with unknown alg */ | ||
922 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
923 | RX_RES_STATUS_SEC_TYPE_ERR) | ||
924 | return decrypt_out; | ||
925 | |||
926 | /* decryption was not done in HW */ | ||
927 | if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != | ||
928 | RX_MPDU_RES_STATUS_DEC_DONE_MSK) | ||
929 | return decrypt_out; | ||
930 | |||
931 | switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { | ||
932 | |||
933 | case RX_RES_STATUS_SEC_TYPE_CCMP: | ||
934 | /* alg is CCM: check MIC only */ | ||
935 | if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) | ||
936 | /* Bad MIC */ | ||
937 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
938 | else | ||
939 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
940 | |||
941 | break; | ||
942 | |||
943 | case RX_RES_STATUS_SEC_TYPE_TKIP: | ||
944 | if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { | ||
945 | /* Bad TTAK */ | ||
946 | decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; | ||
947 | break; | ||
948 | } | ||
949 | /* fall through if TTAK OK */ | ||
950 | default: | ||
951 | if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) | ||
952 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
953 | else | ||
954 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
955 | break; | ||
956 | } | ||
957 | |||
958 | IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n", | ||
959 | decrypt_in, decrypt_out); | ||
960 | |||
961 | return decrypt_out; | ||
962 | } | ||
963 | |||
964 | /* Called for REPLY_RX (legacy ABG frames), or | ||
965 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | ||
966 | static void iwl_rx_reply_rx(struct iwl_priv *priv, | ||
967 | struct iwl_rx_mem_buffer *rxb) | ||
968 | { | ||
969 | struct ieee80211_hdr *header; | ||
970 | struct ieee80211_rx_status rx_status; | ||
971 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
972 | struct iwl_rx_phy_res *phy_res; | ||
973 | __le32 rx_pkt_status; | ||
974 | struct iwl_rx_mpdu_res_start *amsdu; | ||
975 | u32 len; | ||
976 | u32 ampdu_status; | ||
977 | u32 rate_n_flags; | ||
978 | |||
979 | /** | ||
980 | * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently. | ||
981 | * REPLY_RX: physical layer info is in this buffer | ||
982 | * REPLY_RX_MPDU_CMD: physical layer info was sent in separate | ||
983 | * command and cached in priv->last_phy_res | ||
984 | * | ||
985 | * Here we set up local variables depending on which command is | ||
986 | * received. | ||
987 | */ | ||
988 | if (pkt->hdr.cmd == REPLY_RX) { | ||
989 | phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; | ||
990 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) | ||
991 | + phy_res->cfg_phy_cnt); | ||
992 | |||
993 | len = le16_to_cpu(phy_res->byte_count); | ||
994 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + | ||
995 | phy_res->cfg_phy_cnt + len); | ||
996 | ampdu_status = le32_to_cpu(rx_pkt_status); | ||
997 | } else { | ||
998 | if (!priv->_agn.last_phy_res_valid) { | ||
999 | IWL_ERR(priv, "MPDU frame without cached PHY data\n"); | ||
1000 | return; | ||
1001 | } | ||
1002 | phy_res = &priv->_agn.last_phy_res; | ||
1003 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; | ||
1004 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); | ||
1005 | len = le16_to_cpu(amsdu->byte_count); | ||
1006 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); | ||
1007 | ampdu_status = iwl_translate_rx_status(priv, | ||
1008 | le32_to_cpu(rx_pkt_status)); | ||
1009 | } | ||
1010 | |||
1011 | if ((unlikely(phy_res->cfg_phy_cnt > 20))) { | ||
1012 | IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", | ||
1013 | phy_res->cfg_phy_cnt); | ||
1014 | return; | ||
1015 | } | ||
1016 | |||
1017 | if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || | ||
1018 | !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { | ||
1019 | IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", | ||
1020 | le32_to_cpu(rx_pkt_status)); | ||
1021 | return; | ||
1022 | } | ||
1023 | |||
1024 | /* This will be used in several places later */ | ||
1025 | rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); | ||
1026 | |||
1027 | /* rx_status carries information about the packet to mac80211 */ | ||
1028 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); | ||
1029 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | ||
1030 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
1031 | rx_status.freq = | ||
1032 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), | ||
1033 | rx_status.band); | ||
1034 | rx_status.rate_idx = | ||
1035 | iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); | ||
1036 | rx_status.flag = 0; | ||
1037 | |||
1038 | /* TSF isn't reliable. In order to allow smooth user experience, | ||
1039 | * this W/A doesn't propagate it to the mac80211 */ | ||
1040 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ | ||
1041 | |||
1042 | priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); | ||
1043 | |||
1044 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | ||
1045 | rx_status.signal = priv->cfg->ops->utils->calc_rssi(priv, phy_res); | ||
1046 | |||
1047 | iwl_dbg_log_rx_data_frame(priv, len, header); | ||
1048 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", | ||
1049 | rx_status.signal, (unsigned long long)rx_status.mactime); | ||
1050 | |||
1051 | /* | ||
1052 | * "antenna number" | ||
1053 | * | ||
1054 | * It seems that the antenna field in the phy flags value | ||
1055 | * is actually a bit field. This is undefined by radiotap, | ||
1056 | * it wants an actual antenna number but I always get "7" | ||
1057 | * for most legacy frames I receive indicating that the | ||
1058 | * same frame was received on all three RX chains. | ||
1059 | * | ||
1060 | * I think this field should be removed in favor of a | ||
1061 | * new 802.11n radiotap field "RX chains" that is defined | ||
1062 | * as a bitmask. | ||
1063 | */ | ||
1064 | rx_status.antenna = | ||
1065 | (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) | ||
1066 | >> RX_RES_PHY_FLAGS_ANTENNA_POS; | ||
1067 | |||
1068 | /* set the preamble flag if appropriate */ | ||
1069 | if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) | ||
1070 | rx_status.flag |= RX_FLAG_SHORTPRE; | ||
1071 | |||
1072 | /* Set up the HT phy flags */ | ||
1073 | if (rate_n_flags & RATE_MCS_HT_MSK) | ||
1074 | rx_status.flag |= RX_FLAG_HT; | ||
1075 | if (rate_n_flags & RATE_MCS_HT40_MSK) | ||
1076 | rx_status.flag |= RX_FLAG_40MHZ; | ||
1077 | if (rate_n_flags & RATE_MCS_SGI_MSK) | ||
1078 | rx_status.flag |= RX_FLAG_SHORT_GI; | ||
1079 | |||
1080 | iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, | ||
1081 | rxb, &rx_status); | ||
1082 | } | ||
1083 | |||
1084 | /** | ||
1085 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks | ||
1086 | * | ||
1087 | * Setup the RX handlers for each of the reply types sent from the uCode | ||
1088 | * to the host. | ||
1089 | */ | ||
1090 | void iwl_setup_rx_handlers(struct iwl_priv *priv) | ||
1091 | { | ||
1092 | void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | ||
1093 | |||
1094 | handlers = priv->rx_handlers; | ||
1095 | |||
1096 | handlers[REPLY_ALIVE] = iwl_rx_reply_alive; | ||
1097 | handlers[REPLY_ERROR] = iwl_rx_reply_error; | ||
1098 | handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; | ||
1099 | handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif; | ||
1100 | handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; | ||
1101 | handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; | ||
1102 | handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; | ||
1103 | |||
1104 | /* | ||
1105 | * The same handler is used for both the REPLY to a discrete | ||
1106 | * statistics request from the host as well as for the periodic | ||
1107 | * statistics notifications (after received beacons) from the uCode. | ||
1108 | */ | ||
1109 | handlers[REPLY_STATISTICS_CMD] = iwl_rx_reply_statistics; | ||
1110 | handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; | ||
1111 | |||
1112 | iwl_setup_rx_scan_handlers(priv); | ||
1113 | |||
1114 | handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; | ||
1115 | handlers[MISSED_BEACONS_NOTIFICATION] = iwl_rx_missed_beacon_notif; | ||
1116 | |||
1117 | /* Rx handlers */ | ||
1118 | handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; | ||
1119 | handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; | ||
1120 | |||
1121 | /* block ack */ | ||
1122 | handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba; | ||
1123 | |||
1124 | /* Set up hardware specific Rx handlers */ | ||
1125 | priv->cfg->ops->lib->rx_handler_setup(priv); | ||
1126 | } | ||
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 5eac1351a021..6cb6935ee4a3 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h | |||
@@ -387,7 +387,7 @@ struct lbs_offset_value { | |||
387 | struct mrvl_ie_domain_param_set { | 387 | struct mrvl_ie_domain_param_set { |
388 | struct mrvl_ie_header header; | 388 | struct mrvl_ie_header header; |
389 | 389 | ||
390 | u8 country_code[3]; | 390 | u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; |
391 | struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS]; | 391 | struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS]; |
392 | } __packed; | 392 | } __packed; |
393 | 393 | ||
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index df5959f36d0b..36952274950e 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -1056,13 +1056,12 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) | |||
1056 | } | 1056 | } |
1057 | memset(rxq->rxd, 0, size); | 1057 | memset(rxq->rxd, 0, size); |
1058 | 1058 | ||
1059 | rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); | 1059 | rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL); |
1060 | if (rxq->buf == NULL) { | 1060 | if (rxq->buf == NULL) { |
1061 | wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n"); | 1061 | wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n"); |
1062 | pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); | 1062 | pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); |
1063 | return -ENOMEM; | 1063 | return -ENOMEM; |
1064 | } | 1064 | } |
1065 | memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf)); | ||
1066 | 1065 | ||
1067 | for (i = 0; i < MWL8K_RX_DESCS; i++) { | 1066 | for (i = 0; i < MWL8K_RX_DESCS; i++) { |
1068 | int desc_size; | 1067 | int desc_size; |
@@ -1347,13 +1346,12 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) | |||
1347 | } | 1346 | } |
1348 | memset(txq->txd, 0, size); | 1347 | memset(txq->txd, 0, size); |
1349 | 1348 | ||
1350 | txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); | 1349 | txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL); |
1351 | if (txq->skb == NULL) { | 1350 | if (txq->skb == NULL) { |
1352 | wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n"); | 1351 | wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n"); |
1353 | pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); | 1352 | pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); |
1354 | return -ENOMEM; | 1353 | return -ENOMEM; |
1355 | } | 1354 | } |
1356 | memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb)); | ||
1357 | 1355 | ||
1358 | for (i = 0; i < MWL8K_TX_DESCS; i++) { | 1356 | for (i = 0; i < MWL8K_TX_DESCS; i++) { |
1359 | struct mwl8k_tx_desc *tx_desc; | 1357 | struct mwl8k_tx_desc *tx_desc; |
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig index 25f965ffc889..0ec55b50798e 100644 --- a/drivers/net/wireless/p54/Kconfig +++ b/drivers/net/wireless/p54/Kconfig | |||
@@ -43,9 +43,8 @@ config P54_SPI | |||
43 | tristate "Prism54 SPI (stlc45xx) support" | 43 | tristate "Prism54 SPI (stlc45xx) support" |
44 | depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS | 44 | depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS |
45 | ---help--- | 45 | ---help--- |
46 | This driver is for stlc4550 or stlc4560 based wireless chips. | 46 | This driver is for stlc4550 or stlc4560 based wireless chips |
47 | This driver is experimental, untested and will probably only work on | 47 | such as Nokia's N800/N810 Portable Internet Tablet. |
48 | Nokia's N800/N810 Portable Internet Tablet. | ||
49 | 48 | ||
50 | If you choose to build a module, it'll be called p54spi. | 49 | If you choose to build a module, it'll be called p54spi. |
51 | 50 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 2725f3c4442e..329f3283697b 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -779,7 +779,7 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
779 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 779 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
780 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); | 780 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
781 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); | 781 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
782 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); | 782 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); |
783 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); | 783 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
784 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 784 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
785 | 785 | ||
@@ -795,13 +795,13 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
795 | entry_priv->desc_dma); | 795 | entry_priv->desc_dma); |
796 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 796 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
797 | 797 | ||
798 | entry_priv = rt2x00dev->bcn[1].entries[0].priv_data; | 798 | entry_priv = rt2x00dev->atim->entries[0].priv_data; |
799 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 799 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
800 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 800 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
801 | entry_priv->desc_dma); | 801 | entry_priv->desc_dma); |
802 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 802 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
803 | 803 | ||
804 | entry_priv = rt2x00dev->bcn[0].entries[0].priv_data; | 804 | entry_priv = rt2x00dev->bcn->entries[0].priv_data; |
805 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 805 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
806 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 806 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
807 | entry_priv->desc_dma); | 807 | entry_priv->desc_dma); |
@@ -1131,19 +1131,21 @@ static void rt2400pci_write_tx_desc(struct queue_entry *entry, | |||
1131 | rt2x00_desc_write(txd, 2, word); | 1131 | rt2x00_desc_write(txd, 2, word); |
1132 | 1132 | ||
1133 | rt2x00_desc_read(txd, 3, &word); | 1133 | rt2x00_desc_read(txd, 3, &word); |
1134 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); | 1134 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal); |
1135 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); | 1135 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); |
1136 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); | 1136 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); |
1137 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); | 1137 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service); |
1138 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); | 1138 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); |
1139 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); | 1139 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); |
1140 | rt2x00_desc_write(txd, 3, word); | 1140 | rt2x00_desc_write(txd, 3, word); |
1141 | 1141 | ||
1142 | rt2x00_desc_read(txd, 4, &word); | 1142 | rt2x00_desc_read(txd, 4, &word); |
1143 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, txdesc->length_low); | 1143 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, |
1144 | txdesc->u.plcp.length_low); | ||
1144 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); | 1145 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); |
1145 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); | 1146 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); |
1146 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, txdesc->length_high); | 1147 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, |
1148 | txdesc->u.plcp.length_high); | ||
1147 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); | 1149 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); |
1148 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); | 1150 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); |
1149 | rt2x00_desc_write(txd, 4, word); | 1151 | rt2x00_desc_write(txd, 4, word); |
@@ -1164,7 +1166,7 @@ static void rt2400pci_write_tx_desc(struct queue_entry *entry, | |||
1164 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1166 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1165 | rt2x00_set_field32(&word, TXD_W0_RTS, | 1167 | rt2x00_set_field32(&word, TXD_W0_RTS, |
1166 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); | 1168 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1167 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1169 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); |
1168 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1170 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1169 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1171 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1170 | rt2x00_desc_write(txd, 0, word); | 1172 | rt2x00_desc_write(txd, 0, word); |
@@ -1276,7 +1278,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, | |||
1276 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, | 1278 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, |
1277 | const enum data_queue_qid queue_idx) | 1279 | const enum data_queue_qid queue_idx) |
1278 | { | 1280 | { |
1279 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 1281 | struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
1280 | struct queue_entry_priv_pci *entry_priv; | 1282 | struct queue_entry_priv_pci *entry_priv; |
1281 | struct queue_entry *entry; | 1283 | struct queue_entry *entry; |
1282 | struct txdone_entry_desc txdesc; | 1284 | struct txdone_entry_desc txdesc; |
@@ -1315,27 +1317,25 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1315 | static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 1317 | static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
1316 | struct rt2x00_field32 irq_field) | 1318 | struct rt2x00_field32 irq_field) |
1317 | { | 1319 | { |
1318 | unsigned long flags; | ||
1319 | u32 reg; | 1320 | u32 reg; |
1320 | 1321 | ||
1321 | /* | 1322 | /* |
1322 | * Enable a single interrupt. The interrupt mask register | 1323 | * Enable a single interrupt. The interrupt mask register |
1323 | * access needs locking. | 1324 | * access needs locking. |
1324 | */ | 1325 | */ |
1325 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1326 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
1326 | 1327 | ||
1327 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1328 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); |
1328 | rt2x00_set_field32(®, irq_field, 0); | 1329 | rt2x00_set_field32(®, irq_field, 0); |
1329 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1330 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); |
1330 | 1331 | ||
1331 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1332 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
1332 | } | 1333 | } |
1333 | 1334 | ||
1334 | static void rt2400pci_txstatus_tasklet(unsigned long data) | 1335 | static void rt2400pci_txstatus_tasklet(unsigned long data) |
1335 | { | 1336 | { |
1336 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 1337 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
1337 | u32 reg; | 1338 | u32 reg; |
1338 | unsigned long flags; | ||
1339 | 1339 | ||
1340 | /* | 1340 | /* |
1341 | * Handle all tx queues. | 1341 | * Handle all tx queues. |
@@ -1347,7 +1347,7 @@ static void rt2400pci_txstatus_tasklet(unsigned long data) | |||
1347 | /* | 1347 | /* |
1348 | * Enable all TXDONE interrupts again. | 1348 | * Enable all TXDONE interrupts again. |
1349 | */ | 1349 | */ |
1350 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1350 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
1351 | 1351 | ||
1352 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1352 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); |
1353 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); | 1353 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); |
@@ -1355,7 +1355,7 @@ static void rt2400pci_txstatus_tasklet(unsigned long data) | |||
1355 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); | 1355 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); |
1356 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1356 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); |
1357 | 1357 | ||
1358 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1358 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
1359 | } | 1359 | } |
1360 | 1360 | ||
1361 | static void rt2400pci_tbtt_tasklet(unsigned long data) | 1361 | static void rt2400pci_tbtt_tasklet(unsigned long data) |
@@ -1376,7 +1376,6 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
1376 | { | 1376 | { |
1377 | struct rt2x00_dev *rt2x00dev = dev_instance; | 1377 | struct rt2x00_dev *rt2x00dev = dev_instance; |
1378 | u32 reg, mask; | 1378 | u32 reg, mask; |
1379 | unsigned long flags; | ||
1380 | 1379 | ||
1381 | /* | 1380 | /* |
1382 | * Get the interrupt sources & saved to local variable. | 1381 | * Get the interrupt sources & saved to local variable. |
@@ -1418,13 +1417,13 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
1418 | * Disable all interrupts for which a tasklet was scheduled right now, | 1417 | * Disable all interrupts for which a tasklet was scheduled right now, |
1419 | * the tasklet will reenable the appropriate interrupts. | 1418 | * the tasklet will reenable the appropriate interrupts. |
1420 | */ | 1419 | */ |
1421 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1420 | spin_lock(&rt2x00dev->irqmask_lock); |
1422 | 1421 | ||
1423 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1422 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); |
1424 | reg |= mask; | 1423 | reg |= mask; |
1425 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1424 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); |
1426 | 1425 | ||
1427 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1426 | spin_unlock(&rt2x00dev->irqmask_lock); |
1428 | 1427 | ||
1429 | 1428 | ||
1430 | 1429 | ||
@@ -1641,6 +1640,7 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1641 | */ | 1640 | */ |
1642 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1641 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1643 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 1642 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); |
1643 | __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); | ||
1644 | 1644 | ||
1645 | /* | 1645 | /* |
1646 | * Set the rssi offset. | 1646 | * Set the rssi offset. |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 3ef1fb4185c0..58277878889e 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -293,7 +293,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
293 | struct rt2x00intf_conf *conf, | 293 | struct rt2x00intf_conf *conf, |
294 | const unsigned int flags) | 294 | const unsigned int flags) |
295 | { | 295 | { |
296 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON); | 296 | struct data_queue *queue = rt2x00dev->bcn; |
297 | unsigned int bcn_preload; | 297 | unsigned int bcn_preload; |
298 | u32 reg; | 298 | u32 reg; |
299 | 299 | ||
@@ -865,7 +865,7 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
865 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 865 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
866 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); | 866 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
867 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); | 867 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
868 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); | 868 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); |
869 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); | 869 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
870 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 870 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
871 | 871 | ||
@@ -881,13 +881,13 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
881 | entry_priv->desc_dma); | 881 | entry_priv->desc_dma); |
882 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 882 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
883 | 883 | ||
884 | entry_priv = rt2x00dev->bcn[1].entries[0].priv_data; | 884 | entry_priv = rt2x00dev->atim->entries[0].priv_data; |
885 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 885 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
886 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 886 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
887 | entry_priv->desc_dma); | 887 | entry_priv->desc_dma); |
888 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 888 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
889 | 889 | ||
890 | entry_priv = rt2x00dev->bcn[0].entries[0].priv_data; | 890 | entry_priv = rt2x00dev->bcn->entries[0].priv_data; |
891 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 891 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
892 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 892 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
893 | entry_priv->desc_dma); | 893 | entry_priv->desc_dma); |
@@ -1287,10 +1287,12 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, | |||
1287 | rt2x00_desc_write(txd, 2, word); | 1287 | rt2x00_desc_write(txd, 2, word); |
1288 | 1288 | ||
1289 | rt2x00_desc_read(txd, 3, &word); | 1289 | rt2x00_desc_read(txd, 3, &word); |
1290 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); | 1290 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal); |
1291 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); | 1291 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service); |
1292 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, txdesc->length_low); | 1292 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, |
1293 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); | 1293 | txdesc->u.plcp.length_low); |
1294 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, | ||
1295 | txdesc->u.plcp.length_high); | ||
1294 | rt2x00_desc_write(txd, 3, word); | 1296 | rt2x00_desc_write(txd, 3, word); |
1295 | 1297 | ||
1296 | rt2x00_desc_read(txd, 10, &word); | 1298 | rt2x00_desc_read(txd, 10, &word); |
@@ -1315,7 +1317,7 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, | |||
1315 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1317 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1316 | (txdesc->rate_mode == RATE_MODE_OFDM)); | 1318 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1317 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1319 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1318 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1320 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); |
1319 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1321 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1320 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1322 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1321 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); | 1323 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); |
@@ -1408,7 +1410,7 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry, | |||
1408 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, | 1410 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, |
1409 | const enum data_queue_qid queue_idx) | 1411 | const enum data_queue_qid queue_idx) |
1410 | { | 1412 | { |
1411 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 1413 | struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
1412 | struct queue_entry_priv_pci *entry_priv; | 1414 | struct queue_entry_priv_pci *entry_priv; |
1413 | struct queue_entry *entry; | 1415 | struct queue_entry *entry; |
1414 | struct txdone_entry_desc txdesc; | 1416 | struct txdone_entry_desc txdesc; |
@@ -1447,27 +1449,25 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1447 | static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 1449 | static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
1448 | struct rt2x00_field32 irq_field) | 1450 | struct rt2x00_field32 irq_field) |
1449 | { | 1451 | { |
1450 | unsigned long flags; | ||
1451 | u32 reg; | 1452 | u32 reg; |
1452 | 1453 | ||
1453 | /* | 1454 | /* |
1454 | * Enable a single interrupt. The interrupt mask register | 1455 | * Enable a single interrupt. The interrupt mask register |
1455 | * access needs locking. | 1456 | * access needs locking. |
1456 | */ | 1457 | */ |
1457 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1458 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
1458 | 1459 | ||
1459 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1460 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); |
1460 | rt2x00_set_field32(®, irq_field, 0); | 1461 | rt2x00_set_field32(®, irq_field, 0); |
1461 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1462 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); |
1462 | 1463 | ||
1463 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1464 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
1464 | } | 1465 | } |
1465 | 1466 | ||
1466 | static void rt2500pci_txstatus_tasklet(unsigned long data) | 1467 | static void rt2500pci_txstatus_tasklet(unsigned long data) |
1467 | { | 1468 | { |
1468 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 1469 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
1469 | u32 reg; | 1470 | u32 reg; |
1470 | unsigned long flags; | ||
1471 | 1471 | ||
1472 | /* | 1472 | /* |
1473 | * Handle all tx queues. | 1473 | * Handle all tx queues. |
@@ -1479,7 +1479,7 @@ static void rt2500pci_txstatus_tasklet(unsigned long data) | |||
1479 | /* | 1479 | /* |
1480 | * Enable all TXDONE interrupts again. | 1480 | * Enable all TXDONE interrupts again. |
1481 | */ | 1481 | */ |
1482 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1482 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
1483 | 1483 | ||
1484 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1484 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); |
1485 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); | 1485 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); |
@@ -1487,7 +1487,7 @@ static void rt2500pci_txstatus_tasklet(unsigned long data) | |||
1487 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); | 1487 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); |
1488 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1488 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); |
1489 | 1489 | ||
1490 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1490 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | static void rt2500pci_tbtt_tasklet(unsigned long data) | 1493 | static void rt2500pci_tbtt_tasklet(unsigned long data) |
@@ -1508,7 +1508,6 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
1508 | { | 1508 | { |
1509 | struct rt2x00_dev *rt2x00dev = dev_instance; | 1509 | struct rt2x00_dev *rt2x00dev = dev_instance; |
1510 | u32 reg, mask; | 1510 | u32 reg, mask; |
1511 | unsigned long flags; | ||
1512 | 1511 | ||
1513 | /* | 1512 | /* |
1514 | * Get the interrupt sources & saved to local variable. | 1513 | * Get the interrupt sources & saved to local variable. |
@@ -1550,13 +1549,13 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
1550 | * Disable all interrupts for which a tasklet was scheduled right now, | 1549 | * Disable all interrupts for which a tasklet was scheduled right now, |
1551 | * the tasklet will reenable the appropriate interrupts. | 1550 | * the tasklet will reenable the appropriate interrupts. |
1552 | */ | 1551 | */ |
1553 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1552 | spin_lock(&rt2x00dev->irqmask_lock); |
1554 | 1553 | ||
1555 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1554 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); |
1556 | reg |= mask; | 1555 | reg |= mask; |
1557 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1556 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); |
1558 | 1557 | ||
1559 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1558 | spin_unlock(&rt2x00dev->irqmask_lock); |
1560 | 1559 | ||
1561 | return IRQ_HANDLED; | 1560 | return IRQ_HANDLED; |
1562 | } | 1561 | } |
@@ -1959,6 +1958,7 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1959 | */ | 1958 | */ |
1960 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1959 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1961 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 1960 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); |
1961 | __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); | ||
1962 | 1962 | ||
1963 | /* | 1963 | /* |
1964 | * Set the rssi offset. | 1964 | * Set the rssi offset. |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 01f385d5846c..979fe6596a2d 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1100,7 +1100,7 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry, | |||
1100 | (txdesc->rate_mode == RATE_MODE_OFDM)); | 1100 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1101 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1101 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1102 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); | 1102 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); |
1103 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1103 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); |
1104 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); | 1104 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); |
1105 | rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); | 1105 | rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); |
1106 | rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); | 1106 | rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); |
@@ -1114,10 +1114,12 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry, | |||
1114 | rt2x00_desc_write(txd, 1, word); | 1114 | rt2x00_desc_write(txd, 1, word); |
1115 | 1115 | ||
1116 | rt2x00_desc_read(txd, 2, &word); | 1116 | rt2x00_desc_read(txd, 2, &word); |
1117 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); | 1117 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); |
1118 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); | 1118 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); |
1119 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); | 1119 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, |
1120 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); | 1120 | txdesc->u.plcp.length_low); |
1121 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, | ||
1122 | txdesc->u.plcp.length_high); | ||
1121 | rt2x00_desc_write(txd, 2, word); | 1123 | rt2x00_desc_write(txd, 2, word); |
1122 | 1124 | ||
1123 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | 1125 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { |
@@ -1795,6 +1797,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1795 | __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); | 1797 | __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); |
1796 | } | 1798 | } |
1797 | __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); | 1799 | __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); |
1800 | __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); | ||
1798 | 1801 | ||
1799 | /* | 1802 | /* |
1800 | * Set the rssi offset. | 1803 | * Set the rssi offset. |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 6f4a2432c021..70b9abbdeb9e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -66,7 +66,7 @@ | |||
66 | #define RF3320 0x000b | 66 | #define RF3320 0x000b |
67 | #define RF3322 0x000c | 67 | #define RF3322 0x000c |
68 | #define RF3853 0x000d | 68 | #define RF3853 0x000d |
69 | #define RF5390 0x5390 | 69 | #define RF5390 0x5390 |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Chipset revisions. | 72 | * Chipset revisions. |
@@ -79,7 +79,7 @@ | |||
79 | #define REV_RT3071E 0x0211 | 79 | #define REV_RT3071E 0x0211 |
80 | #define REV_RT3090E 0x0211 | 80 | #define REV_RT3090E 0x0211 |
81 | #define REV_RT3390E 0x0211 | 81 | #define REV_RT3390E 0x0211 |
82 | #define REV_RT5390F 0x0502 | 82 | #define REV_RT5390F 0x0502 |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Signal information. | 85 | * Signal information. |
@@ -126,9 +126,9 @@ | |||
126 | /* | 126 | /* |
127 | * AUX_CTRL: Aux/PCI-E related configuration | 127 | * AUX_CTRL: Aux/PCI-E related configuration |
128 | */ | 128 | */ |
129 | #define AUX_CTRL 0x10c | 129 | #define AUX_CTRL 0x10c |
130 | #define AUX_CTRL_WAKE_PCIE_EN FIELD32(0x00000002) | 130 | #define AUX_CTRL_WAKE_PCIE_EN FIELD32(0x00000002) |
131 | #define AUX_CTRL_FORCE_PCIE_CLK FIELD32(0x00000400) | 131 | #define AUX_CTRL_FORCE_PCIE_CLK FIELD32(0x00000400) |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * OPT_14: Unknown register used by rt3xxx devices. | 134 | * OPT_14: Unknown register used by rt3xxx devices. |
@@ -464,7 +464,7 @@ | |||
464 | */ | 464 | */ |
465 | #define RF_CSR_CFG 0x0500 | 465 | #define RF_CSR_CFG 0x0500 |
466 | #define RF_CSR_CFG_DATA FIELD32(0x000000ff) | 466 | #define RF_CSR_CFG_DATA FIELD32(0x000000ff) |
467 | #define RF_CSR_CFG_REGNUM FIELD32(0x00003f00) | 467 | #define RF_CSR_CFG_REGNUM FIELD32(0x00003f00) |
468 | #define RF_CSR_CFG_WRITE FIELD32(0x00010000) | 468 | #define RF_CSR_CFG_WRITE FIELD32(0x00010000) |
469 | #define RF_CSR_CFG_BUSY FIELD32(0x00020000) | 469 | #define RF_CSR_CFG_BUSY FIELD32(0x00020000) |
470 | 470 | ||
@@ -1746,13 +1746,13 @@ struct mac_iveiv_entry { | |||
1746 | */ | 1746 | */ |
1747 | #define BBP4_TX_BF FIELD8(0x01) | 1747 | #define BBP4_TX_BF FIELD8(0x01) |
1748 | #define BBP4_BANDWIDTH FIELD8(0x18) | 1748 | #define BBP4_BANDWIDTH FIELD8(0x18) |
1749 | #define BBP4_MAC_IF_CTRL FIELD8(0x40) | 1749 | #define BBP4_MAC_IF_CTRL FIELD8(0x40) |
1750 | 1750 | ||
1751 | /* | 1751 | /* |
1752 | * BBP 109 | 1752 | * BBP 109 |
1753 | */ | 1753 | */ |
1754 | #define BBP109_TX0_POWER FIELD8(0x0f) | 1754 | #define BBP109_TX0_POWER FIELD8(0x0f) |
1755 | #define BBP109_TX1_POWER FIELD8(0xf0) | 1755 | #define BBP109_TX1_POWER FIELD8(0xf0) |
1756 | 1756 | ||
1757 | /* | 1757 | /* |
1758 | * BBP 138: Unknown | 1758 | * BBP 138: Unknown |
@@ -1765,7 +1765,7 @@ struct mac_iveiv_entry { | |||
1765 | /* | 1765 | /* |
1766 | * BBP 152: Rx Ant | 1766 | * BBP 152: Rx Ant |
1767 | */ | 1767 | */ |
1768 | #define BBP152_RX_DEFAULT_ANT FIELD8(0x80) | 1768 | #define BBP152_RX_DEFAULT_ANT FIELD8(0x80) |
1769 | 1769 | ||
1770 | /* | 1770 | /* |
1771 | * RFCSR registers | 1771 | * RFCSR registers |
@@ -1776,7 +1776,7 @@ struct mac_iveiv_entry { | |||
1776 | * RFCSR 1: | 1776 | * RFCSR 1: |
1777 | */ | 1777 | */ |
1778 | #define RFCSR1_RF_BLOCK_EN FIELD8(0x01) | 1778 | #define RFCSR1_RF_BLOCK_EN FIELD8(0x01) |
1779 | #define RFCSR1_PLL_PD FIELD8(0x02) | 1779 | #define RFCSR1_PLL_PD FIELD8(0x02) |
1780 | #define RFCSR1_RX0_PD FIELD8(0x04) | 1780 | #define RFCSR1_RX0_PD FIELD8(0x04) |
1781 | #define RFCSR1_TX0_PD FIELD8(0x08) | 1781 | #define RFCSR1_TX0_PD FIELD8(0x08) |
1782 | #define RFCSR1_RX1_PD FIELD8(0x10) | 1782 | #define RFCSR1_RX1_PD FIELD8(0x10) |
@@ -1785,7 +1785,7 @@ struct mac_iveiv_entry { | |||
1785 | /* | 1785 | /* |
1786 | * RFCSR 2: | 1786 | * RFCSR 2: |
1787 | */ | 1787 | */ |
1788 | #define RFCSR2_RESCAL_EN FIELD8(0x80) | 1788 | #define RFCSR2_RESCAL_EN FIELD8(0x80) |
1789 | 1789 | ||
1790 | /* | 1790 | /* |
1791 | * RFCSR 6: | 1791 | * RFCSR 6: |
@@ -1801,7 +1801,7 @@ struct mac_iveiv_entry { | |||
1801 | /* | 1801 | /* |
1802 | * RFCSR 11: | 1802 | * RFCSR 11: |
1803 | */ | 1803 | */ |
1804 | #define RFCSR11_R FIELD8(0x03) | 1804 | #define RFCSR11_R FIELD8(0x03) |
1805 | 1805 | ||
1806 | /* | 1806 | /* |
1807 | * RFCSR 12: | 1807 | * RFCSR 12: |
@@ -1857,9 +1857,9 @@ struct mac_iveiv_entry { | |||
1857 | /* | 1857 | /* |
1858 | * RFCSR 30: | 1858 | * RFCSR 30: |
1859 | */ | 1859 | */ |
1860 | #define RFCSR30_TX_H20M FIELD8(0x02) | 1860 | #define RFCSR30_TX_H20M FIELD8(0x02) |
1861 | #define RFCSR30_RX_H20M FIELD8(0x04) | 1861 | #define RFCSR30_RX_H20M FIELD8(0x04) |
1862 | #define RFCSR30_RX_VCM FIELD8(0x18) | 1862 | #define RFCSR30_RX_VCM FIELD8(0x18) |
1863 | #define RFCSR30_RF_CALIBRATION FIELD8(0x80) | 1863 | #define RFCSR30_RF_CALIBRATION FIELD8(0x80) |
1864 | 1864 | ||
1865 | /* | 1865 | /* |
@@ -1871,17 +1871,17 @@ struct mac_iveiv_entry { | |||
1871 | /* | 1871 | /* |
1872 | * RFCSR 38: | 1872 | * RFCSR 38: |
1873 | */ | 1873 | */ |
1874 | #define RFCSR38_RX_LO1_EN FIELD8(0x20) | 1874 | #define RFCSR38_RX_LO1_EN FIELD8(0x20) |
1875 | 1875 | ||
1876 | /* | 1876 | /* |
1877 | * RFCSR 39: | 1877 | * RFCSR 39: |
1878 | */ | 1878 | */ |
1879 | #define RFCSR39_RX_LO2_EN FIELD8(0x80) | 1879 | #define RFCSR39_RX_LO2_EN FIELD8(0x80) |
1880 | 1880 | ||
1881 | /* | 1881 | /* |
1882 | * RFCSR 49: | 1882 | * RFCSR 49: |
1883 | */ | 1883 | */ |
1884 | #define RFCSR49_TX FIELD8(0x3f) | 1884 | #define RFCSR49_TX FIELD8(0x3f) |
1885 | 1885 | ||
1886 | /* | 1886 | /* |
1887 | * RF registers | 1887 | * RF registers |
@@ -1918,7 +1918,7 @@ struct mac_iveiv_entry { | |||
1918 | /* | 1918 | /* |
1919 | * Chip ID | 1919 | * Chip ID |
1920 | */ | 1920 | */ |
1921 | #define EEPROM_CHIP_ID 0x0000 | 1921 | #define EEPROM_CHIP_ID 0x0000 |
1922 | 1922 | ||
1923 | /* | 1923 | /* |
1924 | * EEPROM Version | 1924 | * EEPROM Version |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3da78bf0ca26..2ee6cebb9b25 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -400,15 +400,15 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
400 | if (rt2800_wait_csr_ready(rt2x00dev)) | 400 | if (rt2800_wait_csr_ready(rt2x00dev)) |
401 | return -EBUSY; | 401 | return -EBUSY; |
402 | 402 | ||
403 | if (rt2x00_is_pci(rt2x00dev)) { | 403 | if (rt2x00_is_pci(rt2x00dev)) { |
404 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 404 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
405 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); | 405 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); |
406 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | 406 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); |
407 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | 407 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); |
408 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); | 408 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); |
409 | } | 409 | } |
410 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); | 410 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); |
411 | } | 411 | } |
412 | 412 | ||
413 | /* | 413 | /* |
414 | * Disable DMA, will be reenabled later when enabling | 414 | * Disable DMA, will be reenabled later when enabling |
@@ -472,14 +472,15 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
472 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 472 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
473 | rt2x00_set_field32(&word, TXWI_W0_AMPDU, | 473 | rt2x00_set_field32(&word, TXWI_W0_AMPDU, |
474 | test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); | 474 | test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); |
475 | rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density); | 475 | rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, |
476 | rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop); | 476 | txdesc->u.ht.mpdu_density); |
477 | rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs); | 477 | rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->u.ht.txop); |
478 | rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->u.ht.mcs); | ||
478 | rt2x00_set_field32(&word, TXWI_W0_BW, | 479 | rt2x00_set_field32(&word, TXWI_W0_BW, |
479 | test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); | 480 | test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); |
480 | rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, | 481 | rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, |
481 | test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); | 482 | test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); |
482 | rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc); | 483 | rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->u.ht.stbc); |
483 | rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); | 484 | rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); |
484 | rt2x00_desc_write(txwi, 0, word); | 485 | rt2x00_desc_write(txwi, 0, word); |
485 | 486 | ||
@@ -488,7 +489,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
488 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); | 489 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
489 | rt2x00_set_field32(&word, TXWI_W1_NSEQ, | 490 | rt2x00_set_field32(&word, TXWI_W1_NSEQ, |
490 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | 491 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); |
491 | rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); | 492 | rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->u.ht.ba_size); |
492 | rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, | 493 | rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, |
493 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? | 494 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? |
494 | txdesc->key_idx : 0xff); | 495 | txdesc->key_idx : 0xff); |
@@ -681,7 +682,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) | |||
681 | * confuse the rate control algortihm by providing clearly wrong | 682 | * confuse the rate control algortihm by providing clearly wrong |
682 | * data. | 683 | * data. |
683 | */ | 684 | */ |
684 | if (aggr == 1 && ampdu == 0 && real_mcs != mcs) { | 685 | if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) { |
685 | skbdesc->tx_rate_idx = real_mcs; | 686 | skbdesc->tx_rate_idx = real_mcs; |
686 | mcs = real_mcs; | 687 | mcs = real_mcs; |
687 | } | 688 | } |
@@ -751,7 +752,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
751 | if (pid >= QID_RX) | 752 | if (pid >= QID_RX) |
752 | continue; | 753 | continue; |
753 | 754 | ||
754 | queue = rt2x00queue_get_queue(rt2x00dev, pid); | 755 | queue = rt2x00queue_get_tx_queue(rt2x00dev, pid); |
755 | if (unlikely(!queue)) | 756 | if (unlikely(!queue)) |
756 | continue; | 757 | continue; |
757 | 758 | ||
@@ -1100,27 +1101,44 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
1100 | } | 1101 | } |
1101 | EXPORT_SYMBOL_GPL(rt2800_config_shared_key); | 1102 | EXPORT_SYMBOL_GPL(rt2800_config_shared_key); |
1102 | 1103 | ||
1104 | static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev) | ||
1105 | { | ||
1106 | int idx; | ||
1107 | u32 offset, reg; | ||
1108 | |||
1109 | /* | ||
1110 | * Search for the first free pairwise key entry and return the | ||
1111 | * corresponding index. | ||
1112 | * | ||
1113 | * Make sure the WCID starts _after_ the last possible shared key | ||
1114 | * entry (>32). | ||
1115 | * | ||
1116 | * Since parts of the pairwise key table might be shared with | ||
1117 | * the beacon frame buffers 6 & 7 we should only write into the | ||
1118 | * first 222 entries. | ||
1119 | */ | ||
1120 | for (idx = 33; idx <= 222; idx++) { | ||
1121 | offset = MAC_WCID_ATTR_ENTRY(idx); | ||
1122 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1123 | if (!reg) | ||
1124 | return idx; | ||
1125 | } | ||
1126 | return -1; | ||
1127 | } | ||
1128 | |||
1103 | int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | 1129 | int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, |
1104 | struct rt2x00lib_crypto *crypto, | 1130 | struct rt2x00lib_crypto *crypto, |
1105 | struct ieee80211_key_conf *key) | 1131 | struct ieee80211_key_conf *key) |
1106 | { | 1132 | { |
1107 | struct hw_key_entry key_entry; | 1133 | struct hw_key_entry key_entry; |
1108 | u32 offset; | 1134 | u32 offset; |
1135 | int idx; | ||
1109 | 1136 | ||
1110 | if (crypto->cmd == SET_KEY) { | 1137 | if (crypto->cmd == SET_KEY) { |
1111 | /* | 1138 | idx = rt2800_find_pairwise_keyslot(rt2x00dev); |
1112 | * 1 pairwise key is possible per AID, this means that the AID | 1139 | if (idx < 0) |
1113 | * equals our hw_key_idx. Make sure the WCID starts _after_ the | ||
1114 | * last possible shared key entry. | ||
1115 | * | ||
1116 | * Since parts of the pairwise key table might be shared with | ||
1117 | * the beacon frame buffers 6 & 7 we should only write into the | ||
1118 | * first 222 entries. | ||
1119 | */ | ||
1120 | if (crypto->aid > (222 - 32)) | ||
1121 | return -ENOSPC; | 1140 | return -ENOSPC; |
1122 | 1141 | key->hw_key_idx = idx; | |
1123 | key->hw_key_idx = 32 + crypto->aid; | ||
1124 | 1142 | ||
1125 | memcpy(key_entry.key, crypto->key, | 1143 | memcpy(key_entry.key, crypto->key, |
1126 | sizeof(key_entry.key)); | 1144 | sizeof(key_entry.key)); |
@@ -1585,92 +1603,98 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
1585 | #define RT5390_FREQ_OFFSET_BOUND 0x5f | 1603 | #define RT5390_FREQ_OFFSET_BOUND 0x5f |
1586 | 1604 | ||
1587 | static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | 1605 | static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, |
1588 | struct ieee80211_conf *conf, | 1606 | struct ieee80211_conf *conf, |
1589 | struct rf_channel *rf, | 1607 | struct rf_channel *rf, |
1590 | struct channel_info *info) | 1608 | struct channel_info *info) |
1591 | { | 1609 | { |
1592 | u8 rfcsr; | 1610 | u8 rfcsr; |
1593 | u16 eeprom; | 1611 | u16 eeprom; |
1594 | 1612 | ||
1595 | rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); | 1613 | rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); |
1596 | rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); | 1614 | rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); |
1597 | rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); | 1615 | rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); |
1598 | rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); | 1616 | rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); |
1599 | rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); | 1617 | rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); |
1600 | 1618 | ||
1601 | rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); | 1619 | rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); |
1602 | if (info->default_power1 > RT5390_POWER_BOUND) | 1620 | if (info->default_power1 > RT5390_POWER_BOUND) |
1603 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); | 1621 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); |
1604 | else | 1622 | else |
1605 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); | 1623 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); |
1606 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); | 1624 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); |
1607 | 1625 | ||
1608 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | 1626 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); |
1609 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | 1627 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); |
1610 | rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); | 1628 | rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); |
1611 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); | 1629 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); |
1612 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); | 1630 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); |
1613 | rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | 1631 | rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); |
1614 | 1632 | ||
1615 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | 1633 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); |
1616 | if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) | 1634 | if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) |
1617 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, RT5390_FREQ_OFFSET_BOUND); | 1635 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, |
1618 | else | 1636 | RT5390_FREQ_OFFSET_BOUND); |
1619 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | 1637 | else |
1620 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | 1638 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); |
1621 | 1639 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | |
1622 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | 1640 | |
1623 | if (rf->channel <= 14) { | 1641 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); |
1624 | int idx = rf->channel-1; | 1642 | if (rf->channel <= 14) { |
1625 | 1643 | int idx = rf->channel-1; | |
1626 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { | 1644 | |
1627 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { | 1645 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { |
1628 | /* r55/r59 value array of channel 1~14 */ | 1646 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { |
1629 | static const char r55_bt_rev[] = {0x83, 0x83, | 1647 | /* r55/r59 value array of channel 1~14 */ |
1630 | 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, | 1648 | static const char r55_bt_rev[] = {0x83, 0x83, |
1631 | 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; | 1649 | 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, |
1632 | static const char r59_bt_rev[] = {0x0e, 0x0e, | 1650 | 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; |
1633 | 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, | 1651 | static const char r59_bt_rev[] = {0x0e, 0x0e, |
1634 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; | 1652 | 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, |
1635 | 1653 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; | |
1636 | rt2800_rfcsr_write(rt2x00dev, 55, r55_bt_rev[idx]); | 1654 | |
1637 | rt2800_rfcsr_write(rt2x00dev, 59, r59_bt_rev[idx]); | 1655 | rt2800_rfcsr_write(rt2x00dev, 55, |
1638 | } else { | 1656 | r55_bt_rev[idx]); |
1639 | static const char r59_bt[] = {0x8b, 0x8b, 0x8b, | 1657 | rt2800_rfcsr_write(rt2x00dev, 59, |
1640 | 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, | 1658 | r59_bt_rev[idx]); |
1641 | 0x88, 0x88, 0x86, 0x85, 0x84}; | 1659 | } else { |
1642 | 1660 | static const char r59_bt[] = {0x8b, 0x8b, 0x8b, | |
1643 | rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); | 1661 | 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, |
1644 | } | 1662 | 0x88, 0x88, 0x86, 0x85, 0x84}; |
1645 | } else { | 1663 | |
1646 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { | 1664 | rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); |
1647 | static const char r55_nonbt_rev[] = {0x23, 0x23, | 1665 | } |
1648 | 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, | 1666 | } else { |
1649 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; | 1667 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { |
1650 | static const char r59_nonbt_rev[] = {0x07, 0x07, | 1668 | static const char r55_nonbt_rev[] = {0x23, 0x23, |
1651 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, | 1669 | 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, |
1652 | 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; | 1670 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; |
1653 | 1671 | static const char r59_nonbt_rev[] = {0x07, 0x07, | |
1654 | rt2800_rfcsr_write(rt2x00dev, 55, r55_nonbt_rev[idx]); | 1672 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
1655 | rt2800_rfcsr_write(rt2x00dev, 59, r59_nonbt_rev[idx]); | 1673 | 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; |
1656 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | 1674 | |
1657 | static const char r59_non_bt[] = {0x8f, 0x8f, | 1675 | rt2800_rfcsr_write(rt2x00dev, 55, |
1658 | 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, | 1676 | r55_nonbt_rev[idx]); |
1659 | 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; | 1677 | rt2800_rfcsr_write(rt2x00dev, 59, |
1660 | 1678 | r59_nonbt_rev[idx]); | |
1661 | rt2800_rfcsr_write(rt2x00dev, 59, r59_non_bt[idx]); | 1679 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { |
1662 | } | 1680 | static const char r59_non_bt[] = {0x8f, 0x8f, |
1663 | } | 1681 | 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, |
1664 | } | 1682 | 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; |
1665 | 1683 | ||
1666 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | 1684 | rt2800_rfcsr_write(rt2x00dev, 59, |
1667 | rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); | 1685 | r59_non_bt[idx]); |
1668 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); | 1686 | } |
1669 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 1687 | } |
1670 | 1688 | } | |
1671 | rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); | 1689 | |
1672 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | 1690 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); |
1673 | rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); | 1691 | rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); |
1692 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); | ||
1693 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
1694 | |||
1695 | rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); | ||
1696 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | ||
1697 | rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); | ||
1674 | } | 1698 | } |
1675 | 1699 | ||
1676 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | 1700 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, |
@@ -1697,8 +1721,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1697 | rt2x00_rf(rt2x00dev, RF3052) || | 1721 | rt2x00_rf(rt2x00dev, RF3052) || |
1698 | rt2x00_rf(rt2x00dev, RF3320)) | 1722 | rt2x00_rf(rt2x00dev, RF3320)) |
1699 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); | 1723 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); |
1700 | else if (rt2x00_rf(rt2x00dev, RF5390)) | 1724 | else if (rt2x00_rf(rt2x00dev, RF5390)) |
1701 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); | 1725 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); |
1702 | else | 1726 | else |
1703 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); | 1727 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); |
1704 | 1728 | ||
@@ -1711,14 +1735,15 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1711 | rt2800_bbp_write(rt2x00dev, 86, 0); | 1735 | rt2800_bbp_write(rt2x00dev, 86, 0); |
1712 | 1736 | ||
1713 | if (rf->channel <= 14) { | 1737 | if (rf->channel <= 14) { |
1714 | if (!rt2x00_rt(rt2x00dev, RT5390)) { | 1738 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
1715 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | 1739 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, |
1716 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 1740 | &rt2x00dev->flags)) { |
1717 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 1741 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
1718 | } else { | 1742 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
1719 | rt2800_bbp_write(rt2x00dev, 82, 0x84); | 1743 | } else { |
1720 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | 1744 | rt2800_bbp_write(rt2x00dev, 82, 0x84); |
1721 | } | 1745 | rt2800_bbp_write(rt2x00dev, 75, 0x50); |
1746 | } | ||
1722 | } | 1747 | } |
1723 | } else { | 1748 | } else { |
1724 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); | 1749 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); |
@@ -2097,8 +2122,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) | |||
2097 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2122 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2098 | rt2x00_rt(rt2x00dev, RT3071) || | 2123 | rt2x00_rt(rt2x00dev, RT3071) || |
2099 | rt2x00_rt(rt2x00dev, RT3090) || | 2124 | rt2x00_rt(rt2x00dev, RT3090) || |
2100 | rt2x00_rt(rt2x00dev, RT3390) || | 2125 | rt2x00_rt(rt2x00dev, RT3390) || |
2101 | rt2x00_rt(rt2x00dev, RT5390)) | 2126 | rt2x00_rt(rt2x00dev, RT5390)) |
2102 | return 0x1c + (2 * rt2x00dev->lna_gain); | 2127 | return 0x1c + (2 * rt2x00dev->lna_gain); |
2103 | else | 2128 | else |
2104 | return 0x2e + rt2x00dev->lna_gain; | 2129 | return 0x2e + rt2x00dev->lna_gain; |
@@ -2230,10 +2255,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2230 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | 2255 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); |
2231 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); | 2256 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); |
2232 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); | 2257 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); |
2233 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | 2258 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { |
2234 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); | 2259 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); |
2235 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 2260 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
2236 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); | 2261 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); |
2237 | } else { | 2262 | } else { |
2238 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); | 2263 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); |
2239 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 2264 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
@@ -2450,7 +2475,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2450 | rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), | 2475 | rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), |
2451 | wcid, sizeof(wcid)); | 2476 | wcid, sizeof(wcid)); |
2452 | 2477 | ||
2453 | rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1); | 2478 | rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 0); |
2454 | rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); | 2479 | rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); |
2455 | } | 2480 | } |
2456 | 2481 | ||
@@ -2609,31 +2634,31 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2609 | rt2800_wait_bbp_ready(rt2x00dev))) | 2634 | rt2800_wait_bbp_ready(rt2x00dev))) |
2610 | return -EACCES; | 2635 | return -EACCES; |
2611 | 2636 | ||
2612 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 2637 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
2613 | rt2800_bbp_read(rt2x00dev, 4, &value); | 2638 | rt2800_bbp_read(rt2x00dev, 4, &value); |
2614 | rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); | 2639 | rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); |
2615 | rt2800_bbp_write(rt2x00dev, 4, value); | 2640 | rt2800_bbp_write(rt2x00dev, 4, value); |
2616 | } | 2641 | } |
2617 | 2642 | ||
2618 | if (rt2800_is_305x_soc(rt2x00dev) || | 2643 | if (rt2800_is_305x_soc(rt2x00dev) || |
2619 | rt2x00_rt(rt2x00dev, RT5390)) | 2644 | rt2x00_rt(rt2x00dev, RT5390)) |
2620 | rt2800_bbp_write(rt2x00dev, 31, 0x08); | 2645 | rt2800_bbp_write(rt2x00dev, 31, 0x08); |
2621 | 2646 | ||
2622 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); | 2647 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); |
2623 | rt2800_bbp_write(rt2x00dev, 66, 0x38); | 2648 | rt2800_bbp_write(rt2x00dev, 66, 0x38); |
2624 | 2649 | ||
2625 | if (rt2x00_rt(rt2x00dev, RT5390)) | 2650 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2626 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); | 2651 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); |
2627 | 2652 | ||
2628 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { | 2653 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { |
2629 | rt2800_bbp_write(rt2x00dev, 69, 0x16); | 2654 | rt2800_bbp_write(rt2x00dev, 69, 0x16); |
2630 | rt2800_bbp_write(rt2x00dev, 73, 0x12); | 2655 | rt2800_bbp_write(rt2x00dev, 73, 0x12); |
2631 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | 2656 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { |
2632 | rt2800_bbp_write(rt2x00dev, 69, 0x12); | 2657 | rt2800_bbp_write(rt2x00dev, 69, 0x12); |
2633 | rt2800_bbp_write(rt2x00dev, 73, 0x13); | 2658 | rt2800_bbp_write(rt2x00dev, 73, 0x13); |
2634 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 2659 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
2635 | rt2800_bbp_write(rt2x00dev, 76, 0x28); | 2660 | rt2800_bbp_write(rt2x00dev, 76, 0x28); |
2636 | rt2800_bbp_write(rt2x00dev, 77, 0x59); | 2661 | rt2800_bbp_write(rt2x00dev, 77, 0x59); |
2637 | } else { | 2662 | } else { |
2638 | rt2800_bbp_write(rt2x00dev, 69, 0x12); | 2663 | rt2800_bbp_write(rt2x00dev, 69, 0x12); |
2639 | rt2800_bbp_write(rt2x00dev, 73, 0x10); | 2664 | rt2800_bbp_write(rt2x00dev, 73, 0x10); |
@@ -2644,8 +2669,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2644 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2669 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2645 | rt2x00_rt(rt2x00dev, RT3071) || | 2670 | rt2x00_rt(rt2x00dev, RT3071) || |
2646 | rt2x00_rt(rt2x00dev, RT3090) || | 2671 | rt2x00_rt(rt2x00dev, RT3090) || |
2647 | rt2x00_rt(rt2x00dev, RT3390) || | 2672 | rt2x00_rt(rt2x00dev, RT3390) || |
2648 | rt2x00_rt(rt2x00dev, RT5390)) { | 2673 | rt2x00_rt(rt2x00dev, RT5390)) { |
2649 | rt2800_bbp_write(rt2x00dev, 79, 0x13); | 2674 | rt2800_bbp_write(rt2x00dev, 79, 0x13); |
2650 | rt2800_bbp_write(rt2x00dev, 80, 0x05); | 2675 | rt2800_bbp_write(rt2x00dev, 80, 0x05); |
2651 | rt2800_bbp_write(rt2x00dev, 81, 0x33); | 2676 | rt2800_bbp_write(rt2x00dev, 81, 0x33); |
@@ -2657,62 +2682,62 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2657 | } | 2682 | } |
2658 | 2683 | ||
2659 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 2684 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
2660 | if (rt2x00_rt(rt2x00dev, RT5390)) | 2685 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2661 | rt2800_bbp_write(rt2x00dev, 83, 0x7a); | 2686 | rt2800_bbp_write(rt2x00dev, 83, 0x7a); |
2662 | else | 2687 | else |
2663 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); | 2688 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); |
2664 | 2689 | ||
2665 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) | 2690 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) |
2666 | rt2800_bbp_write(rt2x00dev, 84, 0x19); | 2691 | rt2800_bbp_write(rt2x00dev, 84, 0x19); |
2667 | else if (rt2x00_rt(rt2x00dev, RT5390)) | 2692 | else if (rt2x00_rt(rt2x00dev, RT5390)) |
2668 | rt2800_bbp_write(rt2x00dev, 84, 0x9a); | 2693 | rt2800_bbp_write(rt2x00dev, 84, 0x9a); |
2669 | else | 2694 | else |
2670 | rt2800_bbp_write(rt2x00dev, 84, 0x99); | 2695 | rt2800_bbp_write(rt2x00dev, 84, 0x99); |
2671 | 2696 | ||
2672 | if (rt2x00_rt(rt2x00dev, RT5390)) | 2697 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2673 | rt2800_bbp_write(rt2x00dev, 86, 0x38); | 2698 | rt2800_bbp_write(rt2x00dev, 86, 0x38); |
2674 | else | 2699 | else |
2675 | rt2800_bbp_write(rt2x00dev, 86, 0x00); | 2700 | rt2800_bbp_write(rt2x00dev, 86, 0x00); |
2676 | 2701 | ||
2677 | rt2800_bbp_write(rt2x00dev, 91, 0x04); | 2702 | rt2800_bbp_write(rt2x00dev, 91, 0x04); |
2678 | 2703 | ||
2679 | if (rt2x00_rt(rt2x00dev, RT5390)) | 2704 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2680 | rt2800_bbp_write(rt2x00dev, 92, 0x02); | 2705 | rt2800_bbp_write(rt2x00dev, 92, 0x02); |
2681 | else | 2706 | else |
2682 | rt2800_bbp_write(rt2x00dev, 92, 0x00); | 2707 | rt2800_bbp_write(rt2x00dev, 92, 0x00); |
2683 | 2708 | ||
2684 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || | 2709 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || |
2685 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || | 2710 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || |
2686 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || | 2711 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || |
2687 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || | 2712 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || |
2688 | rt2x00_rt(rt2x00dev, RT5390) || | 2713 | rt2x00_rt(rt2x00dev, RT5390) || |
2689 | rt2800_is_305x_soc(rt2x00dev)) | 2714 | rt2800_is_305x_soc(rt2x00dev)) |
2690 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); | 2715 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
2691 | else | 2716 | else |
2692 | rt2800_bbp_write(rt2x00dev, 103, 0x00); | 2717 | rt2800_bbp_write(rt2x00dev, 103, 0x00); |
2693 | 2718 | ||
2694 | if (rt2x00_rt(rt2x00dev, RT5390)) | 2719 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2695 | rt2800_bbp_write(rt2x00dev, 104, 0x92); | 2720 | rt2800_bbp_write(rt2x00dev, 104, 0x92); |
2696 | 2721 | ||
2697 | if (rt2800_is_305x_soc(rt2x00dev)) | 2722 | if (rt2800_is_305x_soc(rt2x00dev)) |
2698 | rt2800_bbp_write(rt2x00dev, 105, 0x01); | 2723 | rt2800_bbp_write(rt2x00dev, 105, 0x01); |
2699 | else if (rt2x00_rt(rt2x00dev, RT5390)) | 2724 | else if (rt2x00_rt(rt2x00dev, RT5390)) |
2700 | rt2800_bbp_write(rt2x00dev, 105, 0x3c); | 2725 | rt2800_bbp_write(rt2x00dev, 105, 0x3c); |
2701 | else | 2726 | else |
2702 | rt2800_bbp_write(rt2x00dev, 105, 0x05); | 2727 | rt2800_bbp_write(rt2x00dev, 105, 0x05); |
2703 | 2728 | ||
2704 | if (rt2x00_rt(rt2x00dev, RT5390)) | 2729 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2705 | rt2800_bbp_write(rt2x00dev, 106, 0x03); | 2730 | rt2800_bbp_write(rt2x00dev, 106, 0x03); |
2706 | else | 2731 | else |
2707 | rt2800_bbp_write(rt2x00dev, 106, 0x35); | 2732 | rt2800_bbp_write(rt2x00dev, 106, 0x35); |
2708 | 2733 | ||
2709 | if (rt2x00_rt(rt2x00dev, RT5390)) | 2734 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2710 | rt2800_bbp_write(rt2x00dev, 128, 0x12); | 2735 | rt2800_bbp_write(rt2x00dev, 128, 0x12); |
2711 | 2736 | ||
2712 | if (rt2x00_rt(rt2x00dev, RT3071) || | 2737 | if (rt2x00_rt(rt2x00dev, RT3071) || |
2713 | rt2x00_rt(rt2x00dev, RT3090) || | 2738 | rt2x00_rt(rt2x00dev, RT3090) || |
2714 | rt2x00_rt(rt2x00dev, RT3390) || | 2739 | rt2x00_rt(rt2x00dev, RT3390) || |
2715 | rt2x00_rt(rt2x00dev, RT5390)) { | 2740 | rt2x00_rt(rt2x00dev, RT5390)) { |
2716 | rt2800_bbp_read(rt2x00dev, 138, &value); | 2741 | rt2800_bbp_read(rt2x00dev, 138, &value); |
2717 | 2742 | ||
2718 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | 2743 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
@@ -2724,41 +2749,42 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2724 | rt2800_bbp_write(rt2x00dev, 138, value); | 2749 | rt2800_bbp_write(rt2x00dev, 138, value); |
2725 | } | 2750 | } |
2726 | 2751 | ||
2727 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 2752 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
2728 | int ant, div_mode; | 2753 | int ant, div_mode; |
2729 | 2754 | ||
2730 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | 2755 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); |
2731 | div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); | 2756 | div_mode = rt2x00_get_field16(eeprom, |
2732 | ant = (div_mode == 3) ? 1 : 0; | 2757 | EEPROM_NIC_CONF1_ANT_DIVERSITY); |
2733 | 2758 | ant = (div_mode == 3) ? 1 : 0; | |
2734 | /* check if this is a Bluetooth combo card */ | 2759 | |
2735 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | 2760 | /* check if this is a Bluetooth combo card */ |
2736 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { | 2761 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); |
2737 | u32 reg; | 2762 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { |
2738 | 2763 | u32 reg; | |
2739 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | 2764 | |
2740 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); | 2765 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); |
2741 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0); | 2766 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); |
2742 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0); | 2767 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0); |
2743 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0); | 2768 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0); |
2744 | if (ant == 0) | 2769 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0); |
2745 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1); | 2770 | if (ant == 0) |
2746 | else if (ant == 1) | 2771 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1); |
2747 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1); | 2772 | else if (ant == 1) |
2748 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | 2773 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1); |
2749 | } | 2774 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); |
2750 | 2775 | } | |
2751 | rt2800_bbp_read(rt2x00dev, 152, &value); | 2776 | |
2752 | if (ant == 0) | 2777 | rt2800_bbp_read(rt2x00dev, 152, &value); |
2753 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); | 2778 | if (ant == 0) |
2754 | else | 2779 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); |
2755 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); | 2780 | else |
2756 | rt2800_bbp_write(rt2x00dev, 152, value); | 2781 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); |
2757 | 2782 | rt2800_bbp_write(rt2x00dev, 152, value); | |
2758 | /* Init frequency calibration */ | 2783 | |
2759 | rt2800_bbp_write(rt2x00dev, 142, 1); | 2784 | /* Init frequency calibration */ |
2760 | rt2800_bbp_write(rt2x00dev, 143, 57); | 2785 | rt2800_bbp_write(rt2x00dev, 142, 1); |
2761 | } | 2786 | rt2800_bbp_write(rt2x00dev, 143, 57); |
2787 | } | ||
2762 | 2788 | ||
2763 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 2789 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
2764 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 2790 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
@@ -2848,28 +2874,28 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2848 | !rt2x00_rt(rt2x00dev, RT3071) && | 2874 | !rt2x00_rt(rt2x00dev, RT3071) && |
2849 | !rt2x00_rt(rt2x00dev, RT3090) && | 2875 | !rt2x00_rt(rt2x00dev, RT3090) && |
2850 | !rt2x00_rt(rt2x00dev, RT3390) && | 2876 | !rt2x00_rt(rt2x00dev, RT3390) && |
2851 | !rt2x00_rt(rt2x00dev, RT5390) && | 2877 | !rt2x00_rt(rt2x00dev, RT5390) && |
2852 | !rt2800_is_305x_soc(rt2x00dev)) | 2878 | !rt2800_is_305x_soc(rt2x00dev)) |
2853 | return 0; | 2879 | return 0; |
2854 | 2880 | ||
2855 | /* | 2881 | /* |
2856 | * Init RF calibration. | 2882 | * Init RF calibration. |
2857 | */ | 2883 | */ |
2858 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 2884 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
2859 | rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); | 2885 | rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); |
2860 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); | 2886 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); |
2861 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); | 2887 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); |
2862 | msleep(1); | 2888 | msleep(1); |
2863 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); | 2889 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); |
2864 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); | 2890 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); |
2865 | } else { | 2891 | } else { |
2866 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | 2892 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); |
2867 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | 2893 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); |
2868 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 2894 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); |
2869 | msleep(1); | 2895 | msleep(1); |
2870 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); | 2896 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); |
2871 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 2897 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); |
2872 | } | 2898 | } |
2873 | 2899 | ||
2874 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2900 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2875 | rt2x00_rt(rt2x00dev, RT3071) || | 2901 | rt2x00_rt(rt2x00dev, RT3071) || |
@@ -2960,87 +2986,87 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2960 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | 2986 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); |
2961 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); | 2987 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); |
2962 | return 0; | 2988 | return 0; |
2963 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | 2989 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { |
2964 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | 2990 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); |
2965 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | 2991 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); |
2966 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | 2992 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); |
2967 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | 2993 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); |
2968 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | 2994 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) |
2969 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); | 2995 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); |
2970 | else | 2996 | else |
2971 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); | 2997 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); |
2972 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | 2998 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); |
2973 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | 2999 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); |
2974 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | 3000 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); |
2975 | rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); | 3001 | rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); |
2976 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | 3002 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); |
2977 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | 3003 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); |
2978 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | 3004 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); |
2979 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | 3005 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); |
2980 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | 3006 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); |
2981 | rt2800_rfcsr_write(rt2x00dev, 19, 0x00); | 3007 | rt2800_rfcsr_write(rt2x00dev, 19, 0x00); |
2982 | 3008 | ||
2983 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | 3009 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); |
2984 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); | 3010 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); |
2985 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | 3011 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); |
2986 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); | 3012 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); |
2987 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); | 3013 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); |
2988 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | 3014 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) |
2989 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | 3015 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); |
2990 | else | 3016 | else |
2991 | rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); | 3017 | rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); |
2992 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); | 3018 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); |
2993 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | 3019 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); |
2994 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | 3020 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); |
2995 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | 3021 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); |
2996 | 3022 | ||
2997 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | 3023 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); |
2998 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | 3024 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); |
2999 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | 3025 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); |
3000 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | 3026 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); |
3001 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | 3027 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); |
3002 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | 3028 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); |
3003 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | 3029 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); |
3004 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | 3030 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); |
3005 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | 3031 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); |
3006 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | 3032 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); |
3007 | 3033 | ||
3008 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | 3034 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) |
3009 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); | 3035 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); |
3010 | else | 3036 | else |
3011 | rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); | 3037 | rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); |
3012 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | 3038 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); |
3013 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); | 3039 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); |
3014 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); | 3040 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); |
3015 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | 3041 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); |
3016 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | 3042 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); |
3017 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | 3043 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) |
3018 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | 3044 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); |
3019 | else | 3045 | else |
3020 | rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); | 3046 | rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); |
3021 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); | 3047 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); |
3022 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | 3048 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); |
3023 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); | 3049 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); |
3024 | 3050 | ||
3025 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); | 3051 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); |
3026 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | 3052 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) |
3027 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); | 3053 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); |
3028 | else | 3054 | else |
3029 | rt2800_rfcsr_write(rt2x00dev, 53, 0x84); | 3055 | rt2800_rfcsr_write(rt2x00dev, 53, 0x84); |
3030 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); | 3056 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); |
3031 | rt2800_rfcsr_write(rt2x00dev, 55, 0x44); | 3057 | rt2800_rfcsr_write(rt2x00dev, 55, 0x44); |
3032 | rt2800_rfcsr_write(rt2x00dev, 56, 0x22); | 3058 | rt2800_rfcsr_write(rt2x00dev, 56, 0x22); |
3033 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); | 3059 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); |
3034 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); | 3060 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); |
3035 | rt2800_rfcsr_write(rt2x00dev, 59, 0x63); | 3061 | rt2800_rfcsr_write(rt2x00dev, 59, 0x63); |
3036 | 3062 | ||
3037 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | 3063 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); |
3038 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | 3064 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) |
3039 | rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); | 3065 | rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); |
3040 | else | 3066 | else |
3041 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); | 3067 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); |
3042 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | 3068 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); |
3043 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | 3069 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); |
3044 | } | 3070 | } |
3045 | 3071 | ||
3046 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | 3072 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { |
@@ -3094,23 +3120,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
3094 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); | 3120 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); |
3095 | } | 3121 | } |
3096 | 3122 | ||
3097 | if (!rt2x00_rt(rt2x00dev, RT5390)) { | 3123 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
3098 | /* | 3124 | /* |
3099 | * Set back to initial state | 3125 | * Set back to initial state |
3100 | */ | 3126 | */ |
3101 | rt2800_bbp_write(rt2x00dev, 24, 0); | 3127 | rt2800_bbp_write(rt2x00dev, 24, 0); |
3102 | 3128 | ||
3103 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); | 3129 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); |
3104 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); | 3130 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); |
3105 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); | 3131 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); |
3106 | 3132 | ||
3107 | /* | 3133 | /* |
3108 | * Set BBP back to BW20 | 3134 | * Set BBP back to BW20 |
3109 | */ | 3135 | */ |
3110 | rt2800_bbp_read(rt2x00dev, 4, &bbp); | 3136 | rt2800_bbp_read(rt2x00dev, 4, &bbp); |
3111 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); | 3137 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); |
3112 | rt2800_bbp_write(rt2x00dev, 4, bbp); | 3138 | rt2800_bbp_write(rt2x00dev, 4, bbp); |
3113 | } | 3139 | } |
3114 | 3140 | ||
3115 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || | 3141 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || |
3116 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3142 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
@@ -3122,23 +3148,24 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
3122 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); | 3148 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); |
3123 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); | 3149 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); |
3124 | 3150 | ||
3125 | if (!rt2x00_rt(rt2x00dev, RT5390)) { | 3151 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
3126 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | 3152 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); |
3127 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); | 3153 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); |
3128 | if (rt2x00_rt(rt2x00dev, RT3070) || | 3154 | if (rt2x00_rt(rt2x00dev, RT3070) || |
3129 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3155 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
3130 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | 3156 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || |
3131 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | 3157 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { |
3132 | if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | 3158 | if (!test_bit(CONFIG_EXTERNAL_LNA_BG, |
3133 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); | 3159 | &rt2x00dev->flags)) |
3134 | } | 3160 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); |
3135 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); | 3161 | } |
3136 | if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) | 3162 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); |
3137 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, | 3163 | if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) |
3138 | rt2x00_get_field16(eeprom, | 3164 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, |
3139 | EEPROM_TXMIXER_GAIN_BG_VAL)); | 3165 | rt2x00_get_field16(eeprom, |
3140 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | 3166 | EEPROM_TXMIXER_GAIN_BG_VAL)); |
3141 | } | 3167 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); |
3168 | } | ||
3142 | 3169 | ||
3143 | if (rt2x00_rt(rt2x00dev, RT3090)) { | 3170 | if (rt2x00_rt(rt2x00dev, RT3090)) { |
3144 | rt2800_bbp_read(rt2x00dev, 138, &bbp); | 3171 | rt2800_bbp_read(rt2x00dev, 138, &bbp); |
@@ -3189,19 +3216,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
3189 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); | 3216 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); |
3190 | } | 3217 | } |
3191 | 3218 | ||
3192 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 3219 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
3193 | rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); | 3220 | rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); |
3194 | rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); | 3221 | rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); |
3195 | rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); | 3222 | rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); |
3196 | 3223 | ||
3197 | rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); | 3224 | rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); |
3198 | rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); | 3225 | rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); |
3199 | rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); | 3226 | rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); |
3200 | 3227 | ||
3201 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | 3228 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); |
3202 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); | 3229 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); |
3203 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 3230 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); |
3204 | } | 3231 | } |
3205 | 3232 | ||
3206 | return 0; | 3233 | return 0; |
3207 | } | 3234 | } |
@@ -3467,15 +3494,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3467 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | 3494 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
3468 | 3495 | ||
3469 | /* | 3496 | /* |
3470 | * Identify RF chipset by EEPROM value | 3497 | * Identify RF chipset by EEPROM value |
3471 | * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field | 3498 | * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field |
3472 | * RT53xx: defined in "EEPROM_CHIP_ID" field | 3499 | * RT53xx: defined in "EEPROM_CHIP_ID" field |
3473 | */ | 3500 | */ |
3474 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | 3501 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); |
3475 | if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) | 3502 | if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) |
3476 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); | 3503 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); |
3477 | else | 3504 | else |
3478 | value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); | 3505 | value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); |
3479 | 3506 | ||
3480 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), | 3507 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), |
3481 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); | 3508 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); |
@@ -3487,8 +3514,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3487 | !rt2x00_rt(rt2x00dev, RT3071) && | 3514 | !rt2x00_rt(rt2x00dev, RT3071) && |
3488 | !rt2x00_rt(rt2x00dev, RT3090) && | 3515 | !rt2x00_rt(rt2x00dev, RT3090) && |
3489 | !rt2x00_rt(rt2x00dev, RT3390) && | 3516 | !rt2x00_rt(rt2x00dev, RT3390) && |
3490 | !rt2x00_rt(rt2x00dev, RT3572) && | 3517 | !rt2x00_rt(rt2x00dev, RT3572) && |
3491 | !rt2x00_rt(rt2x00dev, RT5390)) { | 3518 | !rt2x00_rt(rt2x00dev, RT5390)) { |
3492 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | 3519 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); |
3493 | return -ENODEV; | 3520 | return -ENODEV; |
3494 | } | 3521 | } |
@@ -3502,8 +3529,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3502 | !rt2x00_rf(rt2x00dev, RF3021) && | 3529 | !rt2x00_rf(rt2x00dev, RF3021) && |
3503 | !rt2x00_rf(rt2x00dev, RF3022) && | 3530 | !rt2x00_rf(rt2x00dev, RF3022) && |
3504 | !rt2x00_rf(rt2x00dev, RF3052) && | 3531 | !rt2x00_rf(rt2x00dev, RF3052) && |
3505 | !rt2x00_rf(rt2x00dev, RF3320) && | 3532 | !rt2x00_rf(rt2x00dev, RF3320) && |
3506 | !rt2x00_rf(rt2x00dev, RF5390)) { | 3533 | !rt2x00_rf(rt2x00dev, RF5390)) { |
3507 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 3534 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); |
3508 | return -ENODEV; | 3535 | return -ENODEV; |
3509 | } | 3536 | } |
@@ -3800,8 +3827,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3800 | rt2x00_rf(rt2x00dev, RF2020) || | 3827 | rt2x00_rf(rt2x00dev, RF2020) || |
3801 | rt2x00_rf(rt2x00dev, RF3021) || | 3828 | rt2x00_rf(rt2x00dev, RF3021) || |
3802 | rt2x00_rf(rt2x00dev, RF3022) || | 3829 | rt2x00_rf(rt2x00dev, RF3022) || |
3803 | rt2x00_rf(rt2x00dev, RF3320) || | 3830 | rt2x00_rf(rt2x00dev, RF3320) || |
3804 | rt2x00_rf(rt2x00dev, RF5390)) { | 3831 | rt2x00_rf(rt2x00dev, RF5390)) { |
3805 | spec->num_channels = 14; | 3832 | spec->num_channels = 14; |
3806 | spec->channels = rf_vals_3x; | 3833 | spec->channels = rf_vals_3x; |
3807 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { | 3834 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { |
@@ -3965,7 +3992,7 @@ int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
3965 | if (queue_idx >= 4) | 3992 | if (queue_idx >= 4) |
3966 | return 0; | 3993 | return 0; |
3967 | 3994 | ||
3968 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 3995 | queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
3969 | 3996 | ||
3970 | /* Update WMM TXOP register */ | 3997 | /* Update WMM TXOP register */ |
3971 | offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); | 3998 | offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 38605e9fe427..808073aa9dcc 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -493,12 +493,12 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
493 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | 493 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); |
494 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | 494 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); |
495 | 495 | ||
496 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 496 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
497 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); | 497 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); |
498 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | 498 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); |
499 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | 499 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); |
500 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); | 500 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); |
501 | } | 501 | } |
502 | 502 | ||
503 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | 503 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); |
504 | 504 | ||
@@ -726,7 +726,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
726 | 726 | ||
727 | while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { | 727 | while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { |
728 | qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); | 728 | qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); |
729 | if (qid >= QID_RX) { | 729 | if (unlikely(qid >= QID_RX)) { |
730 | /* | 730 | /* |
731 | * Unknown queue, this shouldn't happen. Just drop | 731 | * Unknown queue, this shouldn't happen. Just drop |
732 | * this tx status. | 732 | * this tx status. |
@@ -736,7 +736,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
736 | break; | 736 | break; |
737 | } | 737 | } |
738 | 738 | ||
739 | queue = rt2x00queue_get_queue(rt2x00dev, qid); | 739 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
740 | if (unlikely(queue == NULL)) { | 740 | if (unlikely(queue == NULL)) { |
741 | /* | 741 | /* |
742 | * The queue is NULL, this shouldn't happen. Stop | 742 | * The queue is NULL, this shouldn't happen. Stop |
@@ -747,7 +747,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
747 | break; | 747 | break; |
748 | } | 748 | } |
749 | 749 | ||
750 | if (rt2x00queue_empty(queue)) { | 750 | if (unlikely(rt2x00queue_empty(queue))) { |
751 | /* | 751 | /* |
752 | * The queue is empty. Stop processing here | 752 | * The queue is empty. Stop processing here |
753 | * and drop the tx status. | 753 | * and drop the tx status. |
@@ -765,18 +765,17 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
765 | static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 765 | static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
766 | struct rt2x00_field32 irq_field) | 766 | struct rt2x00_field32 irq_field) |
767 | { | 767 | { |
768 | unsigned long flags; | ||
769 | u32 reg; | 768 | u32 reg; |
770 | 769 | ||
771 | /* | 770 | /* |
772 | * Enable a single interrupt. The interrupt mask register | 771 | * Enable a single interrupt. The interrupt mask register |
773 | * access needs locking. | 772 | * access needs locking. |
774 | */ | 773 | */ |
775 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 774 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
776 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); | 775 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); |
777 | rt2x00_set_field32(®, irq_field, 1); | 776 | rt2x00_set_field32(®, irq_field, 1); |
778 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 777 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); |
779 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 778 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
780 | } | 779 | } |
781 | 780 | ||
782 | static void rt2800pci_txstatus_tasklet(unsigned long data) | 781 | static void rt2800pci_txstatus_tasklet(unsigned long data) |
@@ -836,7 +835,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) | |||
836 | * | 835 | * |
837 | * Furthermore we don't disable the TX_FIFO_STATUS | 836 | * Furthermore we don't disable the TX_FIFO_STATUS |
838 | * interrupt here but leave it enabled so that the TX_STA_FIFO | 837 | * interrupt here but leave it enabled so that the TX_STA_FIFO |
839 | * can also be read while the interrupt thread gets executed. | 838 | * can also be read while the tx status tasklet gets executed. |
840 | * | 839 | * |
841 | * Since we have only one producer and one consumer we don't | 840 | * Since we have only one producer and one consumer we don't |
842 | * need to lock the kfifo. | 841 | * need to lock the kfifo. |
@@ -862,7 +861,6 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
862 | { | 861 | { |
863 | struct rt2x00_dev *rt2x00dev = dev_instance; | 862 | struct rt2x00_dev *rt2x00dev = dev_instance; |
864 | u32 reg, mask; | 863 | u32 reg, mask; |
865 | unsigned long flags; | ||
866 | 864 | ||
867 | /* Read status and ACK all interrupts */ | 865 | /* Read status and ACK all interrupts */ |
868 | rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 866 | rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
@@ -905,11 +903,11 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
905 | * Disable all interrupts for which a tasklet was scheduled right now, | 903 | * Disable all interrupts for which a tasklet was scheduled right now, |
906 | * the tasklet will reenable the appropriate interrupts. | 904 | * the tasklet will reenable the appropriate interrupts. |
907 | */ | 905 | */ |
908 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 906 | spin_lock(&rt2x00dev->irqmask_lock); |
909 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); | 907 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); |
910 | reg &= mask; | 908 | reg &= mask; |
911 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 909 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); |
912 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 910 | spin_unlock(&rt2x00dev->irqmask_lock); |
913 | 911 | ||
914 | return IRQ_HANDLED; | 912 | return IRQ_HANDLED; |
915 | } | 913 | } |
@@ -979,6 +977,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
979 | if (!modparam_nohwcrypt) | 977 | if (!modparam_nohwcrypt) |
980 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 978 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); |
981 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 979 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); |
980 | __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); | ||
982 | 981 | ||
983 | /* | 982 | /* |
984 | * Set the rssi offset. | 983 | * Set the rssi offset. |
@@ -1135,7 +1134,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | |||
1135 | { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1134 | { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1136 | #endif | 1135 | #endif |
1137 | #ifdef CONFIG_RT2800PCI_RT53XX | 1136 | #ifdef CONFIG_RT2800PCI_RT53XX |
1138 | { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1137 | { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1139 | #endif | 1138 | #endif |
1140 | { 0, } | 1139 | { 0, } |
1141 | }; | 1140 | }; |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5d91561e0de7..f1a92144996f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -565,6 +565,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
565 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 565 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); |
566 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 566 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); |
567 | __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); | 567 | __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); |
568 | __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); | ||
568 | 569 | ||
569 | /* | 570 | /* |
570 | * Set the rssi offset. | 571 | * Set the rssi offset. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 19453d23e90d..a3940d7300a4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -467,7 +467,6 @@ struct rt2x00lib_crypto { | |||
467 | const u8 *address; | 467 | const u8 *address; |
468 | 468 | ||
469 | u32 bssidx; | 469 | u32 bssidx; |
470 | u32 aid; | ||
471 | 470 | ||
472 | u8 key[16]; | 471 | u8 key[16]; |
473 | u8 tx_mic[8]; | 472 | u8 tx_mic[8]; |
@@ -662,6 +661,8 @@ enum rt2x00_flags { | |||
662 | DRIVER_REQUIRE_L2PAD, | 661 | DRIVER_REQUIRE_L2PAD, |
663 | DRIVER_REQUIRE_TXSTATUS_FIFO, | 662 | DRIVER_REQUIRE_TXSTATUS_FIFO, |
664 | DRIVER_REQUIRE_TASKLET_CONTEXT, | 663 | DRIVER_REQUIRE_TASKLET_CONTEXT, |
664 | DRIVER_REQUIRE_SW_SEQNO, | ||
665 | DRIVER_REQUIRE_HT_TX_DESC, | ||
665 | 666 | ||
666 | /* | 667 | /* |
667 | * Driver features | 668 | * Driver features |
@@ -886,14 +887,13 @@ struct rt2x00_dev { | |||
886 | struct work_struct txdone_work; | 887 | struct work_struct txdone_work; |
887 | 888 | ||
888 | /* | 889 | /* |
889 | * Data queue arrays for RX, TX and Beacon. | 890 | * Data queue arrays for RX, TX, Beacon and ATIM. |
890 | * The Beacon array also contains the Atim queue | ||
891 | * if that is supported by the device. | ||
892 | */ | 891 | */ |
893 | unsigned int data_queues; | 892 | unsigned int data_queues; |
894 | struct data_queue *rx; | 893 | struct data_queue *rx; |
895 | struct data_queue *tx; | 894 | struct data_queue *tx; |
896 | struct data_queue *bcn; | 895 | struct data_queue *bcn; |
896 | struct data_queue *atim; | ||
897 | 897 | ||
898 | /* | 898 | /* |
899 | * Firmware image. | 899 | * Firmware image. |
@@ -1063,12 +1063,24 @@ void rt2x00queue_map_txskb(struct queue_entry *entry); | |||
1063 | void rt2x00queue_unmap_skb(struct queue_entry *entry); | 1063 | void rt2x00queue_unmap_skb(struct queue_entry *entry); |
1064 | 1064 | ||
1065 | /** | 1065 | /** |
1066 | * rt2x00queue_get_queue - Convert queue index to queue pointer | 1066 | * rt2x00queue_get_tx_queue - Convert tx queue index to queue pointer |
1067 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 1067 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
1068 | * @queue: rt2x00 queue index (see &enum data_queue_qid). | 1068 | * @queue: rt2x00 queue index (see &enum data_queue_qid). |
1069 | * | ||
1070 | * Returns NULL for non tx queues. | ||
1069 | */ | 1071 | */ |
1070 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 1072 | static inline struct data_queue * |
1071 | const enum data_queue_qid queue); | 1073 | rt2x00queue_get_tx_queue(struct rt2x00_dev *rt2x00dev, |
1074 | const enum data_queue_qid queue) | ||
1075 | { | ||
1076 | if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) | ||
1077 | return &rt2x00dev->tx[queue]; | ||
1078 | |||
1079 | if (queue == QID_ATIM) | ||
1080 | return rt2x00dev->atim; | ||
1081 | |||
1082 | return NULL; | ||
1083 | } | ||
1072 | 1084 | ||
1073 | /** | 1085 | /** |
1074 | * rt2x00queue_get_entry - Get queue entry where the given index points to. | 1086 | * rt2x00queue_get_entry - Get queue entry where the given index points to. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index 03d9579da681..ae1219dffaae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c | |||
@@ -38,12 +38,12 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
38 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 38 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; |
39 | 39 | ||
40 | if (tx_info->control.sta) | 40 | if (tx_info->control.sta) |
41 | txdesc->mpdu_density = | 41 | txdesc->u.ht.mpdu_density = |
42 | tx_info->control.sta->ht_cap.ampdu_density; | 42 | tx_info->control.sta->ht_cap.ampdu_density; |
43 | 43 | ||
44 | txdesc->ba_size = 7; /* FIXME: What value is needed? */ | 44 | txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ |
45 | 45 | ||
46 | txdesc->stbc = | 46 | txdesc->u.ht.stbc = |
47 | (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; | 47 | (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; |
48 | 48 | ||
49 | /* | 49 | /* |
@@ -51,22 +51,22 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
51 | * mcs rate to be used | 51 | * mcs rate to be used |
52 | */ | 52 | */ |
53 | if (txrate->flags & IEEE80211_TX_RC_MCS) { | 53 | if (txrate->flags & IEEE80211_TX_RC_MCS) { |
54 | txdesc->mcs = txrate->idx; | 54 | txdesc->u.ht.mcs = txrate->idx; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * MIMO PS should be set to 1 for STA's using dynamic SM PS | 57 | * MIMO PS should be set to 1 for STA's using dynamic SM PS |
58 | * when using more then one tx stream (>MCS7). | 58 | * when using more then one tx stream (>MCS7). |
59 | */ | 59 | */ |
60 | if (tx_info->control.sta && txdesc->mcs > 7 && | 60 | if (tx_info->control.sta && txdesc->u.ht.mcs > 7 && |
61 | ((tx_info->control.sta->ht_cap.cap & | 61 | ((tx_info->control.sta->ht_cap.cap & |
62 | IEEE80211_HT_CAP_SM_PS) >> | 62 | IEEE80211_HT_CAP_SM_PS) >> |
63 | IEEE80211_HT_CAP_SM_PS_SHIFT) == | 63 | IEEE80211_HT_CAP_SM_PS_SHIFT) == |
64 | WLAN_HT_CAP_SM_PS_DYNAMIC) | 64 | WLAN_HT_CAP_SM_PS_DYNAMIC) |
65 | __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); | 65 | __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); |
66 | } else { | 66 | } else { |
67 | txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); | 67 | txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs); |
68 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | 68 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
69 | txdesc->mcs |= 0x08; | 69 | txdesc->u.ht.mcs |= 0x08; |
70 | } | 70 | } |
71 | 71 | ||
72 | /* | 72 | /* |
@@ -78,14 +78,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
78 | __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); | 78 | __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * Determine HT Mix/Greenfield rate mode | ||
82 | */ | ||
83 | if (txrate->flags & IEEE80211_TX_RC_MCS) | ||
84 | txdesc->rate_mode = RATE_MODE_HT_MIX; | ||
85 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) | ||
86 | txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; | ||
87 | |||
88 | /* | ||
89 | * Set 40Mhz mode if necessary (for legacy rates this will | 81 | * Set 40Mhz mode if necessary (for legacy rates this will |
90 | * duplicate the frame to both channels). | 82 | * duplicate the frame to both channels). |
91 | */ | 83 | */ |
@@ -105,11 +97,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
105 | * for frames not transmitted with TXOP_HTTXOP | 97 | * for frames not transmitted with TXOP_HTTXOP |
106 | */ | 98 | */ |
107 | if (ieee80211_is_mgmt(hdr->frame_control)) | 99 | if (ieee80211_is_mgmt(hdr->frame_control)) |
108 | txdesc->txop = TXOP_BACKOFF; | 100 | txdesc->u.ht.txop = TXOP_BACKOFF; |
109 | else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) | 101 | else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) |
110 | txdesc->txop = TXOP_SIFS; | 102 | txdesc->u.ht.txop = TXOP_SIFS; |
111 | else | 103 | else |
112 | txdesc->txop = TXOP_HTTXOP; | 104 | txdesc->u.ht.txop = TXOP_HTTXOP; |
113 | } | 105 | } |
114 | 106 | ||
115 | u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | 107 | u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c2c35838c2f3..661c6baad2b9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -116,13 +116,13 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
116 | goto exit_fail; | 116 | goto exit_fail; |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Determine which queue to put packet on. | 119 | * Use the ATIM queue if appropriate and present. |
120 | */ | 120 | */ |
121 | if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && | 121 | if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && |
122 | test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | 122 | test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) |
123 | queue = rt2x00queue_get_queue(rt2x00dev, QID_ATIM); | 123 | qid = QID_ATIM; |
124 | else | 124 | |
125 | queue = rt2x00queue_get_queue(rt2x00dev, qid); | 125 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
126 | if (unlikely(!queue)) { | 126 | if (unlikely(!queue)) { |
127 | ERROR(rt2x00dev, | 127 | ERROR(rt2x00dev, |
128 | "Attempt to send packet over invalid queue %d.\n" | 128 | "Attempt to send packet over invalid queue %d.\n" |
@@ -149,7 +149,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
149 | goto exit_fail; | 149 | goto exit_fail; |
150 | } | 150 | } |
151 | 151 | ||
152 | if (rt2x00queue_write_tx_frame(queue, skb, false)) | 152 | if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) |
153 | goto exit_fail; | 153 | goto exit_fail; |
154 | 154 | ||
155 | if (rt2x00queue_threshold(queue)) | 155 | if (rt2x00queue_threshold(queue)) |
@@ -190,7 +190,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
190 | { | 190 | { |
191 | struct rt2x00_dev *rt2x00dev = hw->priv; | 191 | struct rt2x00_dev *rt2x00dev = hw->priv; |
192 | struct rt2x00_intf *intf = vif_to_intf(vif); | 192 | struct rt2x00_intf *intf = vif_to_intf(vif); |
193 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON); | 193 | struct data_queue *queue = rt2x00dev->bcn; |
194 | struct queue_entry *entry = NULL; | 194 | struct queue_entry *entry = NULL; |
195 | unsigned int i; | 195 | unsigned int i; |
196 | 196 | ||
@@ -518,11 +518,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
518 | 518 | ||
519 | crypto.cmd = cmd; | 519 | crypto.cmd = cmd; |
520 | 520 | ||
521 | if (sta) { | 521 | if (sta) |
522 | /* some drivers need the AID */ | ||
523 | crypto.aid = sta->aid; | ||
524 | crypto.address = sta->addr; | 522 | crypto.address = sta->addr; |
525 | } else | 523 | else |
526 | crypto.address = bcast_addr; | 524 | crypto.address = bcast_addr; |
527 | 525 | ||
528 | if (crypto.cipher == CIPHER_TKIP) | 526 | if (crypto.cipher == CIPHER_TKIP) |
@@ -692,7 +690,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
692 | struct rt2x00_dev *rt2x00dev = hw->priv; | 690 | struct rt2x00_dev *rt2x00dev = hw->priv; |
693 | struct data_queue *queue; | 691 | struct data_queue *queue; |
694 | 692 | ||
695 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 693 | queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
696 | if (unlikely(!queue)) | 694 | if (unlikely(!queue)) |
697 | return -EINVAL; | 695 | return -EINVAL; |
698 | 696 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index bf9bba356280..4b3c70eeef1f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -221,14 +221,17 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | |||
221 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | 221 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); |
222 | unsigned long irqflags; | 222 | unsigned long irqflags; |
223 | 223 | ||
224 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) || | 224 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) |
225 | unlikely(!tx_info->control.vif)) | 225 | return; |
226 | |||
227 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | ||
228 | |||
229 | if (!test_bit(DRIVER_REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->flags)) | ||
226 | return; | 230 | return; |
227 | 231 | ||
228 | /* | 232 | /* |
229 | * Hardware should insert sequence counter. | 233 | * The hardware is not able to insert a sequence number. Assign a |
230 | * FIXME: We insert a software sequence counter first for | 234 | * software generated one here. |
231 | * hardware that doesn't support hardware sequence counting. | ||
232 | * | 235 | * |
233 | * This is wrong because beacons are not getting sequence | 236 | * This is wrong because beacons are not getting sequence |
234 | * numbers assigned properly. | 237 | * numbers assigned properly. |
@@ -246,7 +249,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | |||
246 | 249 | ||
247 | spin_unlock_irqrestore(&intf->seqlock, irqflags); | 250 | spin_unlock_irqrestore(&intf->seqlock, irqflags); |
248 | 251 | ||
249 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | ||
250 | } | 252 | } |
251 | 253 | ||
252 | static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | 254 | static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, |
@@ -260,6 +262,16 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | |||
260 | unsigned int duration; | 262 | unsigned int duration; |
261 | unsigned int residual; | 263 | unsigned int residual; |
262 | 264 | ||
265 | /* | ||
266 | * Determine with what IFS priority this frame should be send. | ||
267 | * Set ifs to IFS_SIFS when the this is not the first fragment, | ||
268 | * or this fragment came after RTS/CTS. | ||
269 | */ | ||
270 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) | ||
271 | txdesc->u.plcp.ifs = IFS_BACKOFF; | ||
272 | else | ||
273 | txdesc->u.plcp.ifs = IFS_SIFS; | ||
274 | |||
263 | /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ | 275 | /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ |
264 | data_length = entry->skb->len + 4; | 276 | data_length = entry->skb->len + 4; |
265 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb); | 277 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb); |
@@ -268,12 +280,12 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | |||
268 | * PLCP setup | 280 | * PLCP setup |
269 | * Length calculation depends on OFDM/CCK rate. | 281 | * Length calculation depends on OFDM/CCK rate. |
270 | */ | 282 | */ |
271 | txdesc->signal = hwrate->plcp; | 283 | txdesc->u.plcp.signal = hwrate->plcp; |
272 | txdesc->service = 0x04; | 284 | txdesc->u.plcp.service = 0x04; |
273 | 285 | ||
274 | if (hwrate->flags & DEV_RATE_OFDM) { | 286 | if (hwrate->flags & DEV_RATE_OFDM) { |
275 | txdesc->length_high = (data_length >> 6) & 0x3f; | 287 | txdesc->u.plcp.length_high = (data_length >> 6) & 0x3f; |
276 | txdesc->length_low = data_length & 0x3f; | 288 | txdesc->u.plcp.length_low = data_length & 0x3f; |
277 | } else { | 289 | } else { |
278 | /* | 290 | /* |
279 | * Convert length to microseconds. | 291 | * Convert length to microseconds. |
@@ -288,18 +300,18 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | |||
288 | * Check if we need to set the Length Extension | 300 | * Check if we need to set the Length Extension |
289 | */ | 301 | */ |
290 | if (hwrate->bitrate == 110 && residual <= 30) | 302 | if (hwrate->bitrate == 110 && residual <= 30) |
291 | txdesc->service |= 0x80; | 303 | txdesc->u.plcp.service |= 0x80; |
292 | } | 304 | } |
293 | 305 | ||
294 | txdesc->length_high = (duration >> 8) & 0xff; | 306 | txdesc->u.plcp.length_high = (duration >> 8) & 0xff; |
295 | txdesc->length_low = duration & 0xff; | 307 | txdesc->u.plcp.length_low = duration & 0xff; |
296 | 308 | ||
297 | /* | 309 | /* |
298 | * When preamble is enabled we should set the | 310 | * When preamble is enabled we should set the |
299 | * preamble bit for the signal. | 311 | * preamble bit for the signal. |
300 | */ | 312 | */ |
301 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | 313 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
302 | txdesc->signal |= 0x08; | 314 | txdesc->u.plcp.signal |= 0x08; |
303 | } | 315 | } |
304 | } | 316 | } |
305 | 317 | ||
@@ -309,9 +321,9 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
309 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 321 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
310 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 322 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
311 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 323 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; |
312 | struct ieee80211_rate *rate = | 324 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; |
313 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); | 325 | struct ieee80211_rate *rate; |
314 | const struct rt2x00_rate *hwrate; | 326 | const struct rt2x00_rate *hwrate = NULL; |
315 | 327 | ||
316 | memset(txdesc, 0, sizeof(*txdesc)); | 328 | memset(txdesc, 0, sizeof(*txdesc)); |
317 | 329 | ||
@@ -371,33 +383,36 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
371 | ieee80211_is_probe_resp(hdr->frame_control)) | 383 | ieee80211_is_probe_resp(hdr->frame_control)) |
372 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); | 384 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); |
373 | 385 | ||
374 | /* | ||
375 | * Determine with what IFS priority this frame should be send. | ||
376 | * Set ifs to IFS_SIFS when the this is not the first fragment, | ||
377 | * or this fragment came after RTS/CTS. | ||
378 | */ | ||
379 | if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) && | 386 | if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) && |
380 | !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { | 387 | !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) |
381 | __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); | 388 | __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); |
382 | txdesc->ifs = IFS_BACKOFF; | ||
383 | } else | ||
384 | txdesc->ifs = IFS_SIFS; | ||
385 | 389 | ||
386 | /* | 390 | /* |
387 | * Determine rate modulation. | 391 | * Determine rate modulation. |
388 | */ | 392 | */ |
389 | hwrate = rt2x00_get_rate(rate->hw_value); | 393 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) |
390 | txdesc->rate_mode = RATE_MODE_CCK; | 394 | txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; |
391 | if (hwrate->flags & DEV_RATE_OFDM) | 395 | else if (txrate->flags & IEEE80211_TX_RC_MCS) |
392 | txdesc->rate_mode = RATE_MODE_OFDM; | 396 | txdesc->rate_mode = RATE_MODE_HT_MIX; |
397 | else { | ||
398 | rate = ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); | ||
399 | hwrate = rt2x00_get_rate(rate->hw_value); | ||
400 | if (hwrate->flags & DEV_RATE_OFDM) | ||
401 | txdesc->rate_mode = RATE_MODE_OFDM; | ||
402 | else | ||
403 | txdesc->rate_mode = RATE_MODE_CCK; | ||
404 | } | ||
393 | 405 | ||
394 | /* | 406 | /* |
395 | * Apply TX descriptor handling by components | 407 | * Apply TX descriptor handling by components |
396 | */ | 408 | */ |
397 | rt2x00crypto_create_tx_descriptor(entry, txdesc); | 409 | rt2x00crypto_create_tx_descriptor(entry, txdesc); |
398 | rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate); | ||
399 | rt2x00queue_create_tx_descriptor_seq(entry, txdesc); | 410 | rt2x00queue_create_tx_descriptor_seq(entry, txdesc); |
400 | rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); | 411 | |
412 | if (test_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags)) | ||
413 | rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate); | ||
414 | else | ||
415 | rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); | ||
401 | } | 416 | } |
402 | 417 | ||
403 | static int rt2x00queue_write_tx_data(struct queue_entry *entry, | 418 | static int rt2x00queue_write_tx_data(struct queue_entry *entry, |
@@ -690,29 +705,6 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, | |||
690 | } | 705 | } |
691 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); | 706 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); |
692 | 707 | ||
693 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | ||
694 | const enum data_queue_qid queue) | ||
695 | { | ||
696 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | ||
697 | |||
698 | if (queue == QID_RX) | ||
699 | return rt2x00dev->rx; | ||
700 | |||
701 | if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) | ||
702 | return &rt2x00dev->tx[queue]; | ||
703 | |||
704 | if (!rt2x00dev->bcn) | ||
705 | return NULL; | ||
706 | |||
707 | if (queue == QID_BEACON) | ||
708 | return &rt2x00dev->bcn[0]; | ||
709 | else if (queue == QID_ATIM && atim) | ||
710 | return &rt2x00dev->bcn[1]; | ||
711 | |||
712 | return NULL; | ||
713 | } | ||
714 | EXPORT_SYMBOL_GPL(rt2x00queue_get_queue); | ||
715 | |||
716 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | 708 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, |
717 | enum queue_index index) | 709 | enum queue_index index) |
718 | { | 710 | { |
@@ -1088,7 +1080,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | |||
1088 | goto exit; | 1080 | goto exit; |
1089 | 1081 | ||
1090 | if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { | 1082 | if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { |
1091 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], | 1083 | status = rt2x00queue_alloc_entries(rt2x00dev->atim, |
1092 | rt2x00dev->ops->atim); | 1084 | rt2x00dev->ops->atim); |
1093 | if (status) | 1085 | if (status) |
1094 | goto exit; | 1086 | goto exit; |
@@ -1162,6 +1154,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
1162 | rt2x00dev->rx = queue; | 1154 | rt2x00dev->rx = queue; |
1163 | rt2x00dev->tx = &queue[1]; | 1155 | rt2x00dev->tx = &queue[1]; |
1164 | rt2x00dev->bcn = &queue[1 + rt2x00dev->ops->tx_queues]; | 1156 | rt2x00dev->bcn = &queue[1 + rt2x00dev->ops->tx_queues]; |
1157 | rt2x00dev->atim = req_atim ? &queue[2 + rt2x00dev->ops->tx_queues] : NULL; | ||
1165 | 1158 | ||
1166 | /* | 1159 | /* |
1167 | * Initialize queue parameters. | 1160 | * Initialize queue parameters. |
@@ -1178,9 +1171,9 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
1178 | tx_queue_for_each(rt2x00dev, queue) | 1171 | tx_queue_for_each(rt2x00dev, queue) |
1179 | rt2x00queue_init(rt2x00dev, queue, qid++); | 1172 | rt2x00queue_init(rt2x00dev, queue, qid++); |
1180 | 1173 | ||
1181 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_BEACON); | 1174 | rt2x00queue_init(rt2x00dev, rt2x00dev->bcn, QID_BEACON); |
1182 | if (req_atim) | 1175 | if (req_atim) |
1183 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_ATIM); | 1176 | rt2x00queue_init(rt2x00dev, rt2x00dev->atim, QID_ATIM); |
1184 | 1177 | ||
1185 | return 0; | 1178 | return 0; |
1186 | } | 1179 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index fab8e2687f29..0c8b0c699679 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -305,20 +305,27 @@ struct txentry_desc { | |||
305 | u16 length; | 305 | u16 length; |
306 | u16 header_length; | 306 | u16 header_length; |
307 | 307 | ||
308 | u16 length_high; | 308 | union { |
309 | u16 length_low; | 309 | struct { |
310 | u16 signal; | 310 | u16 length_high; |
311 | u16 service; | 311 | u16 length_low; |
312 | 312 | u16 signal; | |
313 | u16 mcs; | 313 | u16 service; |
314 | u16 stbc; | 314 | enum ifs ifs; |
315 | u16 ba_size; | 315 | } plcp; |
316 | u16 rate_mode; | 316 | |
317 | u16 mpdu_density; | 317 | struct { |
318 | u16 mcs; | ||
319 | u8 stbc; | ||
320 | u8 ba_size; | ||
321 | u8 mpdu_density; | ||
322 | enum txop txop; | ||
323 | } ht; | ||
324 | } u; | ||
325 | |||
326 | enum rate_modulation rate_mode; | ||
318 | 327 | ||
319 | short retry_limit; | 328 | short retry_limit; |
320 | short ifs; | ||
321 | short txop; | ||
322 | 329 | ||
323 | enum cipher cipher; | 330 | enum cipher cipher; |
324 | u16 key_idx; | 331 | u16 key_idx; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 927a4a3e0eeb..77e8113b91e1 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1898,10 +1898,12 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, | |||
1898 | rt2x00_desc_write(txd, 1, word); | 1898 | rt2x00_desc_write(txd, 1, word); |
1899 | 1899 | ||
1900 | rt2x00_desc_read(txd, 2, &word); | 1900 | rt2x00_desc_read(txd, 2, &word); |
1901 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); | 1901 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); |
1902 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); | 1902 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); |
1903 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); | 1903 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, |
1904 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); | 1904 | txdesc->u.plcp.length_low); |
1905 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, | ||
1906 | txdesc->u.plcp.length_high); | ||
1905 | rt2x00_desc_write(txd, 2, word); | 1907 | rt2x00_desc_write(txd, 2, word); |
1906 | 1908 | ||
1907 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | 1909 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { |
@@ -1946,7 +1948,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, | |||
1946 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1948 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1947 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1949 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1948 | (txdesc->rate_mode == RATE_MODE_OFDM)); | 1950 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1949 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1951 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); |
1950 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1952 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1951 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1953 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1952 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, | 1954 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, |
@@ -2190,7 +2192,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
2190 | * queue identication number. | 2192 | * queue identication number. |
2191 | */ | 2193 | */ |
2192 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); | 2194 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); |
2193 | queue = rt2x00queue_get_queue(rt2x00dev, type); | 2195 | queue = rt2x00queue_get_tx_queue(rt2x00dev, type); |
2194 | if (unlikely(!queue)) | 2196 | if (unlikely(!queue)) |
2195 | continue; | 2197 | continue; |
2196 | 2198 | ||
@@ -2261,39 +2263,37 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) | |||
2261 | static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | 2263 | static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, |
2262 | struct rt2x00_field32 irq_field) | 2264 | struct rt2x00_field32 irq_field) |
2263 | { | 2265 | { |
2264 | unsigned long flags; | ||
2265 | u32 reg; | 2266 | u32 reg; |
2266 | 2267 | ||
2267 | /* | 2268 | /* |
2268 | * Enable a single interrupt. The interrupt mask register | 2269 | * Enable a single interrupt. The interrupt mask register |
2269 | * access needs locking. | 2270 | * access needs locking. |
2270 | */ | 2271 | */ |
2271 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 2272 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
2272 | 2273 | ||
2273 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 2274 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); |
2274 | rt2x00_set_field32(®, irq_field, 0); | 2275 | rt2x00_set_field32(®, irq_field, 0); |
2275 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 2276 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); |
2276 | 2277 | ||
2277 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 2278 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
2278 | } | 2279 | } |
2279 | 2280 | ||
2280 | static void rt61pci_enable_mcu_interrupt(struct rt2x00_dev *rt2x00dev, | 2281 | static void rt61pci_enable_mcu_interrupt(struct rt2x00_dev *rt2x00dev, |
2281 | struct rt2x00_field32 irq_field) | 2282 | struct rt2x00_field32 irq_field) |
2282 | { | 2283 | { |
2283 | unsigned long flags; | ||
2284 | u32 reg; | 2284 | u32 reg; |
2285 | 2285 | ||
2286 | /* | 2286 | /* |
2287 | * Enable a single MCU interrupt. The interrupt mask register | 2287 | * Enable a single MCU interrupt. The interrupt mask register |
2288 | * access needs locking. | 2288 | * access needs locking. |
2289 | */ | 2289 | */ |
2290 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 2290 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
2291 | 2291 | ||
2292 | rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); | 2292 | rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); |
2293 | rt2x00_set_field32(®, irq_field, 0); | 2293 | rt2x00_set_field32(®, irq_field, 0); |
2294 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | 2294 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); |
2295 | 2295 | ||
2296 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 2296 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
2297 | } | 2297 | } |
2298 | 2298 | ||
2299 | static void rt61pci_txstatus_tasklet(unsigned long data) | 2299 | static void rt61pci_txstatus_tasklet(unsigned long data) |
@@ -2331,7 +2331,6 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | |||
2331 | struct rt2x00_dev *rt2x00dev = dev_instance; | 2331 | struct rt2x00_dev *rt2x00dev = dev_instance; |
2332 | u32 reg_mcu, mask_mcu; | 2332 | u32 reg_mcu, mask_mcu; |
2333 | u32 reg, mask; | 2333 | u32 reg, mask; |
2334 | unsigned long flags; | ||
2335 | 2334 | ||
2336 | /* | 2335 | /* |
2337 | * Get the interrupt sources & saved to local variable. | 2336 | * Get the interrupt sources & saved to local variable. |
@@ -2376,7 +2375,7 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | |||
2376 | * Disable all interrupts for which a tasklet was scheduled right now, | 2375 | * Disable all interrupts for which a tasklet was scheduled right now, |
2377 | * the tasklet will reenable the appropriate interrupts. | 2376 | * the tasklet will reenable the appropriate interrupts. |
2378 | */ | 2377 | */ |
2379 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 2378 | spin_lock(&rt2x00dev->irqmask_lock); |
2380 | 2379 | ||
2381 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 2380 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); |
2382 | reg |= mask; | 2381 | reg |= mask; |
@@ -2386,7 +2385,7 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | |||
2386 | reg |= mask_mcu; | 2385 | reg |= mask_mcu; |
2387 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | 2386 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); |
2388 | 2387 | ||
2389 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 2388 | spin_unlock(&rt2x00dev->irqmask_lock); |
2390 | 2389 | ||
2391 | return IRQ_HANDLED; | 2390 | return IRQ_HANDLED; |
2392 | } | 2391 | } |
@@ -2917,7 +2916,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2917 | if (queue_idx >= 4) | 2916 | if (queue_idx >= 4) |
2918 | return 0; | 2917 | return 0; |
2919 | 2918 | ||
2920 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 2919 | queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
2921 | 2920 | ||
2922 | /* Update WMM TXOP register */ | 2921 | /* Update WMM TXOP register */ |
2923 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); | 2922 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6e9981a1dd7f..02f1148c577e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1474,7 +1474,7 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, | |||
1474 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1474 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1475 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1475 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1476 | (txdesc->rate_mode == RATE_MODE_OFDM)); | 1476 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1477 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1477 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); |
1478 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1478 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1479 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1479 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1480 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, | 1480 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, |
@@ -1499,10 +1499,12 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, | |||
1499 | rt2x00_desc_write(txd, 1, word); | 1499 | rt2x00_desc_write(txd, 1, word); |
1500 | 1500 | ||
1501 | rt2x00_desc_read(txd, 2, &word); | 1501 | rt2x00_desc_read(txd, 2, &word); |
1502 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); | 1502 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); |
1503 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); | 1503 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); |
1504 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); | 1504 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, |
1505 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); | 1505 | txdesc->u.plcp.length_low); |
1506 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, | ||
1507 | txdesc->u.plcp.length_high); | ||
1506 | rt2x00_desc_write(txd, 2, word); | 1508 | rt2x00_desc_write(txd, 2, word); |
1507 | 1509 | ||
1508 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | 1510 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { |
@@ -2247,7 +2249,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2247 | if (queue_idx >= 4) | 2249 | if (queue_idx >= 4) |
2248 | return 0; | 2250 | return 0; |
2249 | 2251 | ||
2250 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 2252 | queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
2251 | 2253 | ||
2252 | /* Update WMM TXOP register */ | 2254 | /* Update WMM TXOP register */ |
2253 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); | 2255 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index c5a5e788f25f..1e0be14d10d4 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -869,23 +869,35 @@ static void rtl8187_work(struct work_struct *work) | |||
869 | /* The RTL8187 returns the retry count through register 0xFFFA. In | 869 | /* The RTL8187 returns the retry count through register 0xFFFA. In |
870 | * addition, it appears to be a cumulative retry count, not the | 870 | * addition, it appears to be a cumulative retry count, not the |
871 | * value for the current TX packet. When multiple TX entries are | 871 | * value for the current TX packet. When multiple TX entries are |
872 | * queued, the retry count will be valid for the last one in the queue. | 872 | * waiting in the queue, the retry count will be the total for all. |
873 | * The "error" should not matter for purposes of rate setting. */ | 873 | * The "error" may matter for purposes of rate setting, but there is |
874 | * no other choice with this hardware. | ||
875 | */ | ||
874 | struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, | 876 | struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, |
875 | work.work); | 877 | work.work); |
876 | struct ieee80211_tx_info *info; | 878 | struct ieee80211_tx_info *info; |
877 | struct ieee80211_hw *dev = priv->dev; | 879 | struct ieee80211_hw *dev = priv->dev; |
878 | static u16 retry; | 880 | static u16 retry; |
879 | u16 tmp; | 881 | u16 tmp; |
882 | u16 avg_retry; | ||
883 | int length; | ||
880 | 884 | ||
881 | mutex_lock(&priv->conf_mutex); | 885 | mutex_lock(&priv->conf_mutex); |
882 | tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); | 886 | tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); |
887 | length = skb_queue_len(&priv->b_tx_status.queue); | ||
888 | if (unlikely(!length)) | ||
889 | length = 1; | ||
890 | if (unlikely(tmp < retry)) | ||
891 | tmp = retry; | ||
892 | avg_retry = (tmp - retry) / length; | ||
883 | while (skb_queue_len(&priv->b_tx_status.queue) > 0) { | 893 | while (skb_queue_len(&priv->b_tx_status.queue) > 0) { |
884 | struct sk_buff *old_skb; | 894 | struct sk_buff *old_skb; |
885 | 895 | ||
886 | old_skb = skb_dequeue(&priv->b_tx_status.queue); | 896 | old_skb = skb_dequeue(&priv->b_tx_status.queue); |
887 | info = IEEE80211_SKB_CB(old_skb); | 897 | info = IEEE80211_SKB_CB(old_skb); |
888 | info->status.rates[0].count = tmp - retry + 1; | 898 | info->status.rates[0].count = avg_retry + 1; |
899 | if (info->status.rates[0].count > RETRY_COUNT) | ||
900 | info->flags &= ~IEEE80211_TX_STAT_ACK; | ||
889 | ieee80211_tx_status_irqsafe(dev, old_skb); | 901 | ieee80211_tx_status_irqsafe(dev, old_skb); |
890 | } | 902 | } |
891 | retry = tmp; | 903 | retry = tmp; |
@@ -931,8 +943,8 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
931 | rtl818x_iowrite32(priv, &priv->map->TX_CONF, | 943 | rtl818x_iowrite32(priv, &priv->map->TX_CONF, |
932 | RTL818X_TX_CONF_HW_SEQNUM | | 944 | RTL818X_TX_CONF_HW_SEQNUM | |
933 | RTL818X_TX_CONF_DISREQQSIZE | | 945 | RTL818X_TX_CONF_DISREQQSIZE | |
934 | (7 << 8 /* short retry limit */) | | 946 | (RETRY_COUNT << 8 /* short retry limit */) | |
935 | (7 << 0 /* long retry limit */) | | 947 | (RETRY_COUNT << 0 /* long retry limit */) | |
936 | (7 << 21 /* MAX TX DMA */)); | 948 | (7 << 21 /* MAX TX DMA */)); |
937 | rtl8187_init_urbs(dev); | 949 | rtl8187_init_urbs(dev); |
938 | rtl8187b_init_status_urb(dev); | 950 | rtl8187b_init_status_urb(dev); |
@@ -1376,6 +1388,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1376 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1388 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1377 | IEEE80211_HW_SIGNAL_DBM | | 1389 | IEEE80211_HW_SIGNAL_DBM | |
1378 | IEEE80211_HW_RX_INCLUDES_FCS; | 1390 | IEEE80211_HW_RX_INCLUDES_FCS; |
1391 | /* Initialize rate-control variables */ | ||
1392 | dev->max_rates = 1; | ||
1393 | dev->max_rate_tries = RETRY_COUNT; | ||
1379 | 1394 | ||
1380 | eeprom.data = dev; | 1395 | eeprom.data = dev; |
1381 | eeprom.register_read = rtl8187_eeprom_register_read; | 1396 | eeprom.register_read = rtl8187_eeprom_register_read; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index 0d7b1423f77b..f1cc90751dbf 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | |||
@@ -35,6 +35,8 @@ | |||
35 | #define RFKILL_MASK_8187_89_97 0x2 | 35 | #define RFKILL_MASK_8187_89_97 0x2 |
36 | #define RFKILL_MASK_8198 0x4 | 36 | #define RFKILL_MASK_8198 0x4 |
37 | 37 | ||
38 | #define RETRY_COUNT 7 | ||
39 | |||
38 | struct rtl8187_rx_info { | 40 | struct rtl8187_rx_info { |
39 | struct urb *urb; | 41 | struct urb *urb; |
40 | struct ieee80211_hw *dev; | 42 | struct ieee80211_hw *dev; |
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index 9192fd583413..ec9393f24799 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile | |||
@@ -7,15 +7,18 @@ rtlwifi-objs := \ | |||
7 | efuse.o \ | 7 | efuse.o \ |
8 | ps.o \ | 8 | ps.o \ |
9 | rc.o \ | 9 | rc.o \ |
10 | regd.o \ | 10 | regd.o |
11 | usb.o | ||
12 | 11 | ||
13 | rtl8192c_common-objs += \ | 12 | rtl8192c_common-objs += \ |
14 | 13 | ||
15 | ifeq ($(CONFIG_PCI),y) | 14 | ifneq ($(CONFIG_PCI),) |
16 | rtlwifi-objs += pci.o | 15 | rtlwifi-objs += pci.o |
17 | endif | 16 | endif |
18 | 17 | ||
18 | ifneq ($(CONFIG_USB),) | ||
19 | rtlwifi-objs += usb.o | ||
20 | endif | ||
21 | |||
19 | obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ | 22 | obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ |
20 | obj-$(CONFIG_RTL8192CE) += rtl8192ce/ | 23 | obj-$(CONFIG_RTL8192CE) += rtl8192ce/ |
21 | obj-$(CONFIG_RTL8192CU) += rtl8192cu/ | 24 | obj-$(CONFIG_RTL8192CU) += rtl8192cu/ |
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h index 184628027213..1417b1445c3d 100644 --- a/drivers/net/wireless/wl1251/wl12xx_80211.h +++ b/drivers/net/wireless/wl1251/wl12xx_80211.h | |||
@@ -54,7 +54,6 @@ | |||
54 | 54 | ||
55 | /* This really should be 8, but not for our firmware */ | 55 | /* This really should be 8, but not for our firmware */ |
56 | #define MAX_SUPPORTED_RATES 32 | 56 | #define MAX_SUPPORTED_RATES 32 |
57 | #define COUNTRY_STRING_LEN 3 | ||
58 | #define MAX_COUNTRY_TRIPLETS 32 | 57 | #define MAX_COUNTRY_TRIPLETS 32 |
59 | 58 | ||
60 | /* Headers */ | 59 | /* Headers */ |
@@ -98,7 +97,7 @@ struct country_triplet { | |||
98 | 97 | ||
99 | struct wl12xx_ie_country { | 98 | struct wl12xx_ie_country { |
100 | struct wl12xx_ie_header header; | 99 | struct wl12xx_ie_header header; |
101 | u8 country_string[COUNTRY_STRING_LEN]; | 100 | u8 country_string[IEEE80211_COUNTRY_STRING_LEN]; |
102 | struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; | 101 | struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; |
103 | } __packed; | 102 | } __packed; |
104 | 103 | ||
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 3badc6bb7866..a3db755ceeda 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c | |||
@@ -1361,7 +1361,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl, | |||
1361 | acx->ht_protection = | 1361 | acx->ht_protection = |
1362 | (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); | 1362 | (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); |
1363 | acx->rifs_mode = 0; | 1363 | acx->rifs_mode = 0; |
1364 | acx->gf_protection = 0; | 1364 | acx->gf_protection = |
1365 | !!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
1365 | acx->ht_tx_burst_limit = 0; | 1366 | acx->ht_tx_burst_limit = 0; |
1366 | acx->dual_cts_protection = 0; | 1367 | acx->dual_cts_protection = 0; |
1367 | 1368 | ||
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 1ffbad67d2d8..6934dffd5174 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c | |||
@@ -488,6 +488,9 @@ static void wl1271_boot_hw_version(struct wl1271 *wl) | |||
488 | fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; | 488 | fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; |
489 | 489 | ||
490 | wl->hw_pg_ver = (s8)fuse; | 490 | wl->hw_pg_ver = (s8)fuse; |
491 | |||
492 | if (((wl->hw_pg_ver & PG_MAJOR_VER_MASK) >> PG_MAJOR_VER_OFFSET) < 3) | ||
493 | wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; | ||
491 | } | 494 | } |
492 | 495 | ||
493 | /* uploads NVS and firmware */ | 496 | /* uploads NVS and firmware */ |
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h index d67dcffa31eb..17229b86fc71 100644 --- a/drivers/net/wireless/wl12xx/boot.h +++ b/drivers/net/wireless/wl12xx/boot.h | |||
@@ -59,6 +59,11 @@ struct wl1271_static_data { | |||
59 | #define PG_VER_MASK 0x3c | 59 | #define PG_VER_MASK 0x3c |
60 | #define PG_VER_OFFSET 2 | 60 | #define PG_VER_OFFSET 2 |
61 | 61 | ||
62 | #define PG_MAJOR_VER_MASK 0x3 | ||
63 | #define PG_MAJOR_VER_OFFSET 0x0 | ||
64 | #define PG_MINOR_VER_MASK 0xc | ||
65 | #define PG_MINOR_VER_OFFSET 0x2 | ||
66 | |||
62 | #define CMD_MBOX_ADDRESS 0x407B4 | 67 | #define CMD_MBOX_ADDRESS 0x407B4 |
63 | 68 | ||
64 | #define POLARITY_LOW BIT(1) | 69 | #define POLARITY_LOW BIT(1) |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 97ffd7aa57a8..f0aa7ab97bf7 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -63,6 +63,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, | |||
63 | cmd->status = 0; | 63 | cmd->status = 0; |
64 | 64 | ||
65 | WARN_ON(len % 4 != 0); | 65 | WARN_ON(len % 4 != 0); |
66 | WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags)); | ||
66 | 67 | ||
67 | wl1271_write(wl, wl->cmd_box_addr, buf, len, false); | 68 | wl1271_write(wl, wl->cmd_box_addr, buf, len, false); |
68 | 69 | ||
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index bebfa28a171a..8e75b09723b9 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c | |||
@@ -99,7 +99,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl) | |||
99 | 99 | ||
100 | mutex_lock(&wl->mutex); | 100 | mutex_lock(&wl->mutex); |
101 | 101 | ||
102 | ret = wl1271_ps_elp_wakeup(wl, false); | 102 | ret = wl1271_ps_elp_wakeup(wl); |
103 | if (ret < 0) | 103 | if (ret < 0) |
104 | goto out; | 104 | goto out; |
105 | 105 | ||
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index 844b32b170bb..c1aac8292089 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h | |||
@@ -168,5 +168,6 @@ void wl1271_unregister_hw(struct wl1271 *wl); | |||
168 | int wl1271_init_ieee80211(struct wl1271 *wl); | 168 | int wl1271_init_ieee80211(struct wl1271 *wl); |
169 | struct ieee80211_hw *wl1271_alloc_hw(void); | 169 | struct ieee80211_hw *wl1271_alloc_hw(void); |
170 | int wl1271_free_hw(struct wl1271 *wl); | 170 | int wl1271_free_hw(struct wl1271 *wl); |
171 | irqreturn_t wl1271_irq(int irq, void *data); | ||
171 | 172 | ||
172 | #endif | 173 | #endif |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 947491a1d9cc..8b3c8d196b03 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -304,7 +304,7 @@ static struct conf_drv_settings default_conf = { | |||
304 | .rx_block_num = 70, | 304 | .rx_block_num = 70, |
305 | .tx_min_block_num = 40, | 305 | .tx_min_block_num = 40, |
306 | .dynamic_memory = 0, | 306 | .dynamic_memory = 0, |
307 | .min_req_tx_blocks = 104, | 307 | .min_req_tx_blocks = 100, |
308 | .min_req_rx_blocks = 22, | 308 | .min_req_rx_blocks = 22, |
309 | .tx_min = 27, | 309 | .tx_min = 27, |
310 | } | 310 | } |
@@ -374,7 +374,7 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | |||
374 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 374 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) |
375 | goto out; | 375 | goto out; |
376 | 376 | ||
377 | ret = wl1271_ps_elp_wakeup(wl, false); | 377 | ret = wl1271_ps_elp_wakeup(wl); |
378 | if (ret < 0) | 378 | if (ret < 0) |
379 | goto out; | 379 | goto out; |
380 | 380 | ||
@@ -635,16 +635,44 @@ static void wl1271_fw_status(struct wl1271 *wl, | |||
635 | (s64)le32_to_cpu(status->fw_localtime); | 635 | (s64)le32_to_cpu(status->fw_localtime); |
636 | } | 636 | } |
637 | 637 | ||
638 | #define WL1271_IRQ_MAX_LOOPS 10 | 638 | static void wl1271_flush_deferred_work(struct wl1271 *wl) |
639 | { | ||
640 | struct sk_buff *skb; | ||
641 | |||
642 | /* Pass all received frames to the network stack */ | ||
643 | while ((skb = skb_dequeue(&wl->deferred_rx_queue))) | ||
644 | ieee80211_rx_ni(wl->hw, skb); | ||
639 | 645 | ||
640 | static void wl1271_irq_work(struct work_struct *work) | 646 | /* Return sent skbs to the network stack */ |
647 | while ((skb = skb_dequeue(&wl->deferred_tx_queue))) | ||
648 | ieee80211_tx_status(wl->hw, skb); | ||
649 | } | ||
650 | |||
651 | static void wl1271_netstack_work(struct work_struct *work) | ||
652 | { | ||
653 | struct wl1271 *wl = | ||
654 | container_of(work, struct wl1271, netstack_work); | ||
655 | |||
656 | do { | ||
657 | wl1271_flush_deferred_work(wl); | ||
658 | } while (skb_queue_len(&wl->deferred_rx_queue)); | ||
659 | } | ||
660 | |||
661 | #define WL1271_IRQ_MAX_LOOPS 256 | ||
662 | |||
663 | irqreturn_t wl1271_irq(int irq, void *cookie) | ||
641 | { | 664 | { |
642 | int ret; | 665 | int ret; |
643 | u32 intr; | 666 | u32 intr; |
644 | int loopcount = WL1271_IRQ_MAX_LOOPS; | 667 | int loopcount = WL1271_IRQ_MAX_LOOPS; |
668 | struct wl1271 *wl = (struct wl1271 *)cookie; | ||
669 | bool done = false; | ||
670 | unsigned int defer_count; | ||
645 | unsigned long flags; | 671 | unsigned long flags; |
646 | struct wl1271 *wl = | 672 | |
647 | container_of(work, struct wl1271, irq_work); | 673 | /* TX might be handled here, avoid redundant work */ |
674 | set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); | ||
675 | cancel_work_sync(&wl->tx_work); | ||
648 | 676 | ||
649 | mutex_lock(&wl->mutex); | 677 | mutex_lock(&wl->mutex); |
650 | 678 | ||
@@ -653,26 +681,27 @@ static void wl1271_irq_work(struct work_struct *work) | |||
653 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 681 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
654 | goto out; | 682 | goto out; |
655 | 683 | ||
656 | ret = wl1271_ps_elp_wakeup(wl, true); | 684 | ret = wl1271_ps_elp_wakeup(wl); |
657 | if (ret < 0) | 685 | if (ret < 0) |
658 | goto out; | 686 | goto out; |
659 | 687 | ||
660 | spin_lock_irqsave(&wl->wl_lock, flags); | 688 | while (!done && loopcount--) { |
661 | while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) { | 689 | /* |
662 | clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | 690 | * In order to avoid a race with the hardirq, clear the flag |
663 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 691 | * before acknowledging the chip. Since the mutex is held, |
664 | loopcount--; | 692 | * wl1271_ps_elp_wakeup cannot be called concurrently. |
693 | */ | ||
694 | clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
695 | smp_mb__after_clear_bit(); | ||
665 | 696 | ||
666 | wl1271_fw_status(wl, wl->fw_status); | 697 | wl1271_fw_status(wl, wl->fw_status); |
667 | intr = le32_to_cpu(wl->fw_status->common.intr); | 698 | intr = le32_to_cpu(wl->fw_status->common.intr); |
699 | intr &= WL1271_INTR_MASK; | ||
668 | if (!intr) { | 700 | if (!intr) { |
669 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); | 701 | done = true; |
670 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
671 | continue; | 702 | continue; |
672 | } | 703 | } |
673 | 704 | ||
674 | intr &= WL1271_INTR_MASK; | ||
675 | |||
676 | if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { | 705 | if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { |
677 | wl1271_error("watchdog interrupt received! " | 706 | wl1271_error("watchdog interrupt received! " |
678 | "starting recovery."); | 707 | "starting recovery."); |
@@ -682,25 +711,35 @@ static void wl1271_irq_work(struct work_struct *work) | |||
682 | goto out; | 711 | goto out; |
683 | } | 712 | } |
684 | 713 | ||
685 | if (intr & WL1271_ACX_INTR_DATA) { | 714 | if (likely(intr & WL1271_ACX_INTR_DATA)) { |
686 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); | 715 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); |
687 | 716 | ||
688 | /* check for tx results */ | 717 | wl1271_rx(wl, &wl->fw_status->common); |
689 | if (wl->fw_status->common.tx_results_counter != | ||
690 | (wl->tx_results_count & 0xff)) | ||
691 | wl1271_tx_complete(wl); | ||
692 | 718 | ||
693 | /* Check if any tx blocks were freed */ | 719 | /* Check if any tx blocks were freed */ |
720 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
694 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && | 721 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && |
695 | wl->tx_queue_count) { | 722 | wl->tx_queue_count) { |
723 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
696 | /* | 724 | /* |
697 | * In order to avoid starvation of the TX path, | 725 | * In order to avoid starvation of the TX path, |
698 | * call the work function directly. | 726 | * call the work function directly. |
699 | */ | 727 | */ |
700 | wl1271_tx_work_locked(wl); | 728 | wl1271_tx_work_locked(wl); |
729 | } else { | ||
730 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
701 | } | 731 | } |
702 | 732 | ||
703 | wl1271_rx(wl, &wl->fw_status->common); | 733 | /* check for tx results */ |
734 | if (wl->fw_status->common.tx_results_counter != | ||
735 | (wl->tx_results_count & 0xff)) | ||
736 | wl1271_tx_complete(wl); | ||
737 | |||
738 | /* Make sure the deferred queues don't get too long */ | ||
739 | defer_count = skb_queue_len(&wl->deferred_tx_queue) + | ||
740 | skb_queue_len(&wl->deferred_rx_queue); | ||
741 | if (defer_count > WL1271_DEFERRED_QUEUE_LIMIT) | ||
742 | wl1271_flush_deferred_work(wl); | ||
704 | } | 743 | } |
705 | 744 | ||
706 | if (intr & WL1271_ACX_INTR_EVENT_A) { | 745 | if (intr & WL1271_ACX_INTR_EVENT_A) { |
@@ -719,21 +758,24 @@ static void wl1271_irq_work(struct work_struct *work) | |||
719 | 758 | ||
720 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) | 759 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) |
721 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); | 760 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); |
722 | |||
723 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
724 | } | 761 | } |
725 | 762 | ||
726 | if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags)) | ||
727 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
728 | else | ||
729 | clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
730 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
731 | |||
732 | wl1271_ps_elp_sleep(wl); | 763 | wl1271_ps_elp_sleep(wl); |
733 | 764 | ||
734 | out: | 765 | out: |
766 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
767 | /* In case TX was not handled here, queue TX work */ | ||
768 | clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); | ||
769 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && | ||
770 | wl->tx_queue_count) | ||
771 | ieee80211_queue_work(wl->hw, &wl->tx_work); | ||
772 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
773 | |||
735 | mutex_unlock(&wl->mutex); | 774 | mutex_unlock(&wl->mutex); |
775 | |||
776 | return IRQ_HANDLED; | ||
736 | } | 777 | } |
778 | EXPORT_SYMBOL_GPL(wl1271_irq); | ||
737 | 779 | ||
738 | static int wl1271_fetch_firmware(struct wl1271 *wl) | 780 | static int wl1271_fetch_firmware(struct wl1271 *wl) |
739 | { | 781 | { |
@@ -974,7 +1016,6 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
974 | goto out; | 1016 | goto out; |
975 | 1017 | ||
976 | irq_disable: | 1018 | irq_disable: |
977 | wl1271_disable_interrupts(wl); | ||
978 | mutex_unlock(&wl->mutex); | 1019 | mutex_unlock(&wl->mutex); |
979 | /* Unlocking the mutex in the middle of handling is | 1020 | /* Unlocking the mutex in the middle of handling is |
980 | inherently unsafe. In this case we deem it safe to do, | 1021 | inherently unsafe. In this case we deem it safe to do, |
@@ -983,7 +1024,9 @@ irq_disable: | |||
983 | work function will not do anything.) Also, any other | 1024 | work function will not do anything.) Also, any other |
984 | possible concurrent operations will fail due to the | 1025 | possible concurrent operations will fail due to the |
985 | current state, hence the wl1271 struct should be safe. */ | 1026 | current state, hence the wl1271 struct should be safe. */ |
986 | cancel_work_sync(&wl->irq_work); | 1027 | wl1271_disable_interrupts(wl); |
1028 | wl1271_flush_deferred_work(wl); | ||
1029 | cancel_work_sync(&wl->netstack_work); | ||
987 | mutex_lock(&wl->mutex); | 1030 | mutex_lock(&wl->mutex); |
988 | power_off: | 1031 | power_off: |
989 | wl1271_power_off(wl); | 1032 | wl1271_power_off(wl); |
@@ -1010,14 +1053,15 @@ int __wl1271_plt_stop(struct wl1271 *wl) | |||
1010 | goto out; | 1053 | goto out; |
1011 | } | 1054 | } |
1012 | 1055 | ||
1013 | wl1271_disable_interrupts(wl); | ||
1014 | wl1271_power_off(wl); | 1056 | wl1271_power_off(wl); |
1015 | 1057 | ||
1016 | wl->state = WL1271_STATE_OFF; | 1058 | wl->state = WL1271_STATE_OFF; |
1017 | wl->rx_counter = 0; | 1059 | wl->rx_counter = 0; |
1018 | 1060 | ||
1019 | mutex_unlock(&wl->mutex); | 1061 | mutex_unlock(&wl->mutex); |
1020 | cancel_work_sync(&wl->irq_work); | 1062 | wl1271_disable_interrupts(wl); |
1063 | wl1271_flush_deferred_work(wl); | ||
1064 | cancel_work_sync(&wl->netstack_work); | ||
1021 | cancel_work_sync(&wl->recovery_work); | 1065 | cancel_work_sync(&wl->recovery_work); |
1022 | mutex_lock(&wl->mutex); | 1066 | mutex_lock(&wl->mutex); |
1023 | out: | 1067 | out: |
@@ -1041,7 +1085,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1041 | int q; | 1085 | int q; |
1042 | u8 hlid = 0; | 1086 | u8 hlid = 0; |
1043 | 1087 | ||
1088 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | ||
1089 | |||
1090 | if (wl->bss_type == BSS_TYPE_AP_BSS) | ||
1091 | hlid = wl1271_tx_get_hlid(skb); | ||
1092 | |||
1044 | spin_lock_irqsave(&wl->wl_lock, flags); | 1093 | spin_lock_irqsave(&wl->wl_lock, flags); |
1094 | |||
1045 | wl->tx_queue_count++; | 1095 | wl->tx_queue_count++; |
1046 | 1096 | ||
1047 | /* | 1097 | /* |
@@ -1054,12 +1104,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1054 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | 1104 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); |
1055 | } | 1105 | } |
1056 | 1106 | ||
1057 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1058 | |||
1059 | /* queue the packet */ | 1107 | /* queue the packet */ |
1060 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | ||
1061 | if (wl->bss_type == BSS_TYPE_AP_BSS) { | 1108 | if (wl->bss_type == BSS_TYPE_AP_BSS) { |
1062 | hlid = wl1271_tx_get_hlid(skb); | ||
1063 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); | 1109 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); |
1064 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); | 1110 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); |
1065 | } else { | 1111 | } else { |
@@ -1071,8 +1117,11 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1071 | * before that, the tx_work will not be initialized! | 1117 | * before that, the tx_work will not be initialized! |
1072 | */ | 1118 | */ |
1073 | 1119 | ||
1074 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) | 1120 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && |
1121 | !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags)) | ||
1075 | ieee80211_queue_work(wl->hw, &wl->tx_work); | 1122 | ieee80211_queue_work(wl->hw, &wl->tx_work); |
1123 | |||
1124 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1076 | } | 1125 | } |
1077 | 1126 | ||
1078 | static struct notifier_block wl1271_dev_notifier = { | 1127 | static struct notifier_block wl1271_dev_notifier = { |
@@ -1169,7 +1218,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, | |||
1169 | break; | 1218 | break; |
1170 | 1219 | ||
1171 | irq_disable: | 1220 | irq_disable: |
1172 | wl1271_disable_interrupts(wl); | ||
1173 | mutex_unlock(&wl->mutex); | 1221 | mutex_unlock(&wl->mutex); |
1174 | /* Unlocking the mutex in the middle of handling is | 1222 | /* Unlocking the mutex in the middle of handling is |
1175 | inherently unsafe. In this case we deem it safe to do, | 1223 | inherently unsafe. In this case we deem it safe to do, |
@@ -1178,7 +1226,9 @@ irq_disable: | |||
1178 | work function will not do anything.) Also, any other | 1226 | work function will not do anything.) Also, any other |
1179 | possible concurrent operations will fail due to the | 1227 | possible concurrent operations will fail due to the |
1180 | current state, hence the wl1271 struct should be safe. */ | 1228 | current state, hence the wl1271 struct should be safe. */ |
1181 | cancel_work_sync(&wl->irq_work); | 1229 | wl1271_disable_interrupts(wl); |
1230 | wl1271_flush_deferred_work(wl); | ||
1231 | cancel_work_sync(&wl->netstack_work); | ||
1182 | mutex_lock(&wl->mutex); | 1232 | mutex_lock(&wl->mutex); |
1183 | power_off: | 1233 | power_off: |
1184 | wl1271_power_off(wl); | 1234 | wl1271_power_off(wl); |
@@ -1244,12 +1294,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1244 | 1294 | ||
1245 | wl->state = WL1271_STATE_OFF; | 1295 | wl->state = WL1271_STATE_OFF; |
1246 | 1296 | ||
1247 | wl1271_disable_interrupts(wl); | ||
1248 | |||
1249 | mutex_unlock(&wl->mutex); | 1297 | mutex_unlock(&wl->mutex); |
1250 | 1298 | ||
1299 | wl1271_disable_interrupts(wl); | ||
1300 | wl1271_flush_deferred_work(wl); | ||
1251 | cancel_delayed_work_sync(&wl->scan_complete_work); | 1301 | cancel_delayed_work_sync(&wl->scan_complete_work); |
1252 | cancel_work_sync(&wl->irq_work); | 1302 | cancel_work_sync(&wl->netstack_work); |
1253 | cancel_work_sync(&wl->tx_work); | 1303 | cancel_work_sync(&wl->tx_work); |
1254 | cancel_delayed_work_sync(&wl->pspoll_work); | 1304 | cancel_delayed_work_sync(&wl->pspoll_work); |
1255 | cancel_delayed_work_sync(&wl->elp_work); | 1305 | cancel_delayed_work_sync(&wl->elp_work); |
@@ -1525,7 +1575,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1525 | 1575 | ||
1526 | is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); | 1576 | is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); |
1527 | 1577 | ||
1528 | ret = wl1271_ps_elp_wakeup(wl, false); | 1578 | ret = wl1271_ps_elp_wakeup(wl); |
1529 | if (ret < 0) | 1579 | if (ret < 0) |
1530 | goto out; | 1580 | goto out; |
1531 | 1581 | ||
@@ -1681,7 +1731,7 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, | |||
1681 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 1731 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
1682 | goto out; | 1732 | goto out; |
1683 | 1733 | ||
1684 | ret = wl1271_ps_elp_wakeup(wl, false); | 1734 | ret = wl1271_ps_elp_wakeup(wl); |
1685 | if (ret < 0) | 1735 | if (ret < 0) |
1686 | goto out; | 1736 | goto out; |
1687 | 1737 | ||
@@ -1910,7 +1960,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1910 | goto out_unlock; | 1960 | goto out_unlock; |
1911 | } | 1961 | } |
1912 | 1962 | ||
1913 | ret = wl1271_ps_elp_wakeup(wl, false); | 1963 | ret = wl1271_ps_elp_wakeup(wl); |
1914 | if (ret < 0) | 1964 | if (ret < 0) |
1915 | goto out_unlock; | 1965 | goto out_unlock; |
1916 | 1966 | ||
@@ -2013,7 +2063,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
2013 | goto out; | 2063 | goto out; |
2014 | } | 2064 | } |
2015 | 2065 | ||
2016 | ret = wl1271_ps_elp_wakeup(wl, false); | 2066 | ret = wl1271_ps_elp_wakeup(wl); |
2017 | if (ret < 0) | 2067 | if (ret < 0) |
2018 | goto out; | 2068 | goto out; |
2019 | 2069 | ||
@@ -2039,7 +2089,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) | |||
2039 | goto out; | 2089 | goto out; |
2040 | } | 2090 | } |
2041 | 2091 | ||
2042 | ret = wl1271_ps_elp_wakeup(wl, false); | 2092 | ret = wl1271_ps_elp_wakeup(wl); |
2043 | if (ret < 0) | 2093 | if (ret < 0) |
2044 | goto out; | 2094 | goto out; |
2045 | 2095 | ||
@@ -2067,7 +2117,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | |||
2067 | goto out; | 2117 | goto out; |
2068 | } | 2118 | } |
2069 | 2119 | ||
2070 | ret = wl1271_ps_elp_wakeup(wl, false); | 2120 | ret = wl1271_ps_elp_wakeup(wl); |
2071 | if (ret < 0) | 2121 | if (ret < 0) |
2072 | goto out; | 2122 | goto out; |
2073 | 2123 | ||
@@ -2546,7 +2596,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2546 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 2596 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
2547 | goto out; | 2597 | goto out; |
2548 | 2598 | ||
2549 | ret = wl1271_ps_elp_wakeup(wl, false); | 2599 | ret = wl1271_ps_elp_wakeup(wl); |
2550 | if (ret < 0) | 2600 | if (ret < 0) |
2551 | goto out; | 2601 | goto out; |
2552 | 2602 | ||
@@ -2601,7 +2651,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2601 | conf_tid->apsd_conf[0] = 0; | 2651 | conf_tid->apsd_conf[0] = 0; |
2602 | conf_tid->apsd_conf[1] = 0; | 2652 | conf_tid->apsd_conf[1] = 0; |
2603 | } else { | 2653 | } else { |
2604 | ret = wl1271_ps_elp_wakeup(wl, false); | 2654 | ret = wl1271_ps_elp_wakeup(wl); |
2605 | if (ret < 0) | 2655 | if (ret < 0) |
2606 | goto out; | 2656 | goto out; |
2607 | 2657 | ||
@@ -2647,7 +2697,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) | |||
2647 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 2697 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
2648 | goto out; | 2698 | goto out; |
2649 | 2699 | ||
2650 | ret = wl1271_ps_elp_wakeup(wl, false); | 2700 | ret = wl1271_ps_elp_wakeup(wl); |
2651 | if (ret < 0) | 2701 | if (ret < 0) |
2652 | goto out; | 2702 | goto out; |
2653 | 2703 | ||
@@ -2736,7 +2786,7 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw, | |||
2736 | if (ret < 0) | 2786 | if (ret < 0) |
2737 | goto out; | 2787 | goto out; |
2738 | 2788 | ||
2739 | ret = wl1271_ps_elp_wakeup(wl, false); | 2789 | ret = wl1271_ps_elp_wakeup(wl); |
2740 | if (ret < 0) | 2790 | if (ret < 0) |
2741 | goto out_free_sta; | 2791 | goto out_free_sta; |
2742 | 2792 | ||
@@ -2779,7 +2829,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw, | |||
2779 | if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) | 2829 | if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) |
2780 | goto out; | 2830 | goto out; |
2781 | 2831 | ||
2782 | ret = wl1271_ps_elp_wakeup(wl, false); | 2832 | ret = wl1271_ps_elp_wakeup(wl); |
2783 | if (ret < 0) | 2833 | if (ret < 0) |
2784 | goto out; | 2834 | goto out; |
2785 | 2835 | ||
@@ -2812,7 +2862,7 @@ int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2812 | goto out; | 2862 | goto out; |
2813 | } | 2863 | } |
2814 | 2864 | ||
2815 | ret = wl1271_ps_elp_wakeup(wl, false); | 2865 | ret = wl1271_ps_elp_wakeup(wl); |
2816 | if (ret < 0) | 2866 | if (ret < 0) |
2817 | goto out; | 2867 | goto out; |
2818 | 2868 | ||
@@ -3176,7 +3226,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, | |||
3176 | if (wl->state == WL1271_STATE_OFF) | 3226 | if (wl->state == WL1271_STATE_OFF) |
3177 | goto out; | 3227 | goto out; |
3178 | 3228 | ||
3179 | ret = wl1271_ps_elp_wakeup(wl, false); | 3229 | ret = wl1271_ps_elp_wakeup(wl); |
3180 | if (ret < 0) | 3230 | if (ret < 0) |
3181 | goto out; | 3231 | goto out; |
3182 | 3232 | ||
@@ -3376,9 +3426,12 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
3376 | for (j = 0; j < AP_MAX_LINKS; j++) | 3426 | for (j = 0; j < AP_MAX_LINKS; j++) |
3377 | skb_queue_head_init(&wl->links[j].tx_queue[i]); | 3427 | skb_queue_head_init(&wl->links[j].tx_queue[i]); |
3378 | 3428 | ||
3429 | skb_queue_head_init(&wl->deferred_rx_queue); | ||
3430 | skb_queue_head_init(&wl->deferred_tx_queue); | ||
3431 | |||
3379 | INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); | 3432 | INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); |
3380 | INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); | 3433 | INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); |
3381 | INIT_WORK(&wl->irq_work, wl1271_irq_work); | 3434 | INIT_WORK(&wl->netstack_work, wl1271_netstack_work); |
3382 | INIT_WORK(&wl->tx_work, wl1271_tx_work); | 3435 | INIT_WORK(&wl->tx_work, wl1271_tx_work); |
3383 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); | 3436 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); |
3384 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); | 3437 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); |
@@ -3404,6 +3457,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
3404 | wl->last_tx_hlid = 0; | 3457 | wl->last_tx_hlid = 0; |
3405 | wl->ap_ps_map = 0; | 3458 | wl->ap_ps_map = 0; |
3406 | wl->ap_fw_ps_map = 0; | 3459 | wl->ap_fw_ps_map = 0; |
3460 | wl->quirks = 0; | ||
3407 | 3461 | ||
3408 | memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); | 3462 | memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); |
3409 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) | 3463 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 5c347b1bd17f..971f13e792da 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
@@ -69,7 +69,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) | |||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) | 72 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) |
73 | { | 73 | { |
74 | DECLARE_COMPLETION_ONSTACK(compl); | 74 | DECLARE_COMPLETION_ONSTACK(compl); |
75 | unsigned long flags; | 75 | unsigned long flags; |
@@ -87,7 +87,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) | |||
87 | * the completion variable in one entity. | 87 | * the completion variable in one entity. |
88 | */ | 88 | */ |
89 | spin_lock_irqsave(&wl->wl_lock, flags); | 89 | spin_lock_irqsave(&wl->wl_lock, flags); |
90 | if (work_pending(&wl->irq_work) || chip_awake) | 90 | if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) |
91 | pending = true; | 91 | pending = true; |
92 | else | 92 | else |
93 | wl->elp_compl = &compl; | 93 | wl->elp_compl = &compl; |
@@ -149,7 +149,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, | |||
149 | case STATION_ACTIVE_MODE: | 149 | case STATION_ACTIVE_MODE: |
150 | default: | 150 | default: |
151 | wl1271_debug(DEBUG_PSM, "leaving psm"); | 151 | wl1271_debug(DEBUG_PSM, "leaving psm"); |
152 | ret = wl1271_ps_elp_wakeup(wl, false); | 152 | ret = wl1271_ps_elp_wakeup(wl); |
153 | if (ret < 0) | 153 | if (ret < 0) |
154 | return ret; | 154 | return ret; |
155 | 155 | ||
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h index fc1f4c193593..c41bd0a711bc 100644 --- a/drivers/net/wireless/wl12xx/ps.h +++ b/drivers/net/wireless/wl12xx/ps.h | |||
@@ -30,7 +30,7 @@ | |||
30 | int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, | 30 | int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, |
31 | u32 rates, bool send); | 31 | u32 rates, bool send); |
32 | void wl1271_ps_elp_sleep(struct wl1271 *wl); | 32 | void wl1271_ps_elp_sleep(struct wl1271 *wl); |
33 | int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); | 33 | int wl1271_ps_elp_wakeup(struct wl1271 *wl); |
34 | void wl1271_elp_work(struct work_struct *work); | 34 | void wl1271_elp_work(struct work_struct *work); |
35 | void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); | 35 | void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); |
36 | void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); | 36 | void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); |
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 3d13d7a83ea1..919b59f00301 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c | |||
@@ -129,7 +129,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
129 | 129 | ||
130 | skb_trim(skb, skb->len - desc->pad_len); | 130 | skb_trim(skb, skb->len - desc->pad_len); |
131 | 131 | ||
132 | ieee80211_rx_ni(wl->hw, skb); | 132 | skb_queue_tail(&wl->deferred_rx_queue, skb); |
133 | ieee80211_queue_work(wl->hw, &wl->netstack_work); | ||
133 | 134 | ||
134 | return 0; | 135 | return 0; |
135 | } | 136 | } |
@@ -198,7 +199,13 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) | |||
198 | pkt_offset += pkt_length; | 199 | pkt_offset += pkt_length; |
199 | } | 200 | } |
200 | } | 201 | } |
201 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); | 202 | |
203 | /* | ||
204 | * Write the driver's packet counter to the FW. This is only required | ||
205 | * for older hardware revisions | ||
206 | */ | ||
207 | if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) | ||
208 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); | ||
202 | } | 209 | } |
203 | 210 | ||
204 | void wl1271_set_default_filters(struct wl1271 *wl) | 211 | void wl1271_set_default_filters(struct wl1271 *wl) |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 6f897b9d90ca..420653a2859c 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "cmd.h" | 27 | #include "cmd.h" |
28 | #include "scan.h" | 28 | #include "scan.h" |
29 | #include "acx.h" | 29 | #include "acx.h" |
30 | #include "ps.h" | ||
30 | 31 | ||
31 | void wl1271_scan_complete_work(struct work_struct *work) | 32 | void wl1271_scan_complete_work(struct work_struct *work) |
32 | { | 33 | { |
@@ -40,10 +41,11 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
40 | 41 | ||
41 | mutex_lock(&wl->mutex); | 42 | mutex_lock(&wl->mutex); |
42 | 43 | ||
43 | if (wl->scan.state == WL1271_SCAN_STATE_IDLE) { | 44 | if (wl->state == WL1271_STATE_OFF) |
44 | mutex_unlock(&wl->mutex); | 45 | goto out; |
45 | return; | 46 | |
46 | } | 47 | if (wl->scan.state == WL1271_SCAN_STATE_IDLE) |
48 | goto out; | ||
47 | 49 | ||
48 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 50 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
49 | kfree(wl->scan.scanned_ch); | 51 | kfree(wl->scan.scanned_ch); |
@@ -52,13 +54,19 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
52 | ieee80211_scan_completed(wl->hw, false); | 54 | ieee80211_scan_completed(wl->hw, false); |
53 | 55 | ||
54 | /* restore hardware connection monitoring template */ | 56 | /* restore hardware connection monitoring template */ |
55 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 57 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { |
56 | wl1271_cmd_build_ap_probe_req(wl, wl->probereq); | 58 | if (wl1271_ps_elp_wakeup(wl) == 0) { |
59 | wl1271_cmd_build_ap_probe_req(wl, wl->probereq); | ||
60 | wl1271_ps_elp_sleep(wl); | ||
61 | } | ||
62 | } | ||
57 | 63 | ||
58 | if (wl->scan.failed) { | 64 | if (wl->scan.failed) { |
59 | wl1271_info("Scan completed due to error."); | 65 | wl1271_info("Scan completed due to error."); |
60 | ieee80211_queue_work(wl->hw, &wl->recovery_work); | 66 | ieee80211_queue_work(wl->hw, &wl->recovery_work); |
61 | } | 67 | } |
68 | |||
69 | out: | ||
62 | mutex_unlock(&wl->mutex); | 70 | mutex_unlock(&wl->mutex); |
63 | 71 | ||
64 | } | 72 | } |
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index d5e874825069..5b9dbeafec06 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mmc/sdio_func.h> | 28 | #include <linux/mmc/sdio_func.h> |
29 | #include <linux/mmc/sdio_ids.h> | 29 | #include <linux/mmc/sdio_ids.h> |
30 | #include <linux/mmc/card.h> | 30 | #include <linux/mmc/card.h> |
31 | #include <linux/mmc/host.h> | ||
31 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
32 | #include <linux/wl12xx.h> | 33 | #include <linux/wl12xx.h> |
33 | #include <linux/pm_runtime.h> | 34 | #include <linux/pm_runtime.h> |
@@ -60,7 +61,7 @@ static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) | |||
60 | return &(wl_to_func(wl)->dev); | 61 | return &(wl_to_func(wl)->dev); |
61 | } | 62 | } |
62 | 63 | ||
63 | static irqreturn_t wl1271_irq(int irq, void *cookie) | 64 | static irqreturn_t wl1271_hardirq(int irq, void *cookie) |
64 | { | 65 | { |
65 | struct wl1271 *wl = cookie; | 66 | struct wl1271 *wl = cookie; |
66 | unsigned long flags; | 67 | unsigned long flags; |
@@ -69,17 +70,14 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) | |||
69 | 70 | ||
70 | /* complete the ELP completion */ | 71 | /* complete the ELP completion */ |
71 | spin_lock_irqsave(&wl->wl_lock, flags); | 72 | spin_lock_irqsave(&wl->wl_lock, flags); |
73 | set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
72 | if (wl->elp_compl) { | 74 | if (wl->elp_compl) { |
73 | complete(wl->elp_compl); | 75 | complete(wl->elp_compl); |
74 | wl->elp_compl = NULL; | 76 | wl->elp_compl = NULL; |
75 | } | 77 | } |
76 | |||
77 | if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) | ||
78 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
79 | set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | ||
80 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 78 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
81 | 79 | ||
82 | return IRQ_HANDLED; | 80 | return IRQ_WAKE_THREAD; |
83 | } | 81 | } |
84 | 82 | ||
85 | static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) | 83 | static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) |
@@ -106,8 +104,6 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
106 | int ret; | 104 | int ret; |
107 | struct sdio_func *func = wl_to_func(wl); | 105 | struct sdio_func *func = wl_to_func(wl); |
108 | 106 | ||
109 | sdio_claim_host(func); | ||
110 | |||
111 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | 107 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { |
112 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); | 108 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); |
113 | wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", | 109 | wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", |
@@ -123,8 +119,6 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
123 | wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); | 119 | wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); |
124 | } | 120 | } |
125 | 121 | ||
126 | sdio_release_host(func); | ||
127 | |||
128 | if (ret) | 122 | if (ret) |
129 | wl1271_error("sdio read failed (%d)", ret); | 123 | wl1271_error("sdio read failed (%d)", ret); |
130 | } | 124 | } |
@@ -135,8 +129,6 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
135 | int ret; | 129 | int ret; |
136 | struct sdio_func *func = wl_to_func(wl); | 130 | struct sdio_func *func = wl_to_func(wl); |
137 | 131 | ||
138 | sdio_claim_host(func); | ||
139 | |||
140 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | 132 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { |
141 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); | 133 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); |
142 | wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", | 134 | wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", |
@@ -152,8 +144,6 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
152 | ret = sdio_memcpy_toio(func, addr, buf, len); | 144 | ret = sdio_memcpy_toio(func, addr, buf, len); |
153 | } | 145 | } |
154 | 146 | ||
155 | sdio_release_host(func); | ||
156 | |||
157 | if (ret) | 147 | if (ret) |
158 | wl1271_error("sdio write failed (%d)", ret); | 148 | wl1271_error("sdio write failed (%d)", ret); |
159 | } | 149 | } |
@@ -163,14 +153,18 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) | |||
163 | struct sdio_func *func = wl_to_func(wl); | 153 | struct sdio_func *func = wl_to_func(wl); |
164 | int ret; | 154 | int ret; |
165 | 155 | ||
166 | /* Power up the card */ | 156 | /* Make sure the card will not be powered off by runtime PM */ |
167 | ret = pm_runtime_get_sync(&func->dev); | 157 | ret = pm_runtime_get_sync(&func->dev); |
168 | if (ret < 0) | 158 | if (ret < 0) |
169 | goto out; | 159 | goto out; |
170 | 160 | ||
161 | /* Runtime PM might be disabled, so power up the card manually */ | ||
162 | ret = mmc_power_restore_host(func->card->host); | ||
163 | if (ret < 0) | ||
164 | goto out; | ||
165 | |||
171 | sdio_claim_host(func); | 166 | sdio_claim_host(func); |
172 | sdio_enable_func(func); | 167 | sdio_enable_func(func); |
173 | sdio_release_host(func); | ||
174 | 168 | ||
175 | out: | 169 | out: |
176 | return ret; | 170 | return ret; |
@@ -179,12 +173,17 @@ out: | |||
179 | static int wl1271_sdio_power_off(struct wl1271 *wl) | 173 | static int wl1271_sdio_power_off(struct wl1271 *wl) |
180 | { | 174 | { |
181 | struct sdio_func *func = wl_to_func(wl); | 175 | struct sdio_func *func = wl_to_func(wl); |
176 | int ret; | ||
182 | 177 | ||
183 | sdio_claim_host(func); | ||
184 | sdio_disable_func(func); | 178 | sdio_disable_func(func); |
185 | sdio_release_host(func); | 179 | sdio_release_host(func); |
186 | 180 | ||
187 | /* Power down the card */ | 181 | /* Runtime PM might be disabled, so power off the card manually */ |
182 | ret = mmc_power_save_host(func->card->host); | ||
183 | if (ret < 0) | ||
184 | return ret; | ||
185 | |||
186 | /* Let runtime PM know the card is powered off */ | ||
188 | return pm_runtime_put_sync(&func->dev); | 187 | return pm_runtime_put_sync(&func->dev); |
189 | } | 188 | } |
190 | 189 | ||
@@ -241,14 +240,14 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
241 | wl->irq = wlan_data->irq; | 240 | wl->irq = wlan_data->irq; |
242 | wl->ref_clock = wlan_data->board_ref_clock; | 241 | wl->ref_clock = wlan_data->board_ref_clock; |
243 | 242 | ||
244 | ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); | 243 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, |
244 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
245 | DRIVER_NAME, wl); | ||
245 | if (ret < 0) { | 246 | if (ret < 0) { |
246 | wl1271_error("request_irq() failed: %d", ret); | 247 | wl1271_error("request_irq() failed: %d", ret); |
247 | goto out_free; | 248 | goto out_free; |
248 | } | 249 | } |
249 | 250 | ||
250 | set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); | ||
251 | |||
252 | disable_irq(wl->irq); | 251 | disable_irq(wl->irq); |
253 | 252 | ||
254 | ret = wl1271_init_ieee80211(wl); | 253 | ret = wl1271_init_ieee80211(wl); |
@@ -271,7 +270,6 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
271 | out_irq: | 270 | out_irq: |
272 | free_irq(wl->irq, wl); | 271 | free_irq(wl->irq, wl); |
273 | 272 | ||
274 | |||
275 | out_free: | 273 | out_free: |
276 | wl1271_free_hw(wl); | 274 | wl1271_free_hw(wl); |
277 | 275 | ||
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 0132dad756c4..18cf01719ae0 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c | |||
@@ -320,28 +320,23 @@ static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
320 | spi_sync(wl_to_spi(wl), &m); | 320 | spi_sync(wl_to_spi(wl), &m); |
321 | } | 321 | } |
322 | 322 | ||
323 | static irqreturn_t wl1271_irq(int irq, void *cookie) | 323 | static irqreturn_t wl1271_hardirq(int irq, void *cookie) |
324 | { | 324 | { |
325 | struct wl1271 *wl; | 325 | struct wl1271 *wl = cookie; |
326 | unsigned long flags; | 326 | unsigned long flags; |
327 | 327 | ||
328 | wl1271_debug(DEBUG_IRQ, "IRQ"); | 328 | wl1271_debug(DEBUG_IRQ, "IRQ"); |
329 | 329 | ||
330 | wl = cookie; | ||
331 | |||
332 | /* complete the ELP completion */ | 330 | /* complete the ELP completion */ |
333 | spin_lock_irqsave(&wl->wl_lock, flags); | 331 | spin_lock_irqsave(&wl->wl_lock, flags); |
332 | set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
334 | if (wl->elp_compl) { | 333 | if (wl->elp_compl) { |
335 | complete(wl->elp_compl); | 334 | complete(wl->elp_compl); |
336 | wl->elp_compl = NULL; | 335 | wl->elp_compl = NULL; |
337 | } | 336 | } |
338 | |||
339 | if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) | ||
340 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
341 | set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | ||
342 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 337 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
343 | 338 | ||
344 | return IRQ_HANDLED; | 339 | return IRQ_WAKE_THREAD; |
345 | } | 340 | } |
346 | 341 | ||
347 | static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) | 342 | static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) |
@@ -413,14 +408,14 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
413 | goto out_free; | 408 | goto out_free; |
414 | } | 409 | } |
415 | 410 | ||
416 | ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); | 411 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, |
412 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
413 | DRIVER_NAME, wl); | ||
417 | if (ret < 0) { | 414 | if (ret < 0) { |
418 | wl1271_error("request_irq() failed: %d", ret); | 415 | wl1271_error("request_irq() failed: %d", ret); |
419 | goto out_free; | 416 | goto out_free; |
420 | } | 417 | } |
421 | 418 | ||
422 | set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); | ||
423 | |||
424 | disable_irq(wl->irq); | 419 | disable_irq(wl->irq); |
425 | 420 | ||
426 | ret = wl1271_init_ieee80211(wl); | 421 | ret = wl1271_init_ieee80211(wl); |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index ac60d577319f..5e9ef7d53e7e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -464,7 +464,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) | |||
464 | 464 | ||
465 | while ((skb = wl1271_skb_dequeue(wl))) { | 465 | while ((skb = wl1271_skb_dequeue(wl))) { |
466 | if (!woken_up) { | 466 | if (!woken_up) { |
467 | ret = wl1271_ps_elp_wakeup(wl, false); | 467 | ret = wl1271_ps_elp_wakeup(wl); |
468 | if (ret < 0) | 468 | if (ret < 0) |
469 | goto out_ack; | 469 | goto out_ack; |
470 | woken_up = true; | 470 | woken_up = true; |
@@ -506,8 +506,14 @@ out_ack: | |||
506 | sent_packets = true; | 506 | sent_packets = true; |
507 | } | 507 | } |
508 | if (sent_packets) { | 508 | if (sent_packets) { |
509 | /* interrupt the firmware with the new packets */ | 509 | /* |
510 | wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); | 510 | * Interrupt the firmware with the new packets. This is only |
511 | * required for older hardware revisions | ||
512 | */ | ||
513 | if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) | ||
514 | wl1271_write32(wl, WL1271_HOST_WR_ACCESS, | ||
515 | wl->tx_packets_count); | ||
516 | |||
511 | wl1271_handle_tx_low_watermark(wl); | 517 | wl1271_handle_tx_low_watermark(wl); |
512 | } | 518 | } |
513 | 519 | ||
@@ -583,7 +589,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
583 | result->rate_class_index, result->status); | 589 | result->rate_class_index, result->status); |
584 | 590 | ||
585 | /* return the packet to the stack */ | 591 | /* return the packet to the stack */ |
586 | ieee80211_tx_status(wl->hw, skb); | 592 | skb_queue_tail(&wl->deferred_tx_queue, skb); |
593 | ieee80211_queue_work(wl->hw, &wl->netstack_work); | ||
587 | wl1271_free_tx_id(wl, result->id); | 594 | wl1271_free_tx_id(wl, result->id); |
588 | } | 595 | } |
589 | 596 | ||
@@ -687,16 +694,30 @@ void wl1271_tx_reset(struct wl1271 *wl) | |||
687 | */ | 694 | */ |
688 | wl1271_handle_tx_low_watermark(wl); | 695 | wl1271_handle_tx_low_watermark(wl); |
689 | 696 | ||
690 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) | 697 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) { |
691 | if (wl->tx_frames[i] != NULL) { | 698 | if (wl->tx_frames[i] == NULL) |
692 | skb = wl->tx_frames[i]; | 699 | continue; |
693 | wl1271_free_tx_id(wl, i); | 700 | |
694 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); | 701 | skb = wl->tx_frames[i]; |
695 | info = IEEE80211_SKB_CB(skb); | 702 | wl1271_free_tx_id(wl, i); |
696 | info->status.rates[0].idx = -1; | 703 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); |
697 | info->status.rates[0].count = 0; | 704 | |
698 | ieee80211_tx_status(wl->hw, skb); | 705 | /* Remove private headers before passing the skb to mac80211 */ |
706 | info = IEEE80211_SKB_CB(skb); | ||
707 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | ||
708 | if (info->control.hw_key && | ||
709 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { | ||
710 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
711 | memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, | ||
712 | hdrlen); | ||
713 | skb_pull(skb, WL1271_TKIP_IV_SPACE); | ||
699 | } | 714 | } |
715 | |||
716 | info->status.rates[0].idx = -1; | ||
717 | info->status.rates[0].count = 0; | ||
718 | |||
719 | ieee80211_tx_status(wl->hw, skb); | ||
720 | } | ||
700 | } | 721 | } |
701 | 722 | ||
702 | #define WL1271_TX_FLUSH_TIMEOUT 500000 | 723 | #define WL1271_TX_FLUSH_TIMEOUT 500000 |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 338acc9f60b3..86be83e25ec5 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -130,10 +130,10 @@ extern u32 wl12xx_debug_level; | |||
130 | 130 | ||
131 | 131 | ||
132 | 132 | ||
133 | #define WL1271_FW_NAME "wl1271-fw-2.bin" | 133 | #define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin" |
134 | #define WL1271_AP_FW_NAME "wl1271-fw-ap.bin" | 134 | #define WL1271_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin" |
135 | 135 | ||
136 | #define WL1271_NVS_NAME "wl1271-nvs.bin" | 136 | #define WL1271_NVS_NAME "ti-connectivity/wl1271-nvs.bin" |
137 | 137 | ||
138 | #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) | 138 | #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) |
139 | #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) | 139 | #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) |
@@ -317,10 +317,10 @@ enum wl12xx_flags { | |||
317 | WL1271_FLAG_JOINED, | 317 | WL1271_FLAG_JOINED, |
318 | WL1271_FLAG_GPIO_POWER, | 318 | WL1271_FLAG_GPIO_POWER, |
319 | WL1271_FLAG_TX_QUEUE_STOPPED, | 319 | WL1271_FLAG_TX_QUEUE_STOPPED, |
320 | WL1271_FLAG_TX_PENDING, | ||
320 | WL1271_FLAG_IN_ELP, | 321 | WL1271_FLAG_IN_ELP, |
321 | WL1271_FLAG_PSM, | 322 | WL1271_FLAG_PSM, |
322 | WL1271_FLAG_PSM_REQUESTED, | 323 | WL1271_FLAG_PSM_REQUESTED, |
323 | WL1271_FLAG_IRQ_PENDING, | ||
324 | WL1271_FLAG_IRQ_RUNNING, | 324 | WL1271_FLAG_IRQ_RUNNING, |
325 | WL1271_FLAG_IDLE, | 325 | WL1271_FLAG_IDLE, |
326 | WL1271_FLAG_IDLE_REQUESTED, | 326 | WL1271_FLAG_IDLE_REQUESTED, |
@@ -404,6 +404,12 @@ struct wl1271 { | |||
404 | struct sk_buff_head tx_queue[NUM_TX_QUEUES]; | 404 | struct sk_buff_head tx_queue[NUM_TX_QUEUES]; |
405 | int tx_queue_count; | 405 | int tx_queue_count; |
406 | 406 | ||
407 | /* Frames received, not handled yet by mac80211 */ | ||
408 | struct sk_buff_head deferred_rx_queue; | ||
409 | |||
410 | /* Frames sent, not returned yet to mac80211 */ | ||
411 | struct sk_buff_head deferred_tx_queue; | ||
412 | |||
407 | struct work_struct tx_work; | 413 | struct work_struct tx_work; |
408 | 414 | ||
409 | /* Pending TX frames */ | 415 | /* Pending TX frames */ |
@@ -424,8 +430,8 @@ struct wl1271 { | |||
424 | /* Intermediate buffer, used for packet aggregation */ | 430 | /* Intermediate buffer, used for packet aggregation */ |
425 | u8 *aggr_buf; | 431 | u8 *aggr_buf; |
426 | 432 | ||
427 | /* The target interrupt mask */ | 433 | /* Network stack work */ |
428 | struct work_struct irq_work; | 434 | struct work_struct netstack_work; |
429 | 435 | ||
430 | /* Hardware recovery work */ | 436 | /* Hardware recovery work */ |
431 | struct work_struct recovery_work; | 437 | struct work_struct recovery_work; |
@@ -535,6 +541,9 @@ struct wl1271 { | |||
535 | 541 | ||
536 | /* AP-mode - a bitmap of links currently in PS mode in mac80211 */ | 542 | /* AP-mode - a bitmap of links currently in PS mode in mac80211 */ |
537 | unsigned long ap_ps_map; | 543 | unsigned long ap_ps_map; |
544 | |||
545 | /* Quirks of specific hardware revisions */ | ||
546 | unsigned int quirks; | ||
538 | }; | 547 | }; |
539 | 548 | ||
540 | struct wl1271_station { | 549 | struct wl1271_station { |
@@ -553,6 +562,8 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
553 | #define WL1271_TX_QUEUE_LOW_WATERMARK 10 | 562 | #define WL1271_TX_QUEUE_LOW_WATERMARK 10 |
554 | #define WL1271_TX_QUEUE_HIGH_WATERMARK 25 | 563 | #define WL1271_TX_QUEUE_HIGH_WATERMARK 25 |
555 | 564 | ||
565 | #define WL1271_DEFERRED_QUEUE_LIMIT 64 | ||
566 | |||
556 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power | 567 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power |
557 | on in case is has been shut down shortly before */ | 568 | on in case is has been shut down shortly before */ |
558 | #define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */ | 569 | #define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */ |
@@ -562,4 +573,9 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
562 | #define HW_BG_RATES_MASK 0xffff | 573 | #define HW_BG_RATES_MASK 0xffff |
563 | #define HW_HT_RATES_OFFSET 16 | 574 | #define HW_HT_RATES_OFFSET 16 |
564 | 575 | ||
576 | /* Quirks */ | ||
577 | |||
578 | /* Each RX/TX transaction requires an end-of-transaction transfer */ | ||
579 | #define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) | ||
580 | |||
565 | #endif | 581 | #endif |
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index 67dcf8f28cd3..18fe542360f2 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h | |||
@@ -55,7 +55,6 @@ | |||
55 | 55 | ||
56 | /* This really should be 8, but not for our firmware */ | 56 | /* This really should be 8, but not for our firmware */ |
57 | #define MAX_SUPPORTED_RATES 32 | 57 | #define MAX_SUPPORTED_RATES 32 |
58 | #define COUNTRY_STRING_LEN 3 | ||
59 | #define MAX_COUNTRY_TRIPLETS 32 | 58 | #define MAX_COUNTRY_TRIPLETS 32 |
60 | 59 | ||
61 | /* Headers */ | 60 | /* Headers */ |
@@ -99,7 +98,7 @@ struct country_triplet { | |||
99 | 98 | ||
100 | struct wl12xx_ie_country { | 99 | struct wl12xx_ie_country { |
101 | struct wl12xx_ie_header header; | 100 | struct wl12xx_ie_header header; |
102 | u8 country_string[COUNTRY_STRING_LEN]; | 101 | u8 country_string[IEEE80211_COUNTRY_STRING_LEN]; |
103 | struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; | 102 | struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; |
104 | } __packed; | 103 | } __packed; |
105 | 104 | ||