diff options
78 files changed, 2611 insertions, 1770 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 | ||
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 294169e31364..2d1c6117d92c 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -1325,6 +1325,9 @@ enum { | |||
1325 | /* Although the spec says 8 I'm seeing 6 in practice */ | 1325 | /* Although the spec says 8 I'm seeing 6 in practice */ |
1326 | #define IEEE80211_COUNTRY_IE_MIN_LEN 6 | 1326 | #define IEEE80211_COUNTRY_IE_MIN_LEN 6 |
1327 | 1327 | ||
1328 | /* The Country String field of the element shall be 3 octets in length */ | ||
1329 | #define IEEE80211_COUNTRY_STRING_LEN 3 | ||
1330 | |||
1328 | /* | 1331 | /* |
1329 | * For regulatory extension stuff see IEEE 802.11-2007 | 1332 | * For regulatory extension stuff see IEEE 802.11-2007 |
1330 | * Annex I (page 1141) and Annex J (page 1147). Also | 1333 | * Annex I (page 1141) and Annex J (page 1147). Also |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index a5f8c4684a32..ec6acf2f1c0b 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -415,6 +415,17 @@ struct hci_cp_io_capability_reply { | |||
415 | __u8 authentication; | 415 | __u8 authentication; |
416 | } __packed; | 416 | } __packed; |
417 | 417 | ||
418 | #define HCI_OP_USER_CONFIRM_REPLY 0x042c | ||
419 | struct hci_cp_user_confirm_reply { | ||
420 | bdaddr_t bdaddr; | ||
421 | } __packed; | ||
422 | struct hci_rp_user_confirm_reply { | ||
423 | __u8 status; | ||
424 | bdaddr_t bdaddr; | ||
425 | } __packed; | ||
426 | |||
427 | #define HCI_OP_USER_CONFIRM_NEG_REPLY 0x042d | ||
428 | |||
418 | #define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434 | 429 | #define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434 |
419 | struct hci_cp_io_capability_neg_reply { | 430 | struct hci_cp_io_capability_neg_reply { |
420 | bdaddr_t bdaddr; | 431 | bdaddr_t bdaddr; |
@@ -936,6 +947,12 @@ struct hci_ev_io_capa_reply { | |||
936 | __u8 authentication; | 947 | __u8 authentication; |
937 | } __packed; | 948 | } __packed; |
938 | 949 | ||
950 | #define HCI_EV_USER_CONFIRM_REQUEST 0x33 | ||
951 | struct hci_ev_user_confirm_req { | ||
952 | bdaddr_t bdaddr; | ||
953 | __le32 passkey; | ||
954 | } __packed; | ||
955 | |||
939 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 | 956 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 |
940 | struct hci_ev_simple_pair_complete { | 957 | struct hci_ev_simple_pair_complete { |
941 | __u8 status; | 958 | __u8 status; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d5d8454236bf..441dadbf6a89 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -248,6 +248,10 @@ struct hci_conn { | |||
248 | void *priv; | 248 | void *priv; |
249 | 249 | ||
250 | struct hci_conn *link; | 250 | struct hci_conn *link; |
251 | |||
252 | void (*connect_cfm_cb) (struct hci_conn *conn, u8 status); | ||
253 | void (*security_cfm_cb) (struct hci_conn *conn, u8 status); | ||
254 | void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); | ||
251 | }; | 255 | }; |
252 | 256 | ||
253 | extern struct hci_proto *hci_proto[]; | 257 | extern struct hci_proto *hci_proto[]; |
@@ -571,6 +575,9 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) | |||
571 | hp = hci_proto[HCI_PROTO_SCO]; | 575 | hp = hci_proto[HCI_PROTO_SCO]; |
572 | if (hp && hp->connect_cfm) | 576 | if (hp && hp->connect_cfm) |
573 | hp->connect_cfm(conn, status); | 577 | hp->connect_cfm(conn, status); |
578 | |||
579 | if (conn->connect_cfm_cb) | ||
580 | conn->connect_cfm_cb(conn, status); | ||
574 | } | 581 | } |
575 | 582 | ||
576 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) | 583 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) |
@@ -600,6 +607,9 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) | |||
600 | hp = hci_proto[HCI_PROTO_SCO]; | 607 | hp = hci_proto[HCI_PROTO_SCO]; |
601 | if (hp && hp->disconn_cfm) | 608 | if (hp && hp->disconn_cfm) |
602 | hp->disconn_cfm(conn, reason); | 609 | hp->disconn_cfm(conn, reason); |
610 | |||
611 | if (conn->disconn_cfm_cb) | ||
612 | conn->disconn_cfm_cb(conn, reason); | ||
603 | } | 613 | } |
604 | 614 | ||
605 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | 615 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) |
@@ -619,6 +629,9 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | |||
619 | hp = hci_proto[HCI_PROTO_SCO]; | 629 | hp = hci_proto[HCI_PROTO_SCO]; |
620 | if (hp && hp->security_cfm) | 630 | if (hp && hp->security_cfm) |
621 | hp->security_cfm(conn, status, encrypt); | 631 | hp->security_cfm(conn, status, encrypt); |
632 | |||
633 | if (conn->security_cfm_cb) | ||
634 | conn->security_cfm_cb(conn, status); | ||
622 | } | 635 | } |
623 | 636 | ||
624 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) | 637 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) |
@@ -632,6 +645,9 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u | |||
632 | hp = hci_proto[HCI_PROTO_SCO]; | 645 | hp = hci_proto[HCI_PROTO_SCO]; |
633 | if (hp && hp->security_cfm) | 646 | if (hp && hp->security_cfm) |
634 | hp->security_cfm(conn, status, encrypt); | 647 | hp->security_cfm(conn, status, encrypt); |
648 | |||
649 | if (conn->security_cfm_cb) | ||
650 | conn->security_cfm_cb(conn, status); | ||
635 | } | 651 | } |
636 | 652 | ||
637 | int hci_register_proto(struct hci_proto *hproto); | 653 | int hci_register_proto(struct hci_proto *hproto); |
@@ -746,6 +762,11 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); | |||
746 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr); | 762 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr); |
747 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | 763 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); |
748 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | 764 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); |
765 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value); | ||
766 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | ||
767 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, | ||
768 | u8 status); | ||
769 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status); | ||
749 | 770 | ||
750 | /* HCI info for socket */ | 771 | /* HCI info for socket */ |
751 | #define hci_pi(sk) ((struct hci_pinfo *) sk) | 772 | #define hci_pi(sk) ((struct hci_pinfo *) sk) |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 44ac55c85079..5fabfa886b3e 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -21,11 +21,13 @@ | |||
21 | SOFTWARE IS DISCLAIMED. | 21 | SOFTWARE IS DISCLAIMED. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define MGMT_INDEX_NONE 0xFFFF | ||
25 | |||
24 | struct mgmt_hdr { | 26 | struct mgmt_hdr { |
25 | __le16 opcode; | 27 | __le16 opcode; |
28 | __le16 index; | ||
26 | __le16 len; | 29 | __le16 len; |
27 | } __packed; | 30 | } __packed; |
28 | #define MGMT_HDR_SIZE 4 | ||
29 | 31 | ||
30 | #define MGMT_OP_READ_VERSION 0x0001 | 32 | #define MGMT_OP_READ_VERSION 0x0001 |
31 | struct mgmt_rp_read_version { | 33 | struct mgmt_rp_read_version { |
@@ -40,11 +42,7 @@ struct mgmt_rp_read_index_list { | |||
40 | } __packed; | 42 | } __packed; |
41 | 43 | ||
42 | #define MGMT_OP_READ_INFO 0x0004 | 44 | #define MGMT_OP_READ_INFO 0x0004 |
43 | struct mgmt_cp_read_info { | ||
44 | __le16 index; | ||
45 | } __packed; | ||
46 | struct mgmt_rp_read_info { | 45 | struct mgmt_rp_read_info { |
47 | __le16 index; | ||
48 | __u8 type; | 46 | __u8 type; |
49 | __u8 powered; | 47 | __u8 powered; |
50 | __u8 connectable; | 48 | __u8 connectable; |
@@ -60,7 +58,6 @@ struct mgmt_rp_read_info { | |||
60 | } __packed; | 58 | } __packed; |
61 | 59 | ||
62 | struct mgmt_mode { | 60 | struct mgmt_mode { |
63 | __le16 index; | ||
64 | __u8 val; | 61 | __u8 val; |
65 | } __packed; | 62 | } __packed; |
66 | 63 | ||
@@ -74,27 +71,23 @@ struct mgmt_mode { | |||
74 | 71 | ||
75 | #define MGMT_OP_ADD_UUID 0x0009 | 72 | #define MGMT_OP_ADD_UUID 0x0009 |
76 | struct mgmt_cp_add_uuid { | 73 | struct mgmt_cp_add_uuid { |
77 | __le16 index; | ||
78 | __u8 uuid[16]; | 74 | __u8 uuid[16]; |
79 | __u8 svc_hint; | 75 | __u8 svc_hint; |
80 | } __packed; | 76 | } __packed; |
81 | 77 | ||
82 | #define MGMT_OP_REMOVE_UUID 0x000A | 78 | #define MGMT_OP_REMOVE_UUID 0x000A |
83 | struct mgmt_cp_remove_uuid { | 79 | struct mgmt_cp_remove_uuid { |
84 | __le16 index; | ||
85 | __u8 uuid[16]; | 80 | __u8 uuid[16]; |
86 | } __packed; | 81 | } __packed; |
87 | 82 | ||
88 | #define MGMT_OP_SET_DEV_CLASS 0x000B | 83 | #define MGMT_OP_SET_DEV_CLASS 0x000B |
89 | struct mgmt_cp_set_dev_class { | 84 | struct mgmt_cp_set_dev_class { |
90 | __le16 index; | ||
91 | __u8 major; | 85 | __u8 major; |
92 | __u8 minor; | 86 | __u8 minor; |
93 | } __packed; | 87 | } __packed; |
94 | 88 | ||
95 | #define MGMT_OP_SET_SERVICE_CACHE 0x000C | 89 | #define MGMT_OP_SET_SERVICE_CACHE 0x000C |
96 | struct mgmt_cp_set_service_cache { | 90 | struct mgmt_cp_set_service_cache { |
97 | __le16 index; | ||
98 | __u8 enable; | 91 | __u8 enable; |
99 | } __packed; | 92 | } __packed; |
100 | 93 | ||
@@ -107,7 +100,6 @@ struct mgmt_key_info { | |||
107 | 100 | ||
108 | #define MGMT_OP_LOAD_KEYS 0x000D | 101 | #define MGMT_OP_LOAD_KEYS 0x000D |
109 | struct mgmt_cp_load_keys { | 102 | struct mgmt_cp_load_keys { |
110 | __le16 index; | ||
111 | __u8 debug_keys; | 103 | __u8 debug_keys; |
112 | __le16 key_count; | 104 | __le16 key_count; |
113 | struct mgmt_key_info keys[0]; | 105 | struct mgmt_key_info keys[0]; |
@@ -115,51 +107,66 @@ struct mgmt_cp_load_keys { | |||
115 | 107 | ||
116 | #define MGMT_OP_REMOVE_KEY 0x000E | 108 | #define MGMT_OP_REMOVE_KEY 0x000E |
117 | struct mgmt_cp_remove_key { | 109 | struct mgmt_cp_remove_key { |
118 | __le16 index; | ||
119 | bdaddr_t bdaddr; | 110 | bdaddr_t bdaddr; |
120 | __u8 disconnect; | 111 | __u8 disconnect; |
121 | } __packed; | 112 | } __packed; |
122 | 113 | ||
123 | #define MGMT_OP_DISCONNECT 0x000F | 114 | #define MGMT_OP_DISCONNECT 0x000F |
124 | struct mgmt_cp_disconnect { | 115 | struct mgmt_cp_disconnect { |
125 | __le16 index; | ||
126 | bdaddr_t bdaddr; | 116 | bdaddr_t bdaddr; |
127 | } __packed; | 117 | } __packed; |
128 | struct mgmt_rp_disconnect { | 118 | struct mgmt_rp_disconnect { |
129 | __le16 index; | ||
130 | bdaddr_t bdaddr; | 119 | bdaddr_t bdaddr; |
131 | } __packed; | 120 | } __packed; |
132 | 121 | ||
133 | #define MGMT_OP_GET_CONNECTIONS 0x0010 | 122 | #define MGMT_OP_GET_CONNECTIONS 0x0010 |
134 | struct mgmt_cp_get_connections { | ||
135 | __le16 index; | ||
136 | } __packed; | ||
137 | struct mgmt_rp_get_connections { | 123 | struct mgmt_rp_get_connections { |
138 | __le16 index; | ||
139 | __le16 conn_count; | 124 | __le16 conn_count; |
140 | bdaddr_t conn[0]; | 125 | bdaddr_t conn[0]; |
141 | } __packed; | 126 | } __packed; |
142 | 127 | ||
143 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 | 128 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 |
144 | struct mgmt_cp_pin_code_reply { | 129 | struct mgmt_cp_pin_code_reply { |
145 | __le16 index; | ||
146 | bdaddr_t bdaddr; | 130 | bdaddr_t bdaddr; |
147 | __u8 pin_len; | 131 | __u8 pin_len; |
148 | __u8 pin_code[16]; | 132 | __u8 pin_code[16]; |
149 | } __packed; | 133 | } __packed; |
134 | struct mgmt_rp_pin_code_reply { | ||
135 | bdaddr_t bdaddr; | ||
136 | uint8_t status; | ||
137 | } __packed; | ||
150 | 138 | ||
151 | #define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012 | 139 | #define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012 |
152 | struct mgmt_cp_pin_code_neg_reply { | 140 | struct mgmt_cp_pin_code_neg_reply { |
153 | __le16 index; | ||
154 | bdaddr_t bdaddr; | 141 | bdaddr_t bdaddr; |
155 | } __packed; | 142 | } __packed; |
156 | 143 | ||
157 | #define MGMT_OP_SET_IO_CAPABILITY 0x0013 | 144 | #define MGMT_OP_SET_IO_CAPABILITY 0x0013 |
158 | struct mgmt_cp_set_io_capability { | 145 | struct mgmt_cp_set_io_capability { |
159 | __le16 index; | ||
160 | __u8 io_capability; | 146 | __u8 io_capability; |
161 | } __packed; | 147 | } __packed; |
162 | 148 | ||
149 | #define MGMT_OP_PAIR_DEVICE 0x0014 | ||
150 | struct mgmt_cp_pair_device { | ||
151 | bdaddr_t bdaddr; | ||
152 | __u8 io_cap; | ||
153 | } __packed; | ||
154 | struct mgmt_rp_pair_device { | ||
155 | bdaddr_t bdaddr; | ||
156 | __u8 status; | ||
157 | } __packed; | ||
158 | |||
159 | #define MGMT_OP_USER_CONFIRM_REPLY 0x0015 | ||
160 | struct mgmt_cp_user_confirm_reply { | ||
161 | bdaddr_t bdaddr; | ||
162 | } __packed; | ||
163 | struct mgmt_rp_user_confirm_reply { | ||
164 | bdaddr_t bdaddr; | ||
165 | __u8 status; | ||
166 | } __packed; | ||
167 | |||
168 | #define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016 | ||
169 | |||
163 | #define MGMT_EV_CMD_COMPLETE 0x0001 | 170 | #define MGMT_EV_CMD_COMPLETE 0x0001 |
164 | struct mgmt_ev_cmd_complete { | 171 | struct mgmt_ev_cmd_complete { |
165 | __le16 opcode; | 172 | __le16 opcode; |
@@ -174,19 +181,12 @@ struct mgmt_ev_cmd_status { | |||
174 | 181 | ||
175 | #define MGMT_EV_CONTROLLER_ERROR 0x0003 | 182 | #define MGMT_EV_CONTROLLER_ERROR 0x0003 |
176 | struct mgmt_ev_controller_error { | 183 | struct mgmt_ev_controller_error { |
177 | __le16 index; | ||
178 | __u8 error_code; | 184 | __u8 error_code; |
179 | } __packed; | 185 | } __packed; |
180 | 186 | ||
181 | #define MGMT_EV_INDEX_ADDED 0x0004 | 187 | #define MGMT_EV_INDEX_ADDED 0x0004 |
182 | struct mgmt_ev_index_added { | ||
183 | __le16 index; | ||
184 | } __packed; | ||
185 | 188 | ||
186 | #define MGMT_EV_INDEX_REMOVED 0x0005 | 189 | #define MGMT_EV_INDEX_REMOVED 0x0005 |
187 | struct mgmt_ev_index_removed { | ||
188 | __le16 index; | ||
189 | } __packed; | ||
190 | 190 | ||
191 | #define MGMT_EV_POWERED 0x0006 | 191 | #define MGMT_EV_POWERED 0x0006 |
192 | 192 | ||
@@ -198,32 +198,39 @@ struct mgmt_ev_index_removed { | |||
198 | 198 | ||
199 | #define MGMT_EV_NEW_KEY 0x000A | 199 | #define MGMT_EV_NEW_KEY 0x000A |
200 | struct mgmt_ev_new_key { | 200 | struct mgmt_ev_new_key { |
201 | __le16 index; | ||
202 | struct mgmt_key_info key; | 201 | struct mgmt_key_info key; |
203 | __u8 old_key_type; | 202 | __u8 old_key_type; |
204 | } __packed; | 203 | } __packed; |
205 | 204 | ||
206 | #define MGMT_EV_CONNECTED 0x000B | 205 | #define MGMT_EV_CONNECTED 0x000B |
207 | struct mgmt_ev_connected { | 206 | struct mgmt_ev_connected { |
208 | __le16 index; | ||
209 | bdaddr_t bdaddr; | 207 | bdaddr_t bdaddr; |
210 | } __packed; | 208 | } __packed; |
211 | 209 | ||
212 | #define MGMT_EV_DISCONNECTED 0x000C | 210 | #define MGMT_EV_DISCONNECTED 0x000C |
213 | struct mgmt_ev_disconnected { | 211 | struct mgmt_ev_disconnected { |
214 | __le16 index; | ||
215 | bdaddr_t bdaddr; | 212 | bdaddr_t bdaddr; |
216 | } __packed; | 213 | } __packed; |
217 | 214 | ||
218 | #define MGMT_EV_CONNECT_FAILED 0x000D | 215 | #define MGMT_EV_CONNECT_FAILED 0x000D |
219 | struct mgmt_ev_connect_failed { | 216 | struct mgmt_ev_connect_failed { |
220 | __le16 index; | ||
221 | bdaddr_t bdaddr; | 217 | bdaddr_t bdaddr; |
222 | __u8 status; | 218 | __u8 status; |
223 | } __packed; | 219 | } __packed; |
224 | 220 | ||
225 | #define MGMT_EV_PIN_CODE_REQUEST 0x000E | 221 | #define MGMT_EV_PIN_CODE_REQUEST 0x000E |
226 | struct mgmt_ev_pin_code_request { | 222 | struct mgmt_ev_pin_code_request { |
227 | __le16 index; | ||
228 | bdaddr_t bdaddr; | 223 | bdaddr_t bdaddr; |
229 | } __packed; | 224 | } __packed; |
225 | |||
226 | #define MGMT_EV_USER_CONFIRM_REQUEST 0x000F | ||
227 | struct mgmt_ev_user_confirm_request { | ||
228 | bdaddr_t bdaddr; | ||
229 | __le32 value; | ||
230 | } __packed; | ||
231 | |||
232 | #define MGMT_EV_AUTH_FAILED 0x0010 | ||
233 | struct mgmt_ev_auth_failed { | ||
234 | bdaddr_t bdaddr; | ||
235 | __u8 status; | ||
236 | } __packed; | ||
diff --git a/lib/Kconfig b/lib/Kconfig index 8334342e0d05..3a55a43c43eb 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -221,6 +221,13 @@ config LRU_CACHE | |||
221 | tristate | 221 | tristate |
222 | 222 | ||
223 | config AVERAGE | 223 | config AVERAGE |
224 | bool | 224 | bool "Averaging functions" |
225 | help | ||
226 | This option is provided for the case where no in-kernel-tree | ||
227 | modules require averaging functions, but a module built outside | ||
228 | the kernel tree does. Such modules that use library averaging | ||
229 | functions require Y here. | ||
230 | |||
231 | If unsure, say N. | ||
225 | 232 | ||
226 | endmenu | 233 | endmenu |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 88af9eb9aa48..8add9b499912 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -550,10 +550,8 @@ static int __init bt_init(void) | |||
550 | goto error; | 550 | goto error; |
551 | 551 | ||
552 | err = l2cap_init(); | 552 | err = l2cap_init(); |
553 | if (err < 0) { | 553 | if (err < 0) |
554 | hci_sock_cleanup(); | ||
555 | goto sock_err; | 554 | goto sock_err; |
556 | } | ||
557 | 555 | ||
558 | err = sco_init(); | 556 | err = sco_init(); |
559 | if (err < 0) { | 557 | if (err < 0) { |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index a050a6984901..7a6f56b2f49d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -286,6 +286,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
286 | conn->state = BT_OPEN; | 286 | conn->state = BT_OPEN; |
287 | conn->auth_type = HCI_AT_GENERAL_BONDING; | 287 | conn->auth_type = HCI_AT_GENERAL_BONDING; |
288 | conn->io_capability = hdev->io_capability; | 288 | conn->io_capability = hdev->io_capability; |
289 | conn->remote_auth = 0xff; | ||
289 | 290 | ||
290 | conn->power_save = 1; | 291 | conn->power_save = 1; |
291 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 292 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
@@ -429,10 +430,11 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
429 | 430 | ||
430 | if (type == LE_LINK) { | 431 | if (type == LE_LINK) { |
431 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); | 432 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); |
433 | if (le) | ||
434 | return ERR_PTR(-EBUSY); | ||
435 | le = hci_conn_add(hdev, LE_LINK, dst); | ||
432 | if (!le) | 436 | if (!le) |
433 | le = hci_conn_add(hdev, LE_LINK, dst); | 437 | return ERR_PTR(-ENOMEM); |
434 | if (!le) | ||
435 | return NULL; | ||
436 | if (le->state == BT_OPEN) | 438 | if (le->state == BT_OPEN) |
437 | hci_le_connect(le); | 439 | hci_le_connect(le); |
438 | 440 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 98b5764e4315..3fbfa50c2bff 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -796,6 +796,29 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | |||
796 | hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); | 796 | hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); |
797 | } | 797 | } |
798 | 798 | ||
799 | static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
800 | { | ||
801 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | ||
802 | |||
803 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
804 | |||
805 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
806 | mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr, | ||
807 | rp->status); | ||
808 | } | ||
809 | |||
810 | static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | ||
811 | struct sk_buff *skb) | ||
812 | { | ||
813 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | ||
814 | |||
815 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
816 | |||
817 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
818 | mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr, | ||
819 | rp->status); | ||
820 | } | ||
821 | |||
799 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 822 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
800 | { | 823 | { |
801 | BT_DBG("%s status 0x%x", hdev->name, status); | 824 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -1401,8 +1424,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1401 | if (!ev->status) { | 1424 | if (!ev->status) { |
1402 | conn->link_mode |= HCI_LM_AUTH; | 1425 | conn->link_mode |= HCI_LM_AUTH; |
1403 | conn->sec_level = conn->pending_sec_level; | 1426 | conn->sec_level = conn->pending_sec_level; |
1404 | } else | 1427 | } else { |
1428 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
1405 | conn->sec_level = BT_SECURITY_LOW; | 1429 | conn->sec_level = BT_SECURITY_LOW; |
1430 | } | ||
1406 | 1431 | ||
1407 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1432 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
1408 | 1433 | ||
@@ -1728,6 +1753,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1728 | hci_cc_le_read_buffer_size(hdev, skb); | 1753 | hci_cc_le_read_buffer_size(hdev, skb); |
1729 | break; | 1754 | break; |
1730 | 1755 | ||
1756 | case HCI_OP_USER_CONFIRM_REPLY: | ||
1757 | hci_cc_user_confirm_reply(hdev, skb); | ||
1758 | break; | ||
1759 | |||
1760 | case HCI_OP_USER_CONFIRM_NEG_REPLY: | ||
1761 | hci_cc_user_confirm_neg_reply(hdev, skb); | ||
1762 | break; | ||
1763 | |||
1731 | default: | 1764 | default: |
1732 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1765 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1733 | break; | 1766 | break; |
@@ -2362,6 +2395,21 @@ unlock: | |||
2362 | hci_dev_unlock(hdev); | 2395 | hci_dev_unlock(hdev); |
2363 | } | 2396 | } |
2364 | 2397 | ||
2398 | static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, | ||
2399 | struct sk_buff *skb) | ||
2400 | { | ||
2401 | struct hci_ev_user_confirm_req *ev = (void *) skb->data; | ||
2402 | |||
2403 | BT_DBG("%s", hdev->name); | ||
2404 | |||
2405 | hci_dev_lock(hdev); | ||
2406 | |||
2407 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2408 | mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey); | ||
2409 | |||
2410 | hci_dev_unlock(hdev); | ||
2411 | } | ||
2412 | |||
2365 | static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2413 | static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2366 | { | 2414 | { |
2367 | struct hci_ev_simple_pair_complete *ev = (void *) skb->data; | 2415 | struct hci_ev_simple_pair_complete *ev = (void *) skb->data; |
@@ -2372,9 +2420,20 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ | |||
2372 | hci_dev_lock(hdev); | 2420 | hci_dev_lock(hdev); |
2373 | 2421 | ||
2374 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 2422 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
2375 | if (conn) | 2423 | if (!conn) |
2376 | hci_conn_put(conn); | 2424 | goto unlock; |
2377 | 2425 | ||
2426 | /* To avoid duplicate auth_failed events to user space we check | ||
2427 | * the HCI_CONN_AUTH_PEND flag which will be set if we | ||
2428 | * initiated the authentication. A traditional auth_complete | ||
2429 | * event gets always produced as initiator and is also mapped to | ||
2430 | * the mgmt_auth_failed event */ | ||
2431 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) | ||
2432 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
2433 | |||
2434 | hci_conn_put(conn); | ||
2435 | |||
2436 | unlock: | ||
2378 | hci_dev_unlock(hdev); | 2437 | hci_dev_unlock(hdev); |
2379 | } | 2438 | } |
2380 | 2439 | ||
@@ -2580,6 +2639,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2580 | hci_io_capa_reply_evt(hdev, skb); | 2639 | hci_io_capa_reply_evt(hdev, skb); |
2581 | break; | 2640 | break; |
2582 | 2641 | ||
2642 | case HCI_EV_USER_CONFIRM_REQUEST: | ||
2643 | hci_user_confirm_request_evt(hdev, skb); | ||
2644 | break; | ||
2645 | |||
2583 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 2646 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
2584 | hci_simple_pair_complete_evt(hdev, skb); | 2647 | hci_simple_pair_complete_evt(hdev, skb); |
2585 | break; | 2648 | break; |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index d50e96136608..295e4a88fff8 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -861,7 +861,7 @@ error: | |||
861 | return err; | 861 | return err; |
862 | } | 862 | } |
863 | 863 | ||
864 | void __exit hci_sock_cleanup(void) | 864 | void hci_sock_cleanup(void) |
865 | { | 865 | { |
866 | if (bt_sock_unregister(BTPROTO_HCI) < 0) | 866 | if (bt_sock_unregister(BTPROTO_HCI) < 0) |
867 | BT_ERR("HCI socket unregistration failed"); | 867 | BT_ERR("HCI socket unregistration failed"); |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index efcef0dc1259..c9f9cecca527 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -852,8 +852,6 @@ int l2cap_do_connect(struct sock *sk) | |||
852 | 852 | ||
853 | hci_dev_lock_bh(hdev); | 853 | hci_dev_lock_bh(hdev); |
854 | 854 | ||
855 | err = -ENOMEM; | ||
856 | |||
857 | auth_type = l2cap_get_auth_type(sk); | 855 | auth_type = l2cap_get_auth_type(sk); |
858 | 856 | ||
859 | if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA) | 857 | if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA) |
@@ -863,17 +861,18 @@ int l2cap_do_connect(struct sock *sk) | |||
863 | hcon = hci_connect(hdev, ACL_LINK, dst, | 861 | hcon = hci_connect(hdev, ACL_LINK, dst, |
864 | l2cap_pi(sk)->sec_level, auth_type); | 862 | l2cap_pi(sk)->sec_level, auth_type); |
865 | 863 | ||
866 | if (!hcon) | 864 | if (IS_ERR(hcon)) { |
865 | err = PTR_ERR(hcon); | ||
867 | goto done; | 866 | goto done; |
867 | } | ||
868 | 868 | ||
869 | conn = l2cap_conn_add(hcon, 0); | 869 | conn = l2cap_conn_add(hcon, 0); |
870 | if (!conn) { | 870 | if (!conn) { |
871 | hci_conn_put(hcon); | 871 | hci_conn_put(hcon); |
872 | err = -ENOMEM; | ||
872 | goto done; | 873 | goto done; |
873 | } | 874 | } |
874 | 875 | ||
875 | err = 0; | ||
876 | |||
877 | /* Update source addr of the socket */ | 876 | /* Update source addr of the socket */ |
878 | bacpy(src, conn->src); | 877 | bacpy(src, conn->src); |
879 | 878 | ||
@@ -892,6 +891,8 @@ int l2cap_do_connect(struct sock *sk) | |||
892 | l2cap_do_start(sk); | 891 | l2cap_do_start(sk); |
893 | } | 892 | } |
894 | 893 | ||
894 | err = 0; | ||
895 | |||
895 | done: | 896 | done: |
896 | hci_dev_unlock_bh(hdev); | 897 | hci_dev_unlock_bh(hdev); |
897 | hci_dev_put(hdev); | 898 | hci_dev_put(hdev); |
@@ -4033,8 +4034,6 @@ int __init l2cap_init(void) | |||
4033 | BT_ERR("Failed to create L2CAP debug file"); | 4034 | BT_ERR("Failed to create L2CAP debug file"); |
4034 | } | 4035 | } |
4035 | 4036 | ||
4036 | BT_INFO("L2CAP socket layer initialized"); | ||
4037 | |||
4038 | return 0; | 4037 | return 0; |
4039 | 4038 | ||
4040 | error: | 4039 | error: |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index f5ef7a3374c7..0054c74e27b7 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -38,17 +38,18 @@ struct pending_cmd { | |||
38 | int index; | 38 | int index; |
39 | void *cmd; | 39 | void *cmd; |
40 | struct sock *sk; | 40 | struct sock *sk; |
41 | void *user_data; | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | LIST_HEAD(cmd_list); | 44 | LIST_HEAD(cmd_list); |
44 | 45 | ||
45 | static int cmd_status(struct sock *sk, u16 cmd, u8 status) | 46 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) |
46 | { | 47 | { |
47 | struct sk_buff *skb; | 48 | struct sk_buff *skb; |
48 | struct mgmt_hdr *hdr; | 49 | struct mgmt_hdr *hdr; |
49 | struct mgmt_ev_cmd_status *ev; | 50 | struct mgmt_ev_cmd_status *ev; |
50 | 51 | ||
51 | BT_DBG("sock %p", sk); | 52 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); |
52 | 53 | ||
53 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); | 54 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); |
54 | if (!skb) | 55 | if (!skb) |
@@ -57,6 +58,7 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status) | |||
57 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 58 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
58 | 59 | ||
59 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); | 60 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); |
61 | hdr->index = cpu_to_le16(index); | ||
60 | hdr->len = cpu_to_le16(sizeof(*ev)); | 62 | hdr->len = cpu_to_le16(sizeof(*ev)); |
61 | 63 | ||
62 | ev = (void *) skb_put(skb, sizeof(*ev)); | 64 | ev = (void *) skb_put(skb, sizeof(*ev)); |
@@ -69,7 +71,8 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status) | |||
69 | return 0; | 71 | return 0; |
70 | } | 72 | } |
71 | 73 | ||
72 | static int cmd_complete(struct sock *sk, u16 cmd, void *rp, size_t rp_len) | 74 | static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, |
75 | size_t rp_len) | ||
73 | { | 76 | { |
74 | struct sk_buff *skb; | 77 | struct sk_buff *skb; |
75 | struct mgmt_hdr *hdr; | 78 | struct mgmt_hdr *hdr; |
@@ -84,11 +87,14 @@ static int cmd_complete(struct sock *sk, u16 cmd, void *rp, size_t rp_len) | |||
84 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 87 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
85 | 88 | ||
86 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); | 89 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); |
90 | hdr->index = cpu_to_le16(index); | ||
87 | hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); | 91 | hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); |
88 | 92 | ||
89 | ev = (void *) skb_put(skb, sizeof(*ev) + rp_len); | 93 | ev = (void *) skb_put(skb, sizeof(*ev) + rp_len); |
90 | put_unaligned_le16(cmd, &ev->opcode); | 94 | put_unaligned_le16(cmd, &ev->opcode); |
91 | memcpy(ev->data, rp, rp_len); | 95 | |
96 | if (rp) | ||
97 | memcpy(ev->data, rp, rp_len); | ||
92 | 98 | ||
93 | if (sock_queue_rcv_skb(sk, skb) < 0) | 99 | if (sock_queue_rcv_skb(sk, skb) < 0) |
94 | kfree_skb(skb); | 100 | kfree_skb(skb); |
@@ -105,7 +111,8 @@ static int read_version(struct sock *sk) | |||
105 | rp.version = MGMT_VERSION; | 111 | rp.version = MGMT_VERSION; |
106 | put_unaligned_le16(MGMT_REVISION, &rp.revision); | 112 | put_unaligned_le16(MGMT_REVISION, &rp.revision); |
107 | 113 | ||
108 | return cmd_complete(sk, MGMT_OP_READ_VERSION, &rp, sizeof(rp)); | 114 | return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, &rp, |
115 | sizeof(rp)); | ||
109 | } | 116 | } |
110 | 117 | ||
111 | static int read_index_list(struct sock *sk) | 118 | static int read_index_list(struct sock *sk) |
@@ -151,32 +158,24 @@ static int read_index_list(struct sock *sk) | |||
151 | 158 | ||
152 | read_unlock(&hci_dev_list_lock); | 159 | read_unlock(&hci_dev_list_lock); |
153 | 160 | ||
154 | err = cmd_complete(sk, MGMT_OP_READ_INDEX_LIST, rp, rp_len); | 161 | err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, rp, |
162 | rp_len); | ||
155 | 163 | ||
156 | kfree(rp); | 164 | kfree(rp); |
157 | 165 | ||
158 | return err; | 166 | return err; |
159 | } | 167 | } |
160 | 168 | ||
161 | static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) | 169 | static int read_controller_info(struct sock *sk, u16 index) |
162 | { | 170 | { |
163 | struct mgmt_rp_read_info rp; | 171 | struct mgmt_rp_read_info rp; |
164 | struct mgmt_cp_read_info *cp = (void *) data; | ||
165 | struct hci_dev *hdev; | 172 | struct hci_dev *hdev; |
166 | u16 dev_id; | ||
167 | |||
168 | BT_DBG("sock %p", sk); | ||
169 | 173 | ||
170 | if (len != 2) | 174 | BT_DBG("sock %p hci%u", sk, index); |
171 | return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL); | ||
172 | 175 | ||
173 | dev_id = get_unaligned_le16(&cp->index); | 176 | hdev = hci_dev_get(index); |
174 | |||
175 | BT_DBG("request for hci%u", dev_id); | ||
176 | |||
177 | hdev = hci_dev_get(dev_id); | ||
178 | if (!hdev) | 177 | if (!hdev) |
179 | return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV); | 178 | return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV); |
180 | 179 | ||
181 | hci_del_off_timer(hdev); | 180 | hci_del_off_timer(hdev); |
182 | 181 | ||
@@ -184,7 +183,6 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) | |||
184 | 183 | ||
185 | set_bit(HCI_MGMT, &hdev->flags); | 184 | set_bit(HCI_MGMT, &hdev->flags); |
186 | 185 | ||
187 | put_unaligned_le16(hdev->id, &rp.index); | ||
188 | rp.type = hdev->dev_type; | 186 | rp.type = hdev->dev_type; |
189 | 187 | ||
190 | rp.powered = test_bit(HCI_UP, &hdev->flags); | 188 | rp.powered = test_bit(HCI_UP, &hdev->flags); |
@@ -209,7 +207,7 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) | |||
209 | hci_dev_unlock_bh(hdev); | 207 | hci_dev_unlock_bh(hdev); |
210 | hci_dev_put(hdev); | 208 | hci_dev_put(hdev); |
211 | 209 | ||
212 | return cmd_complete(sk, MGMT_OP_READ_INFO, &rp, sizeof(rp)); | 210 | return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp)); |
213 | } | 211 | } |
214 | 212 | ||
215 | static void mgmt_pending_free(struct pending_cmd *cmd) | 213 | static void mgmt_pending_free(struct pending_cmd *cmd) |
@@ -219,14 +217,14 @@ static void mgmt_pending_free(struct pending_cmd *cmd) | |||
219 | kfree(cmd); | 217 | kfree(cmd); |
220 | } | 218 | } |
221 | 219 | ||
222 | static int mgmt_pending_add(struct sock *sk, u16 opcode, int index, | 220 | static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, |
223 | void *data, u16 len) | 221 | u16 index, void *data, u16 len) |
224 | { | 222 | { |
225 | struct pending_cmd *cmd; | 223 | struct pending_cmd *cmd; |
226 | 224 | ||
227 | cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); | 225 | cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); |
228 | if (!cmd) | 226 | if (!cmd) |
229 | return -ENOMEM; | 227 | return NULL; |
230 | 228 | ||
231 | cmd->opcode = opcode; | 229 | cmd->opcode = opcode; |
232 | cmd->index = index; | 230 | cmd->index = index; |
@@ -234,7 +232,7 @@ static int mgmt_pending_add(struct sock *sk, u16 opcode, int index, | |||
234 | cmd->cmd = kmalloc(len, GFP_ATOMIC); | 232 | cmd->cmd = kmalloc(len, GFP_ATOMIC); |
235 | if (!cmd->cmd) { | 233 | if (!cmd->cmd) { |
236 | kfree(cmd); | 234 | kfree(cmd); |
237 | return -ENOMEM; | 235 | return NULL; |
238 | } | 236 | } |
239 | 237 | ||
240 | memcpy(cmd->cmd, data, len); | 238 | memcpy(cmd->cmd, data, len); |
@@ -244,7 +242,7 @@ static int mgmt_pending_add(struct sock *sk, u16 opcode, int index, | |||
244 | 242 | ||
245 | list_add(&cmd->list, &cmd_list); | 243 | list_add(&cmd->list, &cmd_list); |
246 | 244 | ||
247 | return 0; | 245 | return cmd; |
248 | } | 246 | } |
249 | 247 | ||
250 | static void mgmt_pending_foreach(u16 opcode, int index, | 248 | static void mgmt_pending_foreach(u16 opcode, int index, |
@@ -289,103 +287,106 @@ static struct pending_cmd *mgmt_pending_find(u16 opcode, int index) | |||
289 | return NULL; | 287 | return NULL; |
290 | } | 288 | } |
291 | 289 | ||
292 | static void mgmt_pending_remove(u16 opcode, int index) | 290 | static void mgmt_pending_remove(struct pending_cmd *cmd) |
293 | { | 291 | { |
294 | struct pending_cmd *cmd; | ||
295 | |||
296 | cmd = mgmt_pending_find(opcode, index); | ||
297 | if (cmd == NULL) | ||
298 | return; | ||
299 | |||
300 | list_del(&cmd->list); | 292 | list_del(&cmd->list); |
301 | mgmt_pending_free(cmd); | 293 | mgmt_pending_free(cmd); |
302 | } | 294 | } |
303 | 295 | ||
304 | static int set_powered(struct sock *sk, unsigned char *data, u16 len) | 296 | static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) |
305 | { | 297 | { |
306 | struct mgmt_mode *cp; | 298 | struct mgmt_mode *cp; |
307 | struct hci_dev *hdev; | 299 | struct hci_dev *hdev; |
308 | u16 dev_id; | 300 | struct pending_cmd *cmd; |
309 | int ret, up; | 301 | int err, up; |
310 | 302 | ||
311 | cp = (void *) data; | 303 | cp = (void *) data; |
312 | dev_id = get_unaligned_le16(&cp->index); | ||
313 | 304 | ||
314 | BT_DBG("request for hci%u", dev_id); | 305 | BT_DBG("request for hci%u", index); |
306 | |||
307 | if (len != sizeof(*cp)) | ||
308 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, EINVAL); | ||
315 | 309 | ||
316 | hdev = hci_dev_get(dev_id); | 310 | hdev = hci_dev_get(index); |
317 | if (!hdev) | 311 | if (!hdev) |
318 | return cmd_status(sk, MGMT_OP_SET_POWERED, ENODEV); | 312 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV); |
319 | 313 | ||
320 | hci_dev_lock_bh(hdev); | 314 | hci_dev_lock_bh(hdev); |
321 | 315 | ||
322 | up = test_bit(HCI_UP, &hdev->flags); | 316 | up = test_bit(HCI_UP, &hdev->flags); |
323 | if ((cp->val && up) || (!cp->val && !up)) { | 317 | if ((cp->val && up) || (!cp->val && !up)) { |
324 | ret = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY); | 318 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EALREADY); |
325 | goto failed; | 319 | goto failed; |
326 | } | 320 | } |
327 | 321 | ||
328 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, dev_id)) { | 322 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, index)) { |
329 | ret = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY); | 323 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY); |
330 | goto failed; | 324 | goto failed; |
331 | } | 325 | } |
332 | 326 | ||
333 | ret = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len); | 327 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data, len); |
334 | if (ret < 0) | 328 | if (!cmd) { |
329 | err = -ENOMEM; | ||
335 | goto failed; | 330 | goto failed; |
331 | } | ||
336 | 332 | ||
337 | if (cp->val) | 333 | if (cp->val) |
338 | queue_work(hdev->workqueue, &hdev->power_on); | 334 | queue_work(hdev->workqueue, &hdev->power_on); |
339 | else | 335 | else |
340 | queue_work(hdev->workqueue, &hdev->power_off); | 336 | queue_work(hdev->workqueue, &hdev->power_off); |
341 | 337 | ||
342 | ret = 0; | 338 | err = 0; |
343 | 339 | ||
344 | failed: | 340 | failed: |
345 | hci_dev_unlock_bh(hdev); | 341 | hci_dev_unlock_bh(hdev); |
346 | hci_dev_put(hdev); | 342 | hci_dev_put(hdev); |
347 | return ret; | 343 | return err; |
348 | } | 344 | } |
349 | 345 | ||
350 | static int set_discoverable(struct sock *sk, unsigned char *data, u16 len) | 346 | static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, |
347 | u16 len) | ||
351 | { | 348 | { |
352 | struct mgmt_mode *cp; | 349 | struct mgmt_mode *cp; |
353 | struct hci_dev *hdev; | 350 | struct hci_dev *hdev; |
354 | u16 dev_id; | 351 | struct pending_cmd *cmd; |
355 | u8 scan; | 352 | u8 scan; |
356 | int err; | 353 | int err; |
357 | 354 | ||
358 | cp = (void *) data; | 355 | cp = (void *) data; |
359 | dev_id = get_unaligned_le16(&cp->index); | ||
360 | 356 | ||
361 | BT_DBG("request for hci%u", dev_id); | 357 | BT_DBG("request for hci%u", index); |
358 | |||
359 | if (len != sizeof(*cp)) | ||
360 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EINVAL); | ||
362 | 361 | ||
363 | hdev = hci_dev_get(dev_id); | 362 | hdev = hci_dev_get(index); |
364 | if (!hdev) | 363 | if (!hdev) |
365 | return cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENODEV); | 364 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV); |
366 | 365 | ||
367 | hci_dev_lock_bh(hdev); | 366 | hci_dev_lock_bh(hdev); |
368 | 367 | ||
369 | if (!test_bit(HCI_UP, &hdev->flags)) { | 368 | if (!test_bit(HCI_UP, &hdev->flags)) { |
370 | err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENETDOWN); | 369 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN); |
371 | goto failed; | 370 | goto failed; |
372 | } | 371 | } |
373 | 372 | ||
374 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) || | 373 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || |
375 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) { | 374 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { |
376 | err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EBUSY); | 375 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY); |
377 | goto failed; | 376 | goto failed; |
378 | } | 377 | } |
379 | 378 | ||
380 | if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) && | 379 | if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) && |
381 | test_bit(HCI_PSCAN, &hdev->flags)) { | 380 | test_bit(HCI_PSCAN, &hdev->flags)) { |
382 | err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EALREADY); | 381 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EALREADY); |
383 | goto failed; | 382 | goto failed; |
384 | } | 383 | } |
385 | 384 | ||
386 | err = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len); | 385 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, index, data, len); |
387 | if (err < 0) | 386 | if (!cmd) { |
387 | err = -ENOMEM; | ||
388 | goto failed; | 388 | goto failed; |
389 | } | ||
389 | 390 | ||
390 | scan = SCAN_PAGE; | 391 | scan = SCAN_PAGE; |
391 | 392 | ||
@@ -394,7 +395,7 @@ static int set_discoverable(struct sock *sk, unsigned char *data, u16 len) | |||
394 | 395 | ||
395 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 396 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
396 | if (err < 0) | 397 | if (err < 0) |
397 | mgmt_pending_remove(MGMT_OP_SET_DISCOVERABLE, dev_id); | 398 | mgmt_pending_remove(cmd); |
398 | 399 | ||
399 | failed: | 400 | failed: |
400 | hci_dev_unlock_bh(hdev); | 401 | hci_dev_unlock_bh(hdev); |
@@ -403,44 +404,49 @@ failed: | |||
403 | return err; | 404 | return err; |
404 | } | 405 | } |
405 | 406 | ||
406 | static int set_connectable(struct sock *sk, unsigned char *data, u16 len) | 407 | static int set_connectable(struct sock *sk, u16 index, unsigned char *data, |
408 | u16 len) | ||
407 | { | 409 | { |
408 | struct mgmt_mode *cp; | 410 | struct mgmt_mode *cp; |
409 | struct hci_dev *hdev; | 411 | struct hci_dev *hdev; |
410 | u16 dev_id; | 412 | struct pending_cmd *cmd; |
411 | u8 scan; | 413 | u8 scan; |
412 | int err; | 414 | int err; |
413 | 415 | ||
414 | cp = (void *) data; | 416 | cp = (void *) data; |
415 | dev_id = get_unaligned_le16(&cp->index); | ||
416 | 417 | ||
417 | BT_DBG("request for hci%u", dev_id); | 418 | BT_DBG("request for hci%u", index); |
419 | |||
420 | if (len != sizeof(*cp)) | ||
421 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EINVAL); | ||
418 | 422 | ||
419 | hdev = hci_dev_get(dev_id); | 423 | hdev = hci_dev_get(index); |
420 | if (!hdev) | 424 | if (!hdev) |
421 | return cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENODEV); | 425 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV); |
422 | 426 | ||
423 | hci_dev_lock_bh(hdev); | 427 | hci_dev_lock_bh(hdev); |
424 | 428 | ||
425 | if (!test_bit(HCI_UP, &hdev->flags)) { | 429 | if (!test_bit(HCI_UP, &hdev->flags)) { |
426 | err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENETDOWN); | 430 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN); |
427 | goto failed; | 431 | goto failed; |
428 | } | 432 | } |
429 | 433 | ||
430 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) || | 434 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || |
431 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) { | 435 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { |
432 | err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EBUSY); | 436 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY); |
433 | goto failed; | 437 | goto failed; |
434 | } | 438 | } |
435 | 439 | ||
436 | if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) { | 440 | if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) { |
437 | err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EALREADY); | 441 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EALREADY); |
438 | goto failed; | 442 | goto failed; |
439 | } | 443 | } |
440 | 444 | ||
441 | err = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len); | 445 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, index, data, len); |
442 | if (err < 0) | 446 | if (!cmd) { |
447 | err = -ENOMEM; | ||
443 | goto failed; | 448 | goto failed; |
449 | } | ||
444 | 450 | ||
445 | if (cp->val) | 451 | if (cp->val) |
446 | scan = SCAN_PAGE; | 452 | scan = SCAN_PAGE; |
@@ -449,7 +455,7 @@ static int set_connectable(struct sock *sk, unsigned char *data, u16 len) | |||
449 | 455 | ||
450 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 456 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
451 | if (err < 0) | 457 | if (err < 0) |
452 | mgmt_pending_remove(MGMT_OP_SET_CONNECTABLE, dev_id); | 458 | mgmt_pending_remove(cmd); |
453 | 459 | ||
454 | failed: | 460 | failed: |
455 | hci_dev_unlock_bh(hdev); | 461 | hci_dev_unlock_bh(hdev); |
@@ -458,7 +464,8 @@ failed: | |||
458 | return err; | 464 | return err; |
459 | } | 465 | } |
460 | 466 | ||
461 | static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk) | 467 | static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, |
468 | struct sock *skip_sk) | ||
462 | { | 469 | { |
463 | struct sk_buff *skb; | 470 | struct sk_buff *skb; |
464 | struct mgmt_hdr *hdr; | 471 | struct mgmt_hdr *hdr; |
@@ -471,9 +478,11 @@ static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk) | |||
471 | 478 | ||
472 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 479 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
473 | hdr->opcode = cpu_to_le16(event); | 480 | hdr->opcode = cpu_to_le16(event); |
481 | hdr->index = cpu_to_le16(index); | ||
474 | hdr->len = cpu_to_le16(data_len); | 482 | hdr->len = cpu_to_le16(data_len); |
475 | 483 | ||
476 | memcpy(skb_put(skb, data_len), data, data_len); | 484 | if (data) |
485 | memcpy(skb_put(skb, data_len), data, data_len); | ||
477 | 486 | ||
478 | hci_send_to_sock(NULL, skb, skip_sk); | 487 | hci_send_to_sock(NULL, skb, skip_sk); |
479 | kfree_skb(skb); | 488 | kfree_skb(skb); |
@@ -485,27 +494,28 @@ static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val) | |||
485 | { | 494 | { |
486 | struct mgmt_mode rp; | 495 | struct mgmt_mode rp; |
487 | 496 | ||
488 | put_unaligned_le16(index, &rp.index); | ||
489 | rp.val = val; | 497 | rp.val = val; |
490 | 498 | ||
491 | return cmd_complete(sk, opcode, &rp, sizeof(rp)); | 499 | return cmd_complete(sk, index, opcode, &rp, sizeof(rp)); |
492 | } | 500 | } |
493 | 501 | ||
494 | static int set_pairable(struct sock *sk, unsigned char *data, u16 len) | 502 | static int set_pairable(struct sock *sk, u16 index, unsigned char *data, |
503 | u16 len) | ||
495 | { | 504 | { |
496 | struct mgmt_mode *cp, ev; | 505 | struct mgmt_mode *cp, ev; |
497 | struct hci_dev *hdev; | 506 | struct hci_dev *hdev; |
498 | u16 dev_id; | ||
499 | int err; | 507 | int err; |
500 | 508 | ||
501 | cp = (void *) data; | 509 | cp = (void *) data; |
502 | dev_id = get_unaligned_le16(&cp->index); | ||
503 | 510 | ||
504 | BT_DBG("request for hci%u", dev_id); | 511 | BT_DBG("request for hci%u", index); |
512 | |||
513 | if (len != sizeof(*cp)) | ||
514 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, EINVAL); | ||
505 | 515 | ||
506 | hdev = hci_dev_get(dev_id); | 516 | hdev = hci_dev_get(index); |
507 | if (!hdev) | 517 | if (!hdev) |
508 | return cmd_status(sk, MGMT_OP_SET_PAIRABLE, ENODEV); | 518 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV); |
509 | 519 | ||
510 | hci_dev_lock_bh(hdev); | 520 | hci_dev_lock_bh(hdev); |
511 | 521 | ||
@@ -514,14 +524,13 @@ static int set_pairable(struct sock *sk, unsigned char *data, u16 len) | |||
514 | else | 524 | else |
515 | clear_bit(HCI_PAIRABLE, &hdev->flags); | 525 | clear_bit(HCI_PAIRABLE, &hdev->flags); |
516 | 526 | ||
517 | err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, dev_id, cp->val); | 527 | err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, index, cp->val); |
518 | if (err < 0) | 528 | if (err < 0) |
519 | goto failed; | 529 | goto failed; |
520 | 530 | ||
521 | put_unaligned_le16(dev_id, &ev.index); | ||
522 | ev.val = cp->val; | 531 | ev.val = cp->val; |
523 | 532 | ||
524 | err = mgmt_event(MGMT_EV_PAIRABLE, &ev, sizeof(ev), sk); | 533 | err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); |
525 | 534 | ||
526 | failed: | 535 | failed: |
527 | hci_dev_unlock_bh(hdev); | 536 | hci_dev_unlock_bh(hdev); |
@@ -563,22 +572,23 @@ static int update_class(struct hci_dev *hdev) | |||
563 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | 572 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); |
564 | } | 573 | } |
565 | 574 | ||
566 | static int add_uuid(struct sock *sk, unsigned char *data, u16 len) | 575 | static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) |
567 | { | 576 | { |
568 | struct mgmt_cp_add_uuid *cp; | 577 | struct mgmt_cp_add_uuid *cp; |
569 | struct hci_dev *hdev; | 578 | struct hci_dev *hdev; |
570 | struct bt_uuid *uuid; | 579 | struct bt_uuid *uuid; |
571 | u16 dev_id; | ||
572 | int err; | 580 | int err; |
573 | 581 | ||
574 | cp = (void *) data; | 582 | cp = (void *) data; |
575 | dev_id = get_unaligned_le16(&cp->index); | ||
576 | 583 | ||
577 | BT_DBG("request for hci%u", dev_id); | 584 | BT_DBG("request for hci%u", index); |
578 | 585 | ||
579 | hdev = hci_dev_get(dev_id); | 586 | if (len != sizeof(*cp)) |
587 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, EINVAL); | ||
588 | |||
589 | hdev = hci_dev_get(index); | ||
580 | if (!hdev) | 590 | if (!hdev) |
581 | return cmd_status(sk, MGMT_OP_ADD_UUID, ENODEV); | 591 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV); |
582 | 592 | ||
583 | hci_dev_lock_bh(hdev); | 593 | hci_dev_lock_bh(hdev); |
584 | 594 | ||
@@ -597,7 +607,7 @@ static int add_uuid(struct sock *sk, unsigned char *data, u16 len) | |||
597 | if (err < 0) | 607 | if (err < 0) |
598 | goto failed; | 608 | goto failed; |
599 | 609 | ||
600 | err = cmd_complete(sk, MGMT_OP_ADD_UUID, &dev_id, sizeof(dev_id)); | 610 | err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0); |
601 | 611 | ||
602 | failed: | 612 | failed: |
603 | hci_dev_unlock_bh(hdev); | 613 | hci_dev_unlock_bh(hdev); |
@@ -606,23 +616,24 @@ failed: | |||
606 | return err; | 616 | return err; |
607 | } | 617 | } |
608 | 618 | ||
609 | static int remove_uuid(struct sock *sk, unsigned char *data, u16 len) | 619 | static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) |
610 | { | 620 | { |
611 | struct list_head *p, *n; | 621 | struct list_head *p, *n; |
612 | struct mgmt_cp_add_uuid *cp; | 622 | struct mgmt_cp_remove_uuid *cp; |
613 | struct hci_dev *hdev; | 623 | struct hci_dev *hdev; |
614 | u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | 624 | u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
615 | u16 dev_id; | ||
616 | int err, found; | 625 | int err, found; |
617 | 626 | ||
618 | cp = (void *) data; | 627 | cp = (void *) data; |
619 | dev_id = get_unaligned_le16(&cp->index); | ||
620 | 628 | ||
621 | BT_DBG("request for hci%u", dev_id); | 629 | BT_DBG("request for hci%u", index); |
630 | |||
631 | if (len != sizeof(*cp)) | ||
632 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, EINVAL); | ||
622 | 633 | ||
623 | hdev = hci_dev_get(dev_id); | 634 | hdev = hci_dev_get(index); |
624 | if (!hdev) | 635 | if (!hdev) |
625 | return cmd_status(sk, MGMT_OP_REMOVE_UUID, ENODEV); | 636 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV); |
626 | 637 | ||
627 | hci_dev_lock_bh(hdev); | 638 | hci_dev_lock_bh(hdev); |
628 | 639 | ||
@@ -644,7 +655,7 @@ static int remove_uuid(struct sock *sk, unsigned char *data, u16 len) | |||
644 | } | 655 | } |
645 | 656 | ||
646 | if (found == 0) { | 657 | if (found == 0) { |
647 | err = cmd_status(sk, MGMT_OP_REMOVE_UUID, ENOENT); | 658 | err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENOENT); |
648 | goto unlock; | 659 | goto unlock; |
649 | } | 660 | } |
650 | 661 | ||
@@ -652,7 +663,7 @@ static int remove_uuid(struct sock *sk, unsigned char *data, u16 len) | |||
652 | if (err < 0) | 663 | if (err < 0) |
653 | goto unlock; | 664 | goto unlock; |
654 | 665 | ||
655 | err = cmd_complete(sk, MGMT_OP_REMOVE_UUID, &dev_id, sizeof(dev_id)); | 666 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0); |
656 | 667 | ||
657 | unlock: | 668 | unlock: |
658 | hci_dev_unlock_bh(hdev); | 669 | hci_dev_unlock_bh(hdev); |
@@ -661,21 +672,23 @@ unlock: | |||
661 | return err; | 672 | return err; |
662 | } | 673 | } |
663 | 674 | ||
664 | static int set_dev_class(struct sock *sk, unsigned char *data, u16 len) | 675 | static int set_dev_class(struct sock *sk, u16 index, unsigned char *data, |
676 | u16 len) | ||
665 | { | 677 | { |
666 | struct hci_dev *hdev; | 678 | struct hci_dev *hdev; |
667 | struct mgmt_cp_set_dev_class *cp; | 679 | struct mgmt_cp_set_dev_class *cp; |
668 | u16 dev_id; | ||
669 | int err; | 680 | int err; |
670 | 681 | ||
671 | cp = (void *) data; | 682 | cp = (void *) data; |
672 | dev_id = get_unaligned_le16(&cp->index); | ||
673 | 683 | ||
674 | BT_DBG("request for hci%u", dev_id); | 684 | BT_DBG("request for hci%u", index); |
675 | 685 | ||
676 | hdev = hci_dev_get(dev_id); | 686 | if (len != sizeof(*cp)) |
687 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, EINVAL); | ||
688 | |||
689 | hdev = hci_dev_get(index); | ||
677 | if (!hdev) | 690 | if (!hdev) |
678 | return cmd_status(sk, MGMT_OP_SET_DEV_CLASS, ENODEV); | 691 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV); |
679 | 692 | ||
680 | hci_dev_lock_bh(hdev); | 693 | hci_dev_lock_bh(hdev); |
681 | 694 | ||
@@ -685,8 +698,7 @@ static int set_dev_class(struct sock *sk, unsigned char *data, u16 len) | |||
685 | err = update_class(hdev); | 698 | err = update_class(hdev); |
686 | 699 | ||
687 | if (err == 0) | 700 | if (err == 0) |
688 | err = cmd_complete(sk, MGMT_OP_SET_DEV_CLASS, &dev_id, | 701 | err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0); |
689 | sizeof(dev_id)); | ||
690 | 702 | ||
691 | hci_dev_unlock_bh(hdev); | 703 | hci_dev_unlock_bh(hdev); |
692 | hci_dev_put(hdev); | 704 | hci_dev_put(hdev); |
@@ -694,23 +706,25 @@ static int set_dev_class(struct sock *sk, unsigned char *data, u16 len) | |||
694 | return err; | 706 | return err; |
695 | } | 707 | } |
696 | 708 | ||
697 | static int set_service_cache(struct sock *sk, unsigned char *data, u16 len) | 709 | static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, |
710 | u16 len) | ||
698 | { | 711 | { |
699 | struct hci_dev *hdev; | 712 | struct hci_dev *hdev; |
700 | struct mgmt_cp_set_service_cache *cp; | 713 | struct mgmt_cp_set_service_cache *cp; |
701 | u16 dev_id; | ||
702 | int err; | 714 | int err; |
703 | 715 | ||
704 | cp = (void *) data; | 716 | cp = (void *) data; |
705 | dev_id = get_unaligned_le16(&cp->index); | ||
706 | 717 | ||
707 | hdev = hci_dev_get(dev_id); | 718 | if (len != sizeof(*cp)) |
719 | return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, EINVAL); | ||
720 | |||
721 | hdev = hci_dev_get(index); | ||
708 | if (!hdev) | 722 | if (!hdev) |
709 | return cmd_status(sk, MGMT_OP_SET_SERVICE_CACHE, ENODEV); | 723 | return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV); |
710 | 724 | ||
711 | hci_dev_lock_bh(hdev); | 725 | hci_dev_lock_bh(hdev); |
712 | 726 | ||
713 | BT_DBG("hci%u enable %d", dev_id, cp->enable); | 727 | BT_DBG("hci%u enable %d", index, cp->enable); |
714 | 728 | ||
715 | if (cp->enable) { | 729 | if (cp->enable) { |
716 | set_bit(HCI_SERVICE_CACHE, &hdev->flags); | 730 | set_bit(HCI_SERVICE_CACHE, &hdev->flags); |
@@ -721,8 +735,8 @@ static int set_service_cache(struct sock *sk, unsigned char *data, u16 len) | |||
721 | } | 735 | } |
722 | 736 | ||
723 | if (err == 0) | 737 | if (err == 0) |
724 | err = cmd_complete(sk, MGMT_OP_SET_SERVICE_CACHE, &dev_id, | 738 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, |
725 | sizeof(dev_id)); | 739 | 0); |
726 | 740 | ||
727 | hci_dev_unlock_bh(hdev); | 741 | hci_dev_unlock_bh(hdev); |
728 | hci_dev_put(hdev); | 742 | hci_dev_put(hdev); |
@@ -730,15 +744,18 @@ static int set_service_cache(struct sock *sk, unsigned char *data, u16 len) | |||
730 | return err; | 744 | return err; |
731 | } | 745 | } |
732 | 746 | ||
733 | static int load_keys(struct sock *sk, unsigned char *data, u16 len) | 747 | static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) |
734 | { | 748 | { |
735 | struct hci_dev *hdev; | 749 | struct hci_dev *hdev; |
736 | struct mgmt_cp_load_keys *cp; | 750 | struct mgmt_cp_load_keys *cp; |
737 | u16 dev_id, key_count, expected_len; | 751 | u16 key_count, expected_len; |
738 | int i; | 752 | int i; |
739 | 753 | ||
740 | cp = (void *) data; | 754 | cp = (void *) data; |
741 | dev_id = get_unaligned_le16(&cp->index); | 755 | |
756 | if (len < sizeof(*cp)) | ||
757 | return -EINVAL; | ||
758 | |||
742 | key_count = get_unaligned_le16(&cp->key_count); | 759 | key_count = get_unaligned_le16(&cp->key_count); |
743 | 760 | ||
744 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); | 761 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); |
@@ -748,11 +765,11 @@ static int load_keys(struct sock *sk, unsigned char *data, u16 len) | |||
748 | return -EINVAL; | 765 | return -EINVAL; |
749 | } | 766 | } |
750 | 767 | ||
751 | hdev = hci_dev_get(dev_id); | 768 | hdev = hci_dev_get(index); |
752 | if (!hdev) | 769 | if (!hdev) |
753 | return cmd_status(sk, MGMT_OP_LOAD_KEYS, ENODEV); | 770 | return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV); |
754 | 771 | ||
755 | BT_DBG("hci%u debug_keys %u key_count %u", dev_id, cp->debug_keys, | 772 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, |
756 | key_count); | 773 | key_count); |
757 | 774 | ||
758 | hci_dev_lock_bh(hdev); | 775 | hci_dev_lock_bh(hdev); |
@@ -779,26 +796,27 @@ static int load_keys(struct sock *sk, unsigned char *data, u16 len) | |||
779 | return 0; | 796 | return 0; |
780 | } | 797 | } |
781 | 798 | ||
782 | static int remove_key(struct sock *sk, unsigned char *data, u16 len) | 799 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) |
783 | { | 800 | { |
784 | struct hci_dev *hdev; | 801 | struct hci_dev *hdev; |
785 | struct mgmt_cp_remove_key *cp; | 802 | struct mgmt_cp_remove_key *cp; |
786 | struct hci_conn *conn; | 803 | struct hci_conn *conn; |
787 | u16 dev_id; | ||
788 | int err; | 804 | int err; |
789 | 805 | ||
790 | cp = (void *) data; | 806 | cp = (void *) data; |
791 | dev_id = get_unaligned_le16(&cp->index); | ||
792 | 807 | ||
793 | hdev = hci_dev_get(dev_id); | 808 | if (len != sizeof(*cp)) |
809 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL); | ||
810 | |||
811 | hdev = hci_dev_get(index); | ||
794 | if (!hdev) | 812 | if (!hdev) |
795 | return cmd_status(sk, MGMT_OP_REMOVE_KEY, ENODEV); | 813 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); |
796 | 814 | ||
797 | hci_dev_lock_bh(hdev); | 815 | hci_dev_lock_bh(hdev); |
798 | 816 | ||
799 | err = hci_remove_link_key(hdev, &cp->bdaddr); | 817 | err = hci_remove_link_key(hdev, &cp->bdaddr); |
800 | if (err < 0) { | 818 | if (err < 0) { |
801 | err = cmd_status(sk, MGMT_OP_REMOVE_KEY, -err); | 819 | err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err); |
802 | goto unlock; | 820 | goto unlock; |
803 | } | 821 | } |
804 | 822 | ||
@@ -823,52 +841,56 @@ unlock: | |||
823 | return err; | 841 | return err; |
824 | } | 842 | } |
825 | 843 | ||
826 | static int disconnect(struct sock *sk, unsigned char *data, u16 len) | 844 | static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) |
827 | { | 845 | { |
828 | struct hci_dev *hdev; | 846 | struct hci_dev *hdev; |
829 | struct mgmt_cp_disconnect *cp; | 847 | struct mgmt_cp_disconnect *cp; |
830 | struct hci_cp_disconnect dc; | 848 | struct hci_cp_disconnect dc; |
849 | struct pending_cmd *cmd; | ||
831 | struct hci_conn *conn; | 850 | struct hci_conn *conn; |
832 | u16 dev_id; | ||
833 | int err; | 851 | int err; |
834 | 852 | ||
835 | BT_DBG(""); | 853 | BT_DBG(""); |
836 | 854 | ||
837 | cp = (void *) data; | 855 | cp = (void *) data; |
838 | dev_id = get_unaligned_le16(&cp->index); | ||
839 | 856 | ||
840 | hdev = hci_dev_get(dev_id); | 857 | if (len != sizeof(*cp)) |
858 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, EINVAL); | ||
859 | |||
860 | hdev = hci_dev_get(index); | ||
841 | if (!hdev) | 861 | if (!hdev) |
842 | return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV); | 862 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV); |
843 | 863 | ||
844 | hci_dev_lock_bh(hdev); | 864 | hci_dev_lock_bh(hdev); |
845 | 865 | ||
846 | if (!test_bit(HCI_UP, &hdev->flags)) { | 866 | if (!test_bit(HCI_UP, &hdev->flags)) { |
847 | err = cmd_status(sk, MGMT_OP_DISCONNECT, ENETDOWN); | 867 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN); |
848 | goto failed; | 868 | goto failed; |
849 | } | 869 | } |
850 | 870 | ||
851 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, dev_id)) { | 871 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) { |
852 | err = cmd_status(sk, MGMT_OP_DISCONNECT, EBUSY); | 872 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY); |
853 | goto failed; | 873 | goto failed; |
854 | } | 874 | } |
855 | 875 | ||
856 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | 876 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); |
857 | if (!conn) { | 877 | if (!conn) { |
858 | err = cmd_status(sk, MGMT_OP_DISCONNECT, ENOTCONN); | 878 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN); |
859 | goto failed; | 879 | goto failed; |
860 | } | 880 | } |
861 | 881 | ||
862 | err = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, dev_id, data, len); | 882 | cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len); |
863 | if (err < 0) | 883 | if (!cmd) { |
884 | err = -ENOMEM; | ||
864 | goto failed; | 885 | goto failed; |
886 | } | ||
865 | 887 | ||
866 | put_unaligned_le16(conn->handle, &dc.handle); | 888 | put_unaligned_le16(conn->handle, &dc.handle); |
867 | dc.reason = 0x13; /* Remote User Terminated Connection */ | 889 | dc.reason = 0x13; /* Remote User Terminated Connection */ |
868 | 890 | ||
869 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); | 891 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); |
870 | if (err < 0) | 892 | if (err < 0) |
871 | mgmt_pending_remove(MGMT_OP_DISCONNECT, dev_id); | 893 | mgmt_pending_remove(cmd); |
872 | 894 | ||
873 | failed: | 895 | failed: |
874 | hci_dev_unlock_bh(hdev); | 896 | hci_dev_unlock_bh(hdev); |
@@ -877,24 +899,20 @@ failed: | |||
877 | return err; | 899 | return err; |
878 | } | 900 | } |
879 | 901 | ||
880 | static int get_connections(struct sock *sk, unsigned char *data, u16 len) | 902 | static int get_connections(struct sock *sk, u16 index) |
881 | { | 903 | { |
882 | struct mgmt_cp_get_connections *cp; | ||
883 | struct mgmt_rp_get_connections *rp; | 904 | struct mgmt_rp_get_connections *rp; |
884 | struct hci_dev *hdev; | 905 | struct hci_dev *hdev; |
885 | struct list_head *p; | 906 | struct list_head *p; |
886 | size_t rp_len; | 907 | size_t rp_len; |
887 | u16 dev_id, count; | 908 | u16 count; |
888 | int i, err; | 909 | int i, err; |
889 | 910 | ||
890 | BT_DBG(""); | 911 | BT_DBG(""); |
891 | 912 | ||
892 | cp = (void *) data; | 913 | hdev = hci_dev_get(index); |
893 | dev_id = get_unaligned_le16(&cp->index); | ||
894 | |||
895 | hdev = hci_dev_get(dev_id); | ||
896 | if (!hdev) | 914 | if (!hdev) |
897 | return cmd_status(sk, MGMT_OP_GET_CONNECTIONS, ENODEV); | 915 | return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV); |
898 | 916 | ||
899 | hci_dev_lock_bh(hdev); | 917 | hci_dev_lock_bh(hdev); |
900 | 918 | ||
@@ -910,7 +928,6 @@ static int get_connections(struct sock *sk, unsigned char *data, u16 len) | |||
910 | goto unlock; | 928 | goto unlock; |
911 | } | 929 | } |
912 | 930 | ||
913 | put_unaligned_le16(dev_id, &rp->index); | ||
914 | put_unaligned_le16(count, &rp->conn_count); | 931 | put_unaligned_le16(count, &rp->conn_count); |
915 | 932 | ||
916 | read_lock(&hci_dev_list_lock); | 933 | read_lock(&hci_dev_list_lock); |
@@ -924,7 +941,7 @@ static int get_connections(struct sock *sk, unsigned char *data, u16 len) | |||
924 | 941 | ||
925 | read_unlock(&hci_dev_list_lock); | 942 | read_unlock(&hci_dev_list_lock); |
926 | 943 | ||
927 | err = cmd_complete(sk, MGMT_OP_GET_CONNECTIONS, rp, rp_len); | 944 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); |
928 | 945 | ||
929 | unlock: | 946 | unlock: |
930 | kfree(rp); | 947 | kfree(rp); |
@@ -933,33 +950,38 @@ unlock: | |||
933 | return err; | 950 | return err; |
934 | } | 951 | } |
935 | 952 | ||
936 | static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len) | 953 | static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, |
954 | u16 len) | ||
937 | { | 955 | { |
938 | struct hci_dev *hdev; | 956 | struct hci_dev *hdev; |
939 | struct mgmt_cp_pin_code_reply *cp; | 957 | struct mgmt_cp_pin_code_reply *cp; |
940 | struct hci_cp_pin_code_reply reply; | 958 | struct hci_cp_pin_code_reply reply; |
941 | u16 dev_id; | 959 | struct pending_cmd *cmd; |
942 | int err; | 960 | int err; |
943 | 961 | ||
944 | BT_DBG(""); | 962 | BT_DBG(""); |
945 | 963 | ||
946 | cp = (void *) data; | 964 | cp = (void *) data; |
947 | dev_id = get_unaligned_le16(&cp->index); | ||
948 | 965 | ||
949 | hdev = hci_dev_get(dev_id); | 966 | if (len != sizeof(*cp)) |
967 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, EINVAL); | ||
968 | |||
969 | hdev = hci_dev_get(index); | ||
950 | if (!hdev) | 970 | if (!hdev) |
951 | return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV); | 971 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV); |
952 | 972 | ||
953 | hci_dev_lock_bh(hdev); | 973 | hci_dev_lock_bh(hdev); |
954 | 974 | ||
955 | if (!test_bit(HCI_UP, &hdev->flags)) { | 975 | if (!test_bit(HCI_UP, &hdev->flags)) { |
956 | err = cmd_status(sk, MGMT_OP_PIN_CODE_REPLY, ENETDOWN); | 976 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN); |
957 | goto failed; | 977 | goto failed; |
958 | } | 978 | } |
959 | 979 | ||
960 | err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, dev_id, data, len); | 980 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); |
961 | if (err < 0) | 981 | if (!cmd) { |
982 | err = -ENOMEM; | ||
962 | goto failed; | 983 | goto failed; |
984 | } | ||
963 | 985 | ||
964 | bacpy(&reply.bdaddr, &cp->bdaddr); | 986 | bacpy(&reply.bdaddr, &cp->bdaddr); |
965 | reply.pin_len = cp->pin_len; | 987 | reply.pin_len = cp->pin_len; |
@@ -967,7 +989,7 @@ static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len) | |||
967 | 989 | ||
968 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply); | 990 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply); |
969 | if (err < 0) | 991 | if (err < 0) |
970 | mgmt_pending_remove(MGMT_OP_PIN_CODE_REPLY, dev_id); | 992 | mgmt_pending_remove(cmd); |
971 | 993 | ||
972 | failed: | 994 | failed: |
973 | hci_dev_unlock_bh(hdev); | 995 | hci_dev_unlock_bh(hdev); |
@@ -976,38 +998,46 @@ failed: | |||
976 | return err; | 998 | return err; |
977 | } | 999 | } |
978 | 1000 | ||
979 | static int pin_code_neg_reply(struct sock *sk, unsigned char *data, u16 len) | 1001 | static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, |
1002 | u16 len) | ||
980 | { | 1003 | { |
981 | struct hci_dev *hdev; | 1004 | struct hci_dev *hdev; |
982 | struct mgmt_cp_pin_code_neg_reply *cp; | 1005 | struct mgmt_cp_pin_code_neg_reply *cp; |
983 | u16 dev_id; | 1006 | struct pending_cmd *cmd; |
984 | int err; | 1007 | int err; |
985 | 1008 | ||
986 | BT_DBG(""); | 1009 | BT_DBG(""); |
987 | 1010 | ||
988 | cp = (void *) data; | 1011 | cp = (void *) data; |
989 | dev_id = get_unaligned_le16(&cp->index); | ||
990 | 1012 | ||
991 | hdev = hci_dev_get(dev_id); | 1013 | if (len != sizeof(*cp)) |
1014 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | ||
1015 | EINVAL); | ||
1016 | |||
1017 | hdev = hci_dev_get(index); | ||
992 | if (!hdev) | 1018 | if (!hdev) |
993 | return cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENODEV); | 1019 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, |
1020 | ENODEV); | ||
994 | 1021 | ||
995 | hci_dev_lock_bh(hdev); | 1022 | hci_dev_lock_bh(hdev); |
996 | 1023 | ||
997 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1024 | if (!test_bit(HCI_UP, &hdev->flags)) { |
998 | err = cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENETDOWN); | 1025 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, |
1026 | ENETDOWN); | ||
999 | goto failed; | 1027 | goto failed; |
1000 | } | 1028 | } |
1001 | 1029 | ||
1002 | err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, dev_id, | 1030 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, |
1003 | data, len); | 1031 | data, len); |
1004 | if (err < 0) | 1032 | if (!cmd) { |
1033 | err = -ENOMEM; | ||
1005 | goto failed; | 1034 | goto failed; |
1035 | } | ||
1006 | 1036 | ||
1007 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(bdaddr_t), | 1037 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr), |
1008 | &cp->bdaddr); | 1038 | &cp->bdaddr); |
1009 | if (err < 0) | 1039 | if (err < 0) |
1010 | mgmt_pending_remove(MGMT_OP_PIN_CODE_NEG_REPLY, dev_id); | 1040 | mgmt_pending_remove(cmd); |
1011 | 1041 | ||
1012 | failed: | 1042 | failed: |
1013 | hci_dev_unlock_bh(hdev); | 1043 | hci_dev_unlock_bh(hdev); |
@@ -1016,40 +1046,217 @@ failed: | |||
1016 | return err; | 1046 | return err; |
1017 | } | 1047 | } |
1018 | 1048 | ||
1019 | static int set_io_capability(struct sock *sk, unsigned char *data, u16 len) | 1049 | static int set_io_capability(struct sock *sk, u16 index, unsigned char *data, |
1050 | u16 len) | ||
1020 | { | 1051 | { |
1021 | struct hci_dev *hdev; | 1052 | struct hci_dev *hdev; |
1022 | struct mgmt_cp_set_io_capability *cp; | 1053 | struct mgmt_cp_set_io_capability *cp; |
1023 | u16 dev_id; | ||
1024 | 1054 | ||
1025 | BT_DBG(""); | 1055 | BT_DBG(""); |
1026 | 1056 | ||
1027 | cp = (void *) data; | 1057 | cp = (void *) data; |
1028 | dev_id = get_unaligned_le16(&cp->index); | ||
1029 | 1058 | ||
1030 | hdev = hci_dev_get(dev_id); | 1059 | if (len != sizeof(*cp)) |
1060 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, EINVAL); | ||
1061 | |||
1062 | hdev = hci_dev_get(index); | ||
1031 | if (!hdev) | 1063 | if (!hdev) |
1032 | return cmd_status(sk, MGMT_OP_SET_IO_CAPABILITY, ENODEV); | 1064 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV); |
1033 | 1065 | ||
1034 | hci_dev_lock_bh(hdev); | 1066 | hci_dev_lock_bh(hdev); |
1035 | 1067 | ||
1036 | hdev->io_capability = cp->io_capability; | 1068 | hdev->io_capability = cp->io_capability; |
1037 | 1069 | ||
1038 | BT_DBG("%s IO capability set to 0x%02x", hdev->name, | 1070 | BT_DBG("%s IO capability set to 0x%02x", hdev->name, |
1039 | hdev->io_capability); | 1071 | hdev->io_capability); |
1040 | 1072 | ||
1041 | hci_dev_unlock_bh(hdev); | 1073 | hci_dev_unlock_bh(hdev); |
1042 | hci_dev_put(hdev); | 1074 | hci_dev_put(hdev); |
1043 | 1075 | ||
1044 | return cmd_complete(sk, MGMT_OP_SET_IO_CAPABILITY, | 1076 | return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0); |
1045 | &dev_id, sizeof(dev_id)); | 1077 | } |
1078 | |||
1079 | static inline struct pending_cmd *find_pairing(struct hci_conn *conn) | ||
1080 | { | ||
1081 | struct hci_dev *hdev = conn->hdev; | ||
1082 | struct list_head *p; | ||
1083 | |||
1084 | list_for_each(p, &cmd_list) { | ||
1085 | struct pending_cmd *cmd; | ||
1086 | |||
1087 | cmd = list_entry(p, struct pending_cmd, list); | ||
1088 | |||
1089 | if (cmd->opcode != MGMT_OP_PAIR_DEVICE) | ||
1090 | continue; | ||
1091 | |||
1092 | if (cmd->index != hdev->id) | ||
1093 | continue; | ||
1094 | |||
1095 | if (cmd->user_data != conn) | ||
1096 | continue; | ||
1097 | |||
1098 | return cmd; | ||
1099 | } | ||
1100 | |||
1101 | return NULL; | ||
1102 | } | ||
1103 | |||
1104 | static void pairing_complete(struct pending_cmd *cmd, u8 status) | ||
1105 | { | ||
1106 | struct mgmt_rp_pair_device rp; | ||
1107 | struct hci_conn *conn = cmd->user_data; | ||
1108 | |||
1109 | bacpy(&rp.bdaddr, &conn->dst); | ||
1110 | rp.status = status; | ||
1111 | |||
1112 | cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp)); | ||
1113 | |||
1114 | /* So we don't get further callbacks for this connection */ | ||
1115 | conn->connect_cfm_cb = NULL; | ||
1116 | conn->security_cfm_cb = NULL; | ||
1117 | conn->disconn_cfm_cb = NULL; | ||
1118 | |||
1119 | hci_conn_put(conn); | ||
1120 | |||
1121 | mgmt_pending_remove(cmd); | ||
1122 | } | ||
1123 | |||
1124 | static void pairing_complete_cb(struct hci_conn *conn, u8 status) | ||
1125 | { | ||
1126 | struct pending_cmd *cmd; | ||
1127 | |||
1128 | BT_DBG("status %u", status); | ||
1129 | |||
1130 | cmd = find_pairing(conn); | ||
1131 | if (!cmd) { | ||
1132 | BT_DBG("Unable to find a pending command"); | ||
1133 | return; | ||
1134 | } | ||
1135 | |||
1136 | pairing_complete(cmd, status); | ||
1137 | } | ||
1138 | |||
1139 | static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | ||
1140 | { | ||
1141 | struct hci_dev *hdev; | ||
1142 | struct mgmt_cp_pair_device *cp; | ||
1143 | struct pending_cmd *cmd; | ||
1144 | u8 sec_level, auth_type; | ||
1145 | struct hci_conn *conn; | ||
1146 | int err; | ||
1147 | |||
1148 | BT_DBG(""); | ||
1149 | |||
1150 | cp = (void *) data; | ||
1151 | |||
1152 | if (len != sizeof(*cp)) | ||
1153 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EINVAL); | ||
1154 | |||
1155 | hdev = hci_dev_get(index); | ||
1156 | if (!hdev) | ||
1157 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV); | ||
1158 | |||
1159 | hci_dev_lock_bh(hdev); | ||
1160 | |||
1161 | if (cp->io_cap == 0x03) { | ||
1162 | sec_level = BT_SECURITY_MEDIUM; | ||
1163 | auth_type = HCI_AT_DEDICATED_BONDING; | ||
1164 | } else { | ||
1165 | sec_level = BT_SECURITY_HIGH; | ||
1166 | auth_type = HCI_AT_DEDICATED_BONDING_MITM; | ||
1167 | } | ||
1168 | |||
1169 | conn = hci_connect(hdev, ACL_LINK, &cp->bdaddr, sec_level, auth_type); | ||
1170 | if (IS_ERR(conn)) { | ||
1171 | err = PTR_ERR(conn); | ||
1172 | goto unlock; | ||
1173 | } | ||
1174 | |||
1175 | if (conn->connect_cfm_cb) { | ||
1176 | hci_conn_put(conn); | ||
1177 | err = cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EBUSY); | ||
1178 | goto unlock; | ||
1179 | } | ||
1180 | |||
1181 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len); | ||
1182 | if (!cmd) { | ||
1183 | err = -ENOMEM; | ||
1184 | hci_conn_put(conn); | ||
1185 | goto unlock; | ||
1186 | } | ||
1187 | |||
1188 | conn->connect_cfm_cb = pairing_complete_cb; | ||
1189 | conn->security_cfm_cb = pairing_complete_cb; | ||
1190 | conn->disconn_cfm_cb = pairing_complete_cb; | ||
1191 | conn->io_capability = cp->io_cap; | ||
1192 | cmd->user_data = conn; | ||
1193 | |||
1194 | if (conn->state == BT_CONNECTED && | ||
1195 | hci_conn_security(conn, sec_level, auth_type)) | ||
1196 | pairing_complete(cmd, 0); | ||
1197 | |||
1198 | err = 0; | ||
1199 | |||
1200 | unlock: | ||
1201 | hci_dev_unlock_bh(hdev); | ||
1202 | hci_dev_put(hdev); | ||
1203 | |||
1204 | return err; | ||
1205 | } | ||
1206 | |||
1207 | static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, | ||
1208 | u16 len, int success) | ||
1209 | { | ||
1210 | struct mgmt_cp_user_confirm_reply *cp = (void *) data; | ||
1211 | u16 mgmt_op, hci_op; | ||
1212 | struct pending_cmd *cmd; | ||
1213 | struct hci_dev *hdev; | ||
1214 | int err; | ||
1215 | |||
1216 | BT_DBG(""); | ||
1217 | |||
1218 | if (success) { | ||
1219 | mgmt_op = MGMT_OP_USER_CONFIRM_REPLY; | ||
1220 | hci_op = HCI_OP_USER_CONFIRM_REPLY; | ||
1221 | } else { | ||
1222 | mgmt_op = MGMT_OP_USER_CONFIRM_NEG_REPLY; | ||
1223 | hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY; | ||
1224 | } | ||
1225 | |||
1226 | if (len != sizeof(*cp)) | ||
1227 | return cmd_status(sk, index, mgmt_op, EINVAL); | ||
1228 | |||
1229 | hdev = hci_dev_get(index); | ||
1230 | if (!hdev) | ||
1231 | return cmd_status(sk, index, mgmt_op, ENODEV); | ||
1232 | |||
1233 | if (!test_bit(HCI_UP, &hdev->flags)) { | ||
1234 | err = cmd_status(sk, index, mgmt_op, ENETDOWN); | ||
1235 | goto failed; | ||
1236 | } | ||
1237 | |||
1238 | cmd = mgmt_pending_add(sk, mgmt_op, index, data, len); | ||
1239 | if (!cmd) { | ||
1240 | err = -ENOMEM; | ||
1241 | goto failed; | ||
1242 | } | ||
1243 | |||
1244 | err = hci_send_cmd(hdev, hci_op, sizeof(cp->bdaddr), &cp->bdaddr); | ||
1245 | if (err < 0) | ||
1246 | mgmt_pending_remove(cmd); | ||
1247 | |||
1248 | failed: | ||
1249 | hci_dev_unlock_bh(hdev); | ||
1250 | hci_dev_put(hdev); | ||
1251 | |||
1252 | return err; | ||
1046 | } | 1253 | } |
1047 | 1254 | ||
1048 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | 1255 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) |
1049 | { | 1256 | { |
1050 | unsigned char *buf; | 1257 | unsigned char *buf; |
1051 | struct mgmt_hdr *hdr; | 1258 | struct mgmt_hdr *hdr; |
1052 | u16 opcode, len; | 1259 | u16 opcode, index, len; |
1053 | int err; | 1260 | int err; |
1054 | 1261 | ||
1055 | BT_DBG("got %zu bytes", msglen); | 1262 | BT_DBG("got %zu bytes", msglen); |
@@ -1068,6 +1275,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1068 | 1275 | ||
1069 | hdr = (struct mgmt_hdr *) buf; | 1276 | hdr = (struct mgmt_hdr *) buf; |
1070 | opcode = get_unaligned_le16(&hdr->opcode); | 1277 | opcode = get_unaligned_le16(&hdr->opcode); |
1278 | index = get_unaligned_le16(&hdr->index); | ||
1071 | len = get_unaligned_le16(&hdr->len); | 1279 | len = get_unaligned_le16(&hdr->len); |
1072 | 1280 | ||
1073 | if (len != msglen - sizeof(*hdr)) { | 1281 | if (len != msglen - sizeof(*hdr)) { |
@@ -1083,56 +1291,65 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1083 | err = read_index_list(sk); | 1291 | err = read_index_list(sk); |
1084 | break; | 1292 | break; |
1085 | case MGMT_OP_READ_INFO: | 1293 | case MGMT_OP_READ_INFO: |
1086 | err = read_controller_info(sk, buf + sizeof(*hdr), len); | 1294 | err = read_controller_info(sk, index); |
1087 | break; | 1295 | break; |
1088 | case MGMT_OP_SET_POWERED: | 1296 | case MGMT_OP_SET_POWERED: |
1089 | err = set_powered(sk, buf + sizeof(*hdr), len); | 1297 | err = set_powered(sk, index, buf + sizeof(*hdr), len); |
1090 | break; | 1298 | break; |
1091 | case MGMT_OP_SET_DISCOVERABLE: | 1299 | case MGMT_OP_SET_DISCOVERABLE: |
1092 | err = set_discoverable(sk, buf + sizeof(*hdr), len); | 1300 | err = set_discoverable(sk, index, buf + sizeof(*hdr), len); |
1093 | break; | 1301 | break; |
1094 | case MGMT_OP_SET_CONNECTABLE: | 1302 | case MGMT_OP_SET_CONNECTABLE: |
1095 | err = set_connectable(sk, buf + sizeof(*hdr), len); | 1303 | err = set_connectable(sk, index, buf + sizeof(*hdr), len); |
1096 | break; | 1304 | break; |
1097 | case MGMT_OP_SET_PAIRABLE: | 1305 | case MGMT_OP_SET_PAIRABLE: |
1098 | err = set_pairable(sk, buf + sizeof(*hdr), len); | 1306 | err = set_pairable(sk, index, buf + sizeof(*hdr), len); |
1099 | break; | 1307 | break; |
1100 | case MGMT_OP_ADD_UUID: | 1308 | case MGMT_OP_ADD_UUID: |
1101 | err = add_uuid(sk, buf + sizeof(*hdr), len); | 1309 | err = add_uuid(sk, index, buf + sizeof(*hdr), len); |
1102 | break; | 1310 | break; |
1103 | case MGMT_OP_REMOVE_UUID: | 1311 | case MGMT_OP_REMOVE_UUID: |
1104 | err = remove_uuid(sk, buf + sizeof(*hdr), len); | 1312 | err = remove_uuid(sk, index, buf + sizeof(*hdr), len); |
1105 | break; | 1313 | break; |
1106 | case MGMT_OP_SET_DEV_CLASS: | 1314 | case MGMT_OP_SET_DEV_CLASS: |
1107 | err = set_dev_class(sk, buf + sizeof(*hdr), len); | 1315 | err = set_dev_class(sk, index, buf + sizeof(*hdr), len); |
1108 | break; | 1316 | break; |
1109 | case MGMT_OP_SET_SERVICE_CACHE: | 1317 | case MGMT_OP_SET_SERVICE_CACHE: |
1110 | err = set_service_cache(sk, buf + sizeof(*hdr), len); | 1318 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); |
1111 | break; | 1319 | break; |
1112 | case MGMT_OP_LOAD_KEYS: | 1320 | case MGMT_OP_LOAD_KEYS: |
1113 | err = load_keys(sk, buf + sizeof(*hdr), len); | 1321 | err = load_keys(sk, index, buf + sizeof(*hdr), len); |
1114 | break; | 1322 | break; |
1115 | case MGMT_OP_REMOVE_KEY: | 1323 | case MGMT_OP_REMOVE_KEY: |
1116 | err = remove_key(sk, buf + sizeof(*hdr), len); | 1324 | err = remove_key(sk, index, buf + sizeof(*hdr), len); |
1117 | break; | 1325 | break; |
1118 | case MGMT_OP_DISCONNECT: | 1326 | case MGMT_OP_DISCONNECT: |
1119 | err = disconnect(sk, buf + sizeof(*hdr), len); | 1327 | err = disconnect(sk, index, buf + sizeof(*hdr), len); |
1120 | break; | 1328 | break; |
1121 | case MGMT_OP_GET_CONNECTIONS: | 1329 | case MGMT_OP_GET_CONNECTIONS: |
1122 | err = get_connections(sk, buf + sizeof(*hdr), len); | 1330 | err = get_connections(sk, index); |
1123 | break; | 1331 | break; |
1124 | case MGMT_OP_PIN_CODE_REPLY: | 1332 | case MGMT_OP_PIN_CODE_REPLY: |
1125 | err = pin_code_reply(sk, buf + sizeof(*hdr), len); | 1333 | err = pin_code_reply(sk, index, buf + sizeof(*hdr), len); |
1126 | break; | 1334 | break; |
1127 | case MGMT_OP_PIN_CODE_NEG_REPLY: | 1335 | case MGMT_OP_PIN_CODE_NEG_REPLY: |
1128 | err = pin_code_neg_reply(sk, buf + sizeof(*hdr), len); | 1336 | err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len); |
1129 | break; | 1337 | break; |
1130 | case MGMT_OP_SET_IO_CAPABILITY: | 1338 | case MGMT_OP_SET_IO_CAPABILITY: |
1131 | err = set_io_capability(sk, buf + sizeof(*hdr), len); | 1339 | err = set_io_capability(sk, index, buf + sizeof(*hdr), len); |
1340 | break; | ||
1341 | case MGMT_OP_PAIR_DEVICE: | ||
1342 | err = pair_device(sk, index, buf + sizeof(*hdr), len); | ||
1343 | break; | ||
1344 | case MGMT_OP_USER_CONFIRM_REPLY: | ||
1345 | err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 1); | ||
1346 | break; | ||
1347 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: | ||
1348 | err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0); | ||
1132 | break; | 1349 | break; |
1133 | default: | 1350 | default: |
1134 | BT_DBG("Unknown op %u", opcode); | 1351 | BT_DBG("Unknown op %u", opcode); |
1135 | err = cmd_status(sk, opcode, 0x01); | 1352 | err = cmd_status(sk, index, opcode, 0x01); |
1136 | break; | 1353 | break; |
1137 | } | 1354 | } |
1138 | 1355 | ||
@@ -1148,20 +1365,12 @@ done: | |||
1148 | 1365 | ||
1149 | int mgmt_index_added(u16 index) | 1366 | int mgmt_index_added(u16 index) |
1150 | { | 1367 | { |
1151 | struct mgmt_ev_index_added ev; | 1368 | return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL); |
1152 | |||
1153 | put_unaligned_le16(index, &ev.index); | ||
1154 | |||
1155 | return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev), NULL); | ||
1156 | } | 1369 | } |
1157 | 1370 | ||
1158 | int mgmt_index_removed(u16 index) | 1371 | int mgmt_index_removed(u16 index) |
1159 | { | 1372 | { |
1160 | struct mgmt_ev_index_added ev; | 1373 | return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL); |
1161 | |||
1162 | put_unaligned_le16(index, &ev.index); | ||
1163 | |||
1164 | return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev), NULL); | ||
1165 | } | 1374 | } |
1166 | 1375 | ||
1167 | struct cmd_lookup { | 1376 | struct cmd_lookup { |
@@ -1197,10 +1406,9 @@ int mgmt_powered(u16 index, u8 powered) | |||
1197 | 1406 | ||
1198 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match); | 1407 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match); |
1199 | 1408 | ||
1200 | put_unaligned_le16(index, &ev.index); | ||
1201 | ev.val = powered; | 1409 | ev.val = powered; |
1202 | 1410 | ||
1203 | ret = mgmt_event(MGMT_EV_POWERED, &ev, sizeof(ev), match.sk); | 1411 | ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk); |
1204 | 1412 | ||
1205 | if (match.sk) | 1413 | if (match.sk) |
1206 | sock_put(match.sk); | 1414 | sock_put(match.sk); |
@@ -1214,13 +1422,12 @@ int mgmt_discoverable(u16 index, u8 discoverable) | |||
1214 | struct cmd_lookup match = { discoverable, NULL }; | 1422 | struct cmd_lookup match = { discoverable, NULL }; |
1215 | int ret; | 1423 | int ret; |
1216 | 1424 | ||
1217 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, | 1425 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match); |
1218 | mode_rsp, &match); | ||
1219 | 1426 | ||
1220 | put_unaligned_le16(index, &ev.index); | ||
1221 | ev.val = discoverable; | 1427 | ev.val = discoverable; |
1222 | 1428 | ||
1223 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, &ev, sizeof(ev), match.sk); | 1429 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev), |
1430 | match.sk); | ||
1224 | 1431 | ||
1225 | if (match.sk) | 1432 | if (match.sk) |
1226 | sock_put(match.sk); | 1433 | sock_put(match.sk); |
@@ -1236,10 +1443,9 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
1236 | 1443 | ||
1237 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match); | 1444 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match); |
1238 | 1445 | ||
1239 | put_unaligned_le16(index, &ev.index); | ||
1240 | ev.val = connectable; | 1446 | ev.val = connectable; |
1241 | 1447 | ||
1242 | ret = mgmt_event(MGMT_EV_CONNECTABLE, &ev, sizeof(ev), match.sk); | 1448 | ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk); |
1243 | 1449 | ||
1244 | if (match.sk) | 1450 | if (match.sk) |
1245 | sock_put(match.sk); | 1451 | sock_put(match.sk); |
@@ -1253,25 +1459,22 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type) | |||
1253 | 1459 | ||
1254 | memset(&ev, 0, sizeof(ev)); | 1460 | memset(&ev, 0, sizeof(ev)); |
1255 | 1461 | ||
1256 | put_unaligned_le16(index, &ev.index); | ||
1257 | |||
1258 | bacpy(&ev.key.bdaddr, &key->bdaddr); | 1462 | bacpy(&ev.key.bdaddr, &key->bdaddr); |
1259 | ev.key.type = key->type; | 1463 | ev.key.type = key->type; |
1260 | memcpy(ev.key.val, key->val, 16); | 1464 | memcpy(ev.key.val, key->val, 16); |
1261 | ev.key.pin_len = key->pin_len; | 1465 | ev.key.pin_len = key->pin_len; |
1262 | ev.old_key_type = old_key_type; | 1466 | ev.old_key_type = old_key_type; |
1263 | 1467 | ||
1264 | return mgmt_event(MGMT_EV_NEW_KEY, &ev, sizeof(ev), NULL); | 1468 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); |
1265 | } | 1469 | } |
1266 | 1470 | ||
1267 | int mgmt_connected(u16 index, bdaddr_t *bdaddr) | 1471 | int mgmt_connected(u16 index, bdaddr_t *bdaddr) |
1268 | { | 1472 | { |
1269 | struct mgmt_ev_connected ev; | 1473 | struct mgmt_ev_connected ev; |
1270 | 1474 | ||
1271 | put_unaligned_le16(index, &ev.index); | ||
1272 | bacpy(&ev.bdaddr, bdaddr); | 1475 | bacpy(&ev.bdaddr, bdaddr); |
1273 | 1476 | ||
1274 | return mgmt_event(MGMT_EV_CONNECTED, &ev, sizeof(ev), NULL); | 1477 | return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL); |
1275 | } | 1478 | } |
1276 | 1479 | ||
1277 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) | 1480 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) |
@@ -1280,16 +1483,14 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data) | |||
1280 | struct sock **sk = data; | 1483 | struct sock **sk = data; |
1281 | struct mgmt_rp_disconnect rp; | 1484 | struct mgmt_rp_disconnect rp; |
1282 | 1485 | ||
1283 | put_unaligned_le16(cmd->index, &rp.index); | ||
1284 | bacpy(&rp.bdaddr, &cp->bdaddr); | 1486 | bacpy(&rp.bdaddr, &cp->bdaddr); |
1285 | 1487 | ||
1286 | cmd_complete(cmd->sk, MGMT_OP_DISCONNECT, &rp, sizeof(rp)); | 1488 | cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp)); |
1287 | 1489 | ||
1288 | *sk = cmd->sk; | 1490 | *sk = cmd->sk; |
1289 | sock_hold(*sk); | 1491 | sock_hold(*sk); |
1290 | 1492 | ||
1291 | list_del(&cmd->list); | 1493 | mgmt_pending_remove(cmd); |
1292 | mgmt_pending_free(cmd); | ||
1293 | } | 1494 | } |
1294 | 1495 | ||
1295 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) | 1496 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) |
@@ -1300,10 +1501,9 @@ int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) | |||
1300 | 1501 | ||
1301 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); | 1502 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); |
1302 | 1503 | ||
1303 | put_unaligned_le16(index, &ev.index); | ||
1304 | bacpy(&ev.bdaddr, bdaddr); | 1504 | bacpy(&ev.bdaddr, bdaddr); |
1305 | 1505 | ||
1306 | err = mgmt_event(MGMT_EV_DISCONNECTED, &ev, sizeof(ev), sk); | 1506 | err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk); |
1307 | 1507 | ||
1308 | if (sk) | 1508 | if (sk) |
1309 | sock_put(sk); | 1509 | sock_put(sk); |
@@ -1320,10 +1520,9 @@ int mgmt_disconnect_failed(u16 index) | |||
1320 | if (!cmd) | 1520 | if (!cmd) |
1321 | return -ENOENT; | 1521 | return -ENOENT; |
1322 | 1522 | ||
1323 | err = cmd_status(cmd->sk, MGMT_OP_DISCONNECT, EIO); | 1523 | err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO); |
1324 | 1524 | ||
1325 | list_del(&cmd->list); | 1525 | mgmt_pending_remove(cmd); |
1326 | mgmt_pending_free(cmd); | ||
1327 | 1526 | ||
1328 | return err; | 1527 | return err; |
1329 | } | 1528 | } |
@@ -1332,40 +1531,39 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status) | |||
1332 | { | 1531 | { |
1333 | struct mgmt_ev_connect_failed ev; | 1532 | struct mgmt_ev_connect_failed ev; |
1334 | 1533 | ||
1335 | put_unaligned_le16(index, &ev.index); | ||
1336 | bacpy(&ev.bdaddr, bdaddr); | 1534 | bacpy(&ev.bdaddr, bdaddr); |
1337 | ev.status = status; | 1535 | ev.status = status; |
1338 | 1536 | ||
1339 | return mgmt_event(MGMT_EV_CONNECT_FAILED, &ev, sizeof(ev), NULL); | 1537 | return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); |
1340 | } | 1538 | } |
1341 | 1539 | ||
1342 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr) | 1540 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr) |
1343 | { | 1541 | { |
1344 | struct mgmt_ev_pin_code_request ev; | 1542 | struct mgmt_ev_pin_code_request ev; |
1345 | 1543 | ||
1346 | put_unaligned_le16(index, &ev.index); | ||
1347 | bacpy(&ev.bdaddr, bdaddr); | 1544 | bacpy(&ev.bdaddr, bdaddr); |
1348 | 1545 | ||
1349 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, &ev, sizeof(ev), NULL); | 1546 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), |
1547 | NULL); | ||
1350 | } | 1548 | } |
1351 | 1549 | ||
1352 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 1550 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) |
1353 | { | 1551 | { |
1354 | struct pending_cmd *cmd; | 1552 | struct pending_cmd *cmd; |
1553 | struct mgmt_rp_pin_code_reply rp; | ||
1355 | int err; | 1554 | int err; |
1356 | 1555 | ||
1357 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index); | 1556 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index); |
1358 | if (!cmd) | 1557 | if (!cmd) |
1359 | return -ENOENT; | 1558 | return -ENOENT; |
1360 | 1559 | ||
1361 | if (status != 0) | 1560 | bacpy(&rp.bdaddr, bdaddr); |
1362 | err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, status); | 1561 | rp.status = status; |
1363 | else | ||
1364 | err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY, | ||
1365 | bdaddr, sizeof(*bdaddr)); | ||
1366 | 1562 | ||
1367 | list_del(&cmd->list); | 1563 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp, |
1368 | mgmt_pending_free(cmd); | 1564 | sizeof(rp)); |
1565 | |||
1566 | mgmt_pending_remove(cmd); | ||
1369 | 1567 | ||
1370 | return err; | 1568 | return err; |
1371 | } | 1569 | } |
@@ -1373,20 +1571,75 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
1373 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 1571 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) |
1374 | { | 1572 | { |
1375 | struct pending_cmd *cmd; | 1573 | struct pending_cmd *cmd; |
1574 | struct mgmt_rp_pin_code_reply rp; | ||
1376 | int err; | 1575 | int err; |
1377 | 1576 | ||
1378 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index); | 1577 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index); |
1379 | if (!cmd) | 1578 | if (!cmd) |
1380 | return -ENOENT; | 1579 | return -ENOENT; |
1381 | 1580 | ||
1382 | if (status != 0) | 1581 | bacpy(&rp.bdaddr, bdaddr); |
1383 | err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, status); | 1582 | rp.status = status; |
1384 | else | ||
1385 | err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, | ||
1386 | bdaddr, sizeof(*bdaddr)); | ||
1387 | 1583 | ||
1388 | list_del(&cmd->list); | 1584 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, |
1389 | mgmt_pending_free(cmd); | 1585 | sizeof(rp)); |
1586 | |||
1587 | mgmt_pending_remove(cmd); | ||
1588 | |||
1589 | return err; | ||
1590 | } | ||
1591 | |||
1592 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value) | ||
1593 | { | ||
1594 | struct mgmt_ev_user_confirm_request ev; | ||
1595 | |||
1596 | BT_DBG("hci%u", index); | ||
1597 | |||
1598 | bacpy(&ev.bdaddr, bdaddr); | ||
1599 | put_unaligned_le32(value, &ev.value); | ||
1600 | |||
1601 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), | ||
1602 | NULL); | ||
1603 | } | ||
1604 | |||
1605 | static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status, | ||
1606 | u8 opcode) | ||
1607 | { | ||
1608 | struct pending_cmd *cmd; | ||
1609 | struct mgmt_rp_user_confirm_reply rp; | ||
1610 | int err; | ||
1611 | |||
1612 | cmd = mgmt_pending_find(opcode, index); | ||
1613 | if (!cmd) | ||
1614 | return -ENOENT; | ||
1615 | |||
1616 | bacpy(&rp.bdaddr, bdaddr); | ||
1617 | rp.status = status; | ||
1618 | err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp)); | ||
1619 | |||
1620 | mgmt_pending_remove(cmd); | ||
1390 | 1621 | ||
1391 | return err; | 1622 | return err; |
1392 | } | 1623 | } |
1624 | |||
1625 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | ||
1626 | { | ||
1627 | return confirm_reply_complete(index, bdaddr, status, | ||
1628 | MGMT_OP_USER_CONFIRM_REPLY); | ||
1629 | } | ||
1630 | |||
1631 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | ||
1632 | { | ||
1633 | return confirm_reply_complete(index, bdaddr, status, | ||
1634 | MGMT_OP_USER_CONFIRM_NEG_REPLY); | ||
1635 | } | ||
1636 | |||
1637 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status) | ||
1638 | { | ||
1639 | struct mgmt_ev_auth_failed ev; | ||
1640 | |||
1641 | bacpy(&ev.bdaddr, bdaddr); | ||
1642 | ev.status = status; | ||
1643 | |||
1644 | return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL); | ||
1645 | } | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index c9348ddda877..42fdffd1d76c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -190,20 +190,21 @@ static int sco_connect(struct sock *sk) | |||
190 | 190 | ||
191 | hci_dev_lock_bh(hdev); | 191 | hci_dev_lock_bh(hdev); |
192 | 192 | ||
193 | err = -ENOMEM; | ||
194 | |||
195 | if (lmp_esco_capable(hdev) && !disable_esco) | 193 | if (lmp_esco_capable(hdev) && !disable_esco) |
196 | type = ESCO_LINK; | 194 | type = ESCO_LINK; |
197 | else | 195 | else |
198 | type = SCO_LINK; | 196 | type = SCO_LINK; |
199 | 197 | ||
200 | hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING); | 198 | hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING); |
201 | if (!hcon) | 199 | if (IS_ERR(hcon)) { |
200 | err = PTR_ERR(hcon); | ||
202 | goto done; | 201 | goto done; |
202 | } | ||
203 | 203 | ||
204 | conn = sco_conn_add(hcon, 0); | 204 | conn = sco_conn_add(hcon, 0); |
205 | if (!conn) { | 205 | if (!conn) { |
206 | hci_conn_put(hcon); | 206 | hci_conn_put(hcon); |
207 | err = -ENOMEM; | ||
207 | goto done; | 208 | goto done; |
208 | } | 209 | } |
209 | 210 | ||
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 8106aa1b7466..4ddbe27eb570 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #define WEP_IV_LEN 4 | 22 | #define WEP_IV_LEN 4 |
23 | #define WEP_ICV_LEN 4 | 23 | #define WEP_ICV_LEN 4 |
24 | #define ALG_TKIP_KEY_LEN 32 | ||
25 | #define ALG_CCMP_KEY_LEN 16 | 24 | #define ALG_CCMP_KEY_LEN 16 |
26 | #define CCMP_HDR_LEN 8 | 25 | #define CCMP_HDR_LEN 8 |
27 | #define CCMP_MIC_LEN 8 | 26 | #define CCMP_MIC_LEN 8 |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 2543e48bd813..562d2984c482 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -380,6 +380,9 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
380 | 380 | ||
381 | trace_api_restart_hw(local); | 381 | trace_api_restart_hw(local); |
382 | 382 | ||
383 | wiphy_info(hw->wiphy, | ||
384 | "Hardware restart was requested\n"); | ||
385 | |||
383 | /* use this reason, ieee80211_reconfig will unblock it */ | 386 | /* use this reason, ieee80211_reconfig will unblock it */ |
384 | ieee80211_stop_queues_by_reason(hw, | 387 | ieee80211_stop_queues_by_reason(hw, |
385 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 388 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 165a4518bb48..bce14fbfc3b6 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -415,10 +415,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
415 | mi->sample_count--; | 415 | mi->sample_count--; |
416 | } | 416 | } |
417 | 417 | ||
418 | if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { | 418 | if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) |
419 | mi->sample_packets += info->status.ampdu_len; | 419 | mi->sample_packets += info->status.ampdu_len; |
420 | minstrel_next_sample_idx(mi); | ||
421 | } | ||
422 | 420 | ||
423 | for (i = 0; !last; i++) { | 421 | for (i = 0; !last; i++) { |
424 | last = (i == IEEE80211_TX_MAX_RATES - 1) || | 422 | last = (i == IEEE80211_TX_MAX_RATES - 1) || |
@@ -519,9 +517,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, | |||
519 | rate->count = mr->retry_count; | 517 | rate->count = mr->retry_count; |
520 | 518 | ||
521 | rate->flags = IEEE80211_TX_RC_MCS | group->flags; | 519 | rate->flags = IEEE80211_TX_RC_MCS | group->flags; |
522 | if (txrc->short_preamble) | 520 | if (rtscts) |
523 | rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | ||
524 | if (txrc->rts || rtscts) | ||
525 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; | 521 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; |
526 | rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES; | 522 | rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES; |
527 | } | 523 | } |
@@ -553,13 +549,14 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
553 | sample_idx = sample_table[mg->column][mg->index]; | 549 | sample_idx = sample_table[mg->column][mg->index]; |
554 | mr = &mg->rates[sample_idx]; | 550 | mr = &mg->rates[sample_idx]; |
555 | sample_idx += mi->sample_group * MCS_GROUP_RATES; | 551 | sample_idx += mi->sample_group * MCS_GROUP_RATES; |
552 | minstrel_next_sample_idx(mi); | ||
556 | 553 | ||
557 | /* | 554 | /* |
558 | * When not using MRR, do not sample if the probability is already | 555 | * When not using MRR, do not sample if the probability is already |
559 | * higher than 95% to avoid wasting airtime | 556 | * higher than 95% to avoid wasting airtime |
560 | */ | 557 | */ |
561 | if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100))) | 558 | if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100))) |
562 | goto next; | 559 | return -1; |
563 | 560 | ||
564 | /* | 561 | /* |
565 | * Make sure that lower rates get sampled only occasionally, | 562 | * Make sure that lower rates get sampled only occasionally, |
@@ -568,17 +565,13 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
568 | if (minstrel_get_duration(sample_idx) > | 565 | if (minstrel_get_duration(sample_idx) > |
569 | minstrel_get_duration(mi->max_tp_rate)) { | 566 | minstrel_get_duration(mi->max_tp_rate)) { |
570 | if (mr->sample_skipped < 20) | 567 | if (mr->sample_skipped < 20) |
571 | goto next; | 568 | return -1; |
572 | 569 | ||
573 | if (mi->sample_slow++ > 2) | 570 | if (mi->sample_slow++ > 2) |
574 | goto next; | 571 | return -1; |
575 | } | 572 | } |
576 | 573 | ||
577 | return sample_idx; | 574 | return sample_idx; |
578 | |||
579 | next: | ||
580 | minstrel_next_sample_idx(mi); | ||
581 | return -1; | ||
582 | } | 575 | } |
583 | 576 | ||
584 | static void | 577 | static void |
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index 1a873f00691a..6510f8ee738e 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
@@ -24,9 +24,6 @@ | |||
24 | /* Fixed point arithmetic shifting amount. */ | 24 | /* Fixed point arithmetic shifting amount. */ |
25 | #define RC_PID_ARITH_SHIFT 8 | 25 | #define RC_PID_ARITH_SHIFT 8 |
26 | 26 | ||
27 | /* Fixed point arithmetic factor. */ | ||
28 | #define RC_PID_ARITH_FACTOR (1 << RC_PID_ARITH_SHIFT) | ||
29 | |||
30 | /* Proportional PID component coefficient. */ | 27 | /* Proportional PID component coefficient. */ |
31 | #define RC_PID_COEFF_P 15 | 28 | #define RC_PID_COEFF_P 15 |
32 | /* Integral PID component coefficient. */ | 29 | /* Integral PID component coefficient. */ |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 842954509925..489b6ad200d4 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -258,10 +258,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
258 | return true; | 258 | return true; |
259 | } | 259 | } |
260 | 260 | ||
261 | static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | 261 | static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, |
262 | bool was_hw_scan) | 262 | bool was_hw_scan) |
263 | { | 263 | { |
264 | struct ieee80211_local *local = hw_to_local(hw); | 264 | struct ieee80211_local *local = hw_to_local(hw); |
265 | bool on_oper_chan; | ||
266 | bool enable_beacons = false; | ||
265 | 267 | ||
266 | lockdep_assert_held(&local->mtx); | 268 | lockdep_assert_held(&local->mtx); |
267 | 269 | ||
@@ -275,12 +277,12 @@ static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
275 | aborted = true; | 277 | aborted = true; |
276 | 278 | ||
277 | if (WARN_ON(!local->scan_req)) | 279 | if (WARN_ON(!local->scan_req)) |
278 | return false; | 280 | return; |
279 | 281 | ||
280 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { | 282 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { |
281 | int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); | 283 | int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); |
282 | if (rc == 0) | 284 | if (rc == 0) |
283 | return false; | 285 | return; |
284 | } | 286 | } |
285 | 287 | ||
286 | kfree(local->hw_scan_req); | 288 | kfree(local->hw_scan_req); |
@@ -294,26 +296,11 @@ static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
294 | local->scanning = 0; | 296 | local->scanning = 0; |
295 | local->scan_channel = NULL; | 297 | local->scan_channel = NULL; |
296 | 298 | ||
297 | return true; | ||
298 | } | ||
299 | |||
300 | static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, | ||
301 | bool was_hw_scan) | ||
302 | { | ||
303 | struct ieee80211_local *local = hw_to_local(hw); | ||
304 | bool on_oper_chan; | ||
305 | bool enable_beacons = false; | ||
306 | |||
307 | mutex_lock(&local->mtx); | ||
308 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 299 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
309 | 300 | ||
310 | WARN_ON(local->scanning & (SCAN_SW_SCANNING | SCAN_HW_SCANNING)); | 301 | if (was_hw_scan || !on_oper_chan) |
311 | |||
312 | if (was_hw_scan || !on_oper_chan) { | ||
313 | if (WARN_ON(local->scan_channel)) | ||
314 | local->scan_channel = NULL; | ||
315 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 302 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
316 | } else | 303 | else |
317 | /* Set power back to normal operating levels. */ | 304 | /* Set power back to normal operating levels. */ |
318 | ieee80211_hw_config(local, 0); | 305 | ieee80211_hw_config(local, 0); |
319 | 306 | ||
@@ -331,7 +318,6 @@ static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, | |||
331 | } | 318 | } |
332 | 319 | ||
333 | ieee80211_recalc_idle(local); | 320 | ieee80211_recalc_idle(local); |
334 | mutex_unlock(&local->mtx); | ||
335 | 321 | ||
336 | ieee80211_mlme_notify_scan_completed(local); | 322 | ieee80211_mlme_notify_scan_completed(local); |
337 | ieee80211_ibss_notify_scan_completed(local); | 323 | ieee80211_ibss_notify_scan_completed(local); |
@@ -686,12 +672,14 @@ void ieee80211_scan_work(struct work_struct *work) | |||
686 | { | 672 | { |
687 | struct ieee80211_local *local = | 673 | struct ieee80211_local *local = |
688 | container_of(work, struct ieee80211_local, scan_work.work); | 674 | container_of(work, struct ieee80211_local, scan_work.work); |
689 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 675 | struct ieee80211_sub_if_data *sdata; |
690 | unsigned long next_delay = 0; | 676 | unsigned long next_delay = 0; |
691 | bool aborted, hw_scan, finish; | 677 | bool aborted, hw_scan; |
692 | 678 | ||
693 | mutex_lock(&local->mtx); | 679 | mutex_lock(&local->mtx); |
694 | 680 | ||
681 | sdata = local->scan_sdata; | ||
682 | |||
695 | if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { | 683 | if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { |
696 | aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); | 684 | aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); |
697 | goto out_complete; | 685 | goto out_complete; |
@@ -755,17 +743,11 @@ void ieee80211_scan_work(struct work_struct *work) | |||
755 | } while (next_delay == 0); | 743 | } while (next_delay == 0); |
756 | 744 | ||
757 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); | 745 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); |
758 | mutex_unlock(&local->mtx); | 746 | goto out; |
759 | return; | ||
760 | 747 | ||
761 | out_complete: | 748 | out_complete: |
762 | hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); | 749 | hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); |
763 | finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan); | 750 | __ieee80211_scan_completed(&local->hw, aborted, hw_scan); |
764 | mutex_unlock(&local->mtx); | ||
765 | if (finish) | ||
766 | __ieee80211_scan_completed_finish(&local->hw, hw_scan); | ||
767 | return; | ||
768 | |||
769 | out: | 751 | out: |
770 | mutex_unlock(&local->mtx); | 752 | mutex_unlock(&local->mtx); |
771 | } | 753 | } |
@@ -835,7 +817,6 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
835 | void ieee80211_scan_cancel(struct ieee80211_local *local) | 817 | void ieee80211_scan_cancel(struct ieee80211_local *local) |
836 | { | 818 | { |
837 | bool abortscan; | 819 | bool abortscan; |
838 | bool finish = false; | ||
839 | 820 | ||
840 | /* | 821 | /* |
841 | * We are only canceling software scan, or deferred scan that was not | 822 | * We are only canceling software scan, or deferred scan that was not |
@@ -855,14 +836,17 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
855 | 836 | ||
856 | mutex_lock(&local->mtx); | 837 | mutex_lock(&local->mtx); |
857 | abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); | 838 | abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); |
858 | if (abortscan) | ||
859 | finish = __ieee80211_scan_completed(&local->hw, true, false); | ||
860 | mutex_unlock(&local->mtx); | ||
861 | |||
862 | if (abortscan) { | 839 | if (abortscan) { |
863 | /* The scan is canceled, but stop work from being pending */ | 840 | /* |
864 | cancel_delayed_work_sync(&local->scan_work); | 841 | * The scan is canceled, but stop work from being pending. |
842 | * | ||
843 | * If the work is currently running, it must be blocked on | ||
844 | * the mutex, but we'll set scan_sdata = NULL and it'll | ||
845 | * simply exit once it acquires the mutex. | ||
846 | */ | ||
847 | cancel_delayed_work(&local->scan_work); | ||
848 | /* and clean up */ | ||
849 | __ieee80211_scan_completed(&local->hw, true, false); | ||
865 | } | 850 | } |
866 | if (finish) | 851 | mutex_unlock(&local->mtx); |
867 | __ieee80211_scan_completed_finish(&local->hw, false); | ||
868 | } | 852 | } |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 204f0a4db969..e73c8cae036b 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #define IEEE80211_AUTH_MAX_TRIES 3 | 30 | #define IEEE80211_AUTH_MAX_TRIES 3 |
31 | #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) | 31 | #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) |
32 | #define IEEE80211_ASSOC_MAX_TRIES 3 | 32 | #define IEEE80211_ASSOC_MAX_TRIES 3 |
33 | #define IEEE80211_MAX_PROBE_TRIES 5 | ||
34 | 33 | ||
35 | enum work_action { | 34 | enum work_action { |
36 | WORK_ACT_MISMATCH, | 35 | WORK_ACT_MISMATCH, |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index c565689f0b9f..3332d5bce317 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -63,6 +63,10 @@ static struct regulatory_request *last_request; | |||
63 | /* To trigger userspace events */ | 63 | /* To trigger userspace events */ |
64 | static struct platform_device *reg_pdev; | 64 | static struct platform_device *reg_pdev; |
65 | 65 | ||
66 | static struct device_type reg_device_type = { | ||
67 | .uevent = reg_device_uevent, | ||
68 | }; | ||
69 | |||
66 | /* | 70 | /* |
67 | * Central wireless core regulatory domains, we only need two, | 71 | * Central wireless core regulatory domains, we only need two, |
68 | * the current one and a world regulatory domain in case we have no | 72 | * the current one and a world regulatory domain in case we have no |
@@ -362,16 +366,11 @@ static inline void reg_regdb_query(const char *alpha2) {} | |||
362 | 366 | ||
363 | /* | 367 | /* |
364 | * This lets us keep regulatory code which is updated on a regulatory | 368 | * This lets us keep regulatory code which is updated on a regulatory |
365 | * basis in userspace. | 369 | * basis in userspace. Country information is filled in by |
370 | * reg_device_uevent | ||
366 | */ | 371 | */ |
367 | static int call_crda(const char *alpha2) | 372 | static int call_crda(const char *alpha2) |
368 | { | 373 | { |
369 | char country_env[9 + 2] = "COUNTRY="; | ||
370 | char *envp[] = { | ||
371 | country_env, | ||
372 | NULL | ||
373 | }; | ||
374 | |||
375 | if (!is_world_regdom((char *) alpha2)) | 374 | if (!is_world_regdom((char *) alpha2)) |
376 | pr_info("Calling CRDA for country: %c%c\n", | 375 | pr_info("Calling CRDA for country: %c%c\n", |
377 | alpha2[0], alpha2[1]); | 376 | alpha2[0], alpha2[1]); |
@@ -381,10 +380,7 @@ static int call_crda(const char *alpha2) | |||
381 | /* query internal regulatory database (if it exists) */ | 380 | /* query internal regulatory database (if it exists) */ |
382 | reg_regdb_query(alpha2); | 381 | reg_regdb_query(alpha2); |
383 | 382 | ||
384 | country_env[8] = alpha2[0]; | 383 | return kobject_uevent(®_pdev->dev.kobj, KOBJ_CHANGE); |
385 | country_env[9] = alpha2[1]; | ||
386 | |||
387 | return kobject_uevent_env(®_pdev->dev.kobj, KOBJ_CHANGE, envp); | ||
388 | } | 384 | } |
389 | 385 | ||
390 | /* Used by nl80211 before kmalloc'ing our regulatory domain */ | 386 | /* Used by nl80211 before kmalloc'ing our regulatory domain */ |
@@ -2087,6 +2083,25 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2087 | return r; | 2083 | return r; |
2088 | } | 2084 | } |
2089 | 2085 | ||
2086 | #ifdef CONFIG_HOTPLUG | ||
2087 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
2088 | { | ||
2089 | if (last_request && !last_request->processed) { | ||
2090 | if (add_uevent_var(env, "COUNTRY=%c%c", | ||
2091 | last_request->alpha2[0], | ||
2092 | last_request->alpha2[1])) | ||
2093 | return -ENOMEM; | ||
2094 | } | ||
2095 | |||
2096 | return 0; | ||
2097 | } | ||
2098 | #else | ||
2099 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
2100 | { | ||
2101 | return -ENODEV; | ||
2102 | } | ||
2103 | #endif /* CONFIG_HOTPLUG */ | ||
2104 | |||
2090 | /* Caller must hold cfg80211_mutex */ | 2105 | /* Caller must hold cfg80211_mutex */ |
2091 | void reg_device_remove(struct wiphy *wiphy) | 2106 | void reg_device_remove(struct wiphy *wiphy) |
2092 | { | 2107 | { |
@@ -2118,6 +2133,8 @@ int __init regulatory_init(void) | |||
2118 | if (IS_ERR(reg_pdev)) | 2133 | if (IS_ERR(reg_pdev)) |
2119 | return PTR_ERR(reg_pdev); | 2134 | return PTR_ERR(reg_pdev); |
2120 | 2135 | ||
2136 | reg_pdev->dev.type = ®_device_type; | ||
2137 | |||
2121 | spin_lock_init(®_requests_lock); | 2138 | spin_lock_init(®_requests_lock); |
2122 | spin_lock_init(®_pending_beacons_lock); | 2139 | spin_lock_init(®_pending_beacons_lock); |
2123 | 2140 | ||
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index c4695d07af23..b67d1c3a2fb9 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -8,6 +8,7 @@ bool reg_is_valid_request(const char *alpha2); | |||
8 | 8 | ||
9 | int regulatory_hint_user(const char *alpha2); | 9 | int regulatory_hint_user(const char *alpha2); |
10 | 10 | ||
11 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env); | ||
11 | void reg_device_remove(struct wiphy *wiphy); | 12 | void reg_device_remove(struct wiphy *wiphy); |
12 | 13 | ||
13 | int __init regulatory_init(void); | 14 | int __init regulatory_init(void); |