diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-01-28 14:43:00 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-01-28 14:43:00 -0500 |
commit | 4205e6ef4ee747aa81930537b6035086ba5f1e28 (patch) | |
tree | b2ebe2b4621f5f531f283cb9bf0005cd3c04ca7b /drivers/net/wireless | |
parent | cef401de7be8c4e155c6746bfccf721a4fa5fab9 (diff) | |
parent | 9ebea3829fac7505e0cd2642fbd13cfa9c038831 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers/net/wireless')
127 files changed, 4270 insertions, 2437 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 30ca0a60a64c..1d264c0f5a9b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -240,13 +240,14 @@ static const struct ath_ops ath5k_common_ops = { | |||
240 | * Driver Initialization * | 240 | * Driver Initialization * |
241 | \***********************/ | 241 | \***********************/ |
242 | 242 | ||
243 | static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) | 243 | static void ath5k_reg_notifier(struct wiphy *wiphy, |
244 | struct regulatory_request *request) | ||
244 | { | 245 | { |
245 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 246 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
246 | struct ath5k_hw *ah = hw->priv; | 247 | struct ath5k_hw *ah = hw->priv; |
247 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); | 248 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); |
248 | 249 | ||
249 | return ath_reg_notifier_apply(wiphy, request, regulatory); | 250 | ath_reg_notifier_apply(wiphy, request, regulatory); |
250 | } | 251 | } |
251 | 252 | ||
252 | /********************\ | 253 | /********************\ |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5516a8ccc3c6..4225cca0f198 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -3492,8 +3492,8 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) | |||
3492 | ath6kl_cfg80211_stop(vif); | 3492 | ath6kl_cfg80211_stop(vif); |
3493 | } | 3493 | } |
3494 | 3494 | ||
3495 | static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, | 3495 | static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, |
3496 | struct regulatory_request *request) | 3496 | struct regulatory_request *request) |
3497 | { | 3497 | { |
3498 | struct ath6kl *ar = wiphy_priv(wiphy); | 3498 | struct ath6kl *ar = wiphy_priv(wiphy); |
3499 | u32 rates[IEEE80211_NUM_BANDS]; | 3499 | u32 rates[IEEE80211_NUM_BANDS]; |
@@ -3506,17 +3506,13 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, | |||
3506 | request->processed ? " processed" : "", | 3506 | request->processed ? " processed" : "", |
3507 | request->initiator, request->user_reg_hint_type); | 3507 | request->initiator, request->user_reg_hint_type); |
3508 | 3508 | ||
3509 | /* | ||
3510 | * As firmware is not able intersect regdoms, we can only listen to | ||
3511 | * cellular hints. | ||
3512 | */ | ||
3513 | if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) | 3509 | if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) |
3514 | return -EOPNOTSUPP; | 3510 | return; |
3515 | 3511 | ||
3516 | ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2); | 3512 | ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2); |
3517 | if (ret) { | 3513 | if (ret) { |
3518 | ath6kl_err("failed to set regdomain: %d\n", ret); | 3514 | ath6kl_err("failed to set regdomain: %d\n", ret); |
3519 | return ret; | 3515 | return; |
3520 | } | 3516 | } |
3521 | 3517 | ||
3522 | /* | 3518 | /* |
@@ -3536,10 +3532,8 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, | |||
3536 | if (ret) { | 3532 | if (ret) { |
3537 | ath6kl_err("failed to start scan for a regdomain change: %d\n", | 3533 | ath6kl_err("failed to start scan for a regdomain change: %d\n", |
3538 | ret); | 3534 | ret); |
3539 | return ret; | 3535 | return; |
3540 | } | 3536 | } |
3541 | |||
3542 | return 0; | ||
3543 | } | 3537 | } |
3544 | 3538 | ||
3545 | static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) | 3539 | static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 3a69804f4c16..d1ff3c246a12 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -86,29 +86,25 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
86 | 86 | ||
87 | if (!pdev->dev.platform_data) { | 87 | if (!pdev->dev.platform_data) { |
88 | dev_err(&pdev->dev, "no platform data specified\n"); | 88 | dev_err(&pdev->dev, "no platform data specified\n"); |
89 | ret = -EINVAL; | 89 | return -EINVAL; |
90 | goto err_out; | ||
91 | } | 90 | } |
92 | 91 | ||
93 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 92 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
94 | if (res == NULL) { | 93 | if (res == NULL) { |
95 | dev_err(&pdev->dev, "no memory resource found\n"); | 94 | dev_err(&pdev->dev, "no memory resource found\n"); |
96 | ret = -ENXIO; | 95 | return -ENXIO; |
97 | goto err_out; | ||
98 | } | 96 | } |
99 | 97 | ||
100 | mem = ioremap_nocache(res->start, resource_size(res)); | 98 | mem = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); |
101 | if (mem == NULL) { | 99 | if (mem == NULL) { |
102 | dev_err(&pdev->dev, "ioremap failed\n"); | 100 | dev_err(&pdev->dev, "ioremap failed\n"); |
103 | ret = -ENOMEM; | 101 | return -ENOMEM; |
104 | goto err_out; | ||
105 | } | 102 | } |
106 | 103 | ||
107 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 104 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
108 | if (res == NULL) { | 105 | if (res == NULL) { |
109 | dev_err(&pdev->dev, "no IRQ resource found\n"); | 106 | dev_err(&pdev->dev, "no IRQ resource found\n"); |
110 | ret = -ENXIO; | 107 | return -ENXIO; |
111 | goto err_iounmap; | ||
112 | } | 108 | } |
113 | 109 | ||
114 | irq = res->start; | 110 | irq = res->start; |
@@ -116,8 +112,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
116 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); | 112 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); |
117 | if (hw == NULL) { | 113 | if (hw == NULL) { |
118 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | 114 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); |
119 | ret = -ENOMEM; | 115 | return -ENOMEM; |
120 | goto err_iounmap; | ||
121 | } | 116 | } |
122 | 117 | ||
123 | SET_IEEE80211_DEV(hw, &pdev->dev); | 118 | SET_IEEE80211_DEV(hw, &pdev->dev); |
@@ -156,9 +151,6 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
156 | err_free_hw: | 151 | err_free_hw: |
157 | ieee80211_free_hw(hw); | 152 | ieee80211_free_hw(hw); |
158 | platform_set_drvdata(pdev, NULL); | 153 | platform_set_drvdata(pdev, NULL); |
159 | err_iounmap: | ||
160 | iounmap(mem); | ||
161 | err_out: | ||
162 | return ret; | 154 | return ret; |
163 | } | 155 | } |
164 | 156 | ||
@@ -168,12 +160,10 @@ static int ath_ahb_remove(struct platform_device *pdev) | |||
168 | 160 | ||
169 | if (hw) { | 161 | if (hw) { |
170 | struct ath_softc *sc = hw->priv; | 162 | struct ath_softc *sc = hw->priv; |
171 | void __iomem *mem = sc->mem; | ||
172 | 163 | ||
173 | ath9k_deinit_device(sc); | 164 | ath9k_deinit_device(sc); |
174 | free_irq(sc->irq, sc); | 165 | free_irq(sc->irq, sc); |
175 | ieee80211_free_hw(sc->hw); | 166 | ieee80211_free_hw(sc->hw); |
176 | iounmap(mem); | ||
177 | platform_set_drvdata(pdev, NULL); | 167 | platform_set_drvdata(pdev, NULL); |
178 | } | 168 | } |
179 | 169 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index e09ec40ce71a..7ecd40f07a74 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -152,7 +152,8 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, | |||
152 | ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", | 152 | ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", |
153 | aniState->ofdmNoiseImmunityLevel, | 153 | aniState->ofdmNoiseImmunityLevel, |
154 | immunityLevel, BEACON_RSSI(ah), | 154 | immunityLevel, BEACON_RSSI(ah), |
155 | aniState->rssiThrLow, aniState->rssiThrHigh); | 155 | ATH9K_ANI_RSSI_THR_LOW, |
156 | ATH9K_ANI_RSSI_THR_HIGH); | ||
156 | 157 | ||
157 | if (!scan) | 158 | if (!scan) |
158 | aniState->ofdmNoiseImmunityLevel = immunityLevel; | 159 | aniState->ofdmNoiseImmunityLevel = immunityLevel; |
@@ -173,7 +174,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, | |||
173 | 174 | ||
174 | weak_sig = entry_ofdm->ofdm_weak_signal_on; | 175 | weak_sig = entry_ofdm->ofdm_weak_signal_on; |
175 | if (ah->opmode == NL80211_IFTYPE_STATION && | 176 | if (ah->opmode == NL80211_IFTYPE_STATION && |
176 | BEACON_RSSI(ah) <= aniState->rssiThrHigh) | 177 | BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH) |
177 | weak_sig = true; | 178 | weak_sig = true; |
178 | 179 | ||
179 | if (aniState->ofdmWeakSigDetect != weak_sig) | 180 | if (aniState->ofdmWeakSigDetect != weak_sig) |
@@ -216,11 +217,11 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, | |||
216 | 217 | ||
217 | ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", | 218 | ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", |
218 | aniState->cckNoiseImmunityLevel, immunityLevel, | 219 | aniState->cckNoiseImmunityLevel, immunityLevel, |
219 | BEACON_RSSI(ah), aniState->rssiThrLow, | 220 | BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW, |
220 | aniState->rssiThrHigh); | 221 | ATH9K_ANI_RSSI_THR_HIGH); |
221 | 222 | ||
222 | if (ah->opmode == NL80211_IFTYPE_STATION && | 223 | if (ah->opmode == NL80211_IFTYPE_STATION && |
223 | BEACON_RSSI(ah) <= aniState->rssiThrLow && | 224 | BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW && |
224 | immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) | 225 | immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) |
225 | immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; | 226 | immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; |
226 | 227 | ||
@@ -418,9 +419,6 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) | |||
418 | return; | 419 | return; |
419 | 420 | ||
420 | aniState = &ah->curchan->ani; | 421 | aniState = &ah->curchan->ani; |
421 | if (WARN_ON(!aniState)) | ||
422 | return; | ||
423 | |||
424 | if (!ath9k_hw_ani_read_counters(ah)) | 422 | if (!ath9k_hw_ani_read_counters(ah)) |
425 | return; | 423 | return; |
426 | 424 | ||
@@ -489,23 +487,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) | |||
489 | } | 487 | } |
490 | EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); | 488 | EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); |
491 | 489 | ||
492 | void ath9k_hw_ani_setup(struct ath_hw *ah) | ||
493 | { | ||
494 | int i; | ||
495 | |||
496 | static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; | ||
497 | static const int coarseHigh[] = { -14, -14, -14, -14, -12 }; | ||
498 | static const int coarseLow[] = { -64, -64, -64, -64, -70 }; | ||
499 | static const int firpwr[] = { -78, -78, -78, -78, -80 }; | ||
500 | |||
501 | for (i = 0; i < 5; i++) { | ||
502 | ah->totalSizeDesired[i] = totalSizeDesired[i]; | ||
503 | ah->coarse_high[i] = coarseHigh[i]; | ||
504 | ah->coarse_low[i] = coarseLow[i]; | ||
505 | ah->firpwr[i] = firpwr[i]; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | void ath9k_hw_ani_init(struct ath_hw *ah) | 490 | void ath9k_hw_ani_init(struct ath_hw *ah) |
510 | { | 491 | { |
511 | struct ath_common *common = ath9k_hw_common(ah); | 492 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -531,8 +512,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
531 | 512 | ||
532 | ani->ofdmsTurn = true; | 513 | ani->ofdmsTurn = true; |
533 | 514 | ||
534 | ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; | ||
535 | ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; | ||
536 | ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; | 515 | ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; |
537 | ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; | 516 | ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; |
538 | ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; | 517 | ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; |
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 1485bf5e3518..dddb1361039a 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h | |||
@@ -104,7 +104,6 @@ struct ath9k_ani_default { | |||
104 | }; | 104 | }; |
105 | 105 | ||
106 | struct ar5416AniState { | 106 | struct ar5416AniState { |
107 | struct ath9k_channel *c; | ||
108 | u8 noiseImmunityLevel; | 107 | u8 noiseImmunityLevel; |
109 | u8 ofdmNoiseImmunityLevel; | 108 | u8 ofdmNoiseImmunityLevel; |
110 | u8 cckNoiseImmunityLevel; | 109 | u8 cckNoiseImmunityLevel; |
@@ -113,15 +112,9 @@ struct ar5416AniState { | |||
113 | u8 spurImmunityLevel; | 112 | u8 spurImmunityLevel; |
114 | u8 firstepLevel; | 113 | u8 firstepLevel; |
115 | u8 ofdmWeakSigDetect; | 114 | u8 ofdmWeakSigDetect; |
116 | u8 cckWeakSigThreshold; | ||
117 | u32 listenTime; | 115 | u32 listenTime; |
118 | int32_t rssiThrLow; | ||
119 | int32_t rssiThrHigh; | ||
120 | u32 ofdmPhyErrCount; | 116 | u32 ofdmPhyErrCount; |
121 | u32 cckPhyErrCount; | 117 | u32 cckPhyErrCount; |
122 | int16_t pktRssi[2]; | ||
123 | int16_t ofdmErrRssi[2]; | ||
124 | int16_t cckErrRssi[2]; | ||
125 | struct ath9k_ani_default iniDef; | 118 | struct ath9k_ani_default iniDef; |
126 | }; | 119 | }; |
127 | 120 | ||
@@ -147,7 +140,6 @@ struct ar5416Stats { | |||
147 | 140 | ||
148 | void ath9k_enable_mib_counters(struct ath_hw *ah); | 141 | void ath9k_enable_mib_counters(struct ath_hw *ah); |
149 | void ath9k_hw_disable_mib_counters(struct ath_hw *ah); | 142 | void ath9k_hw_disable_mib_counters(struct ath_hw *ah); |
150 | void ath9k_hw_ani_setup(struct ath_hw *ah); | ||
151 | void ath9k_hw_ani_init(struct ath_hw *ah); | 143 | void ath9k_hw_ani_init(struct ath_hw *ah); |
152 | 144 | ||
153 | #endif /* ANI_H */ | 145 | #endif /* ANI_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index f81e7fc60a36..467ccfae2cee 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h | |||
@@ -466,7 +466,7 @@ static const u32 ar5416Bank0[][2] = { | |||
466 | }; | 466 | }; |
467 | 467 | ||
468 | static const u32 ar5416BB_RfGain[][3] = { | 468 | static const u32 ar5416BB_RfGain[][3] = { |
469 | /* Addr 5G_HT20 5G_HT40 */ | 469 | /* Addr 5G 2G */ |
470 | {0x00009a00, 0x00000000, 0x00000000}, | 470 | {0x00009a00, 0x00000000, 0x00000000}, |
471 | {0x00009a04, 0x00000040, 0x00000040}, | 471 | {0x00009a04, 0x00000040, 0x00000040}, |
472 | {0x00009a08, 0x00000080, 0x00000080}, | 472 | {0x00009a08, 0x00000080, 0x00000080}, |
@@ -546,12 +546,12 @@ static const u32 ar5416Bank2[][2] = { | |||
546 | }; | 546 | }; |
547 | 547 | ||
548 | static const u32 ar5416Bank3[][3] = { | 548 | static const u32 ar5416Bank3[][3] = { |
549 | /* Addr 5G_HT20 5G_HT40 */ | 549 | /* Addr 5G 2G */ |
550 | {0x000098f0, 0x01400018, 0x01c00018}, | 550 | {0x000098f0, 0x01400018, 0x01c00018}, |
551 | }; | 551 | }; |
552 | 552 | ||
553 | static const u32 ar5416Bank6[][3] = { | 553 | static const u32 ar5416Bank6[][3] = { |
554 | /* Addr 5G_HT20 5G_HT40 */ | 554 | /* Addr 5G 2G */ |
555 | {0x0000989c, 0x00000000, 0x00000000}, | 555 | {0x0000989c, 0x00000000, 0x00000000}, |
556 | {0x0000989c, 0x00000000, 0x00000000}, | 556 | {0x0000989c, 0x00000000, 0x00000000}, |
557 | {0x0000989c, 0x00000000, 0x00000000}, | 557 | {0x0000989c, 0x00000000, 0x00000000}, |
@@ -588,7 +588,7 @@ static const u32 ar5416Bank6[][3] = { | |||
588 | }; | 588 | }; |
589 | 589 | ||
590 | static const u32 ar5416Bank6TPC[][3] = { | 590 | static const u32 ar5416Bank6TPC[][3] = { |
591 | /* Addr 5G_HT20 5G_HT40 */ | 591 | /* Addr 5G 2G */ |
592 | {0x0000989c, 0x00000000, 0x00000000}, | 592 | {0x0000989c, 0x00000000, 0x00000000}, |
593 | {0x0000989c, 0x00000000, 0x00000000}, | 593 | {0x0000989c, 0x00000000, 0x00000000}, |
594 | {0x0000989c, 0x00000000, 0x00000000}, | 594 | {0x0000989c, 0x00000000, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 874186bfda41..fd69376ecc83 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -470,16 +470,15 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, | |||
470 | static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) | 470 | static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) |
471 | { | 471 | { |
472 | #define ATH_ALLOC_BANK(bank, size) do { \ | 472 | #define ATH_ALLOC_BANK(bank, size) do { \ |
473 | bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \ | 473 | bank = devm_kzalloc(ah->dev, sizeof(u32) * size, GFP_KERNEL); \ |
474 | if (!bank) { \ | 474 | if (!bank) \ |
475 | ath_err(common, "Cannot allocate RF banks\n"); \ | 475 | goto error; \ |
476 | return -ENOMEM; \ | ||
477 | } \ | ||
478 | } while (0); | 476 | } while (0); |
479 | 477 | ||
480 | struct ath_common *common = ath9k_hw_common(ah); | 478 | struct ath_common *common = ath9k_hw_common(ah); |
481 | 479 | ||
482 | BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); | 480 | if (AR_SREV_9280_20_OR_LATER(ah)) |
481 | return 0; | ||
483 | 482 | ||
484 | ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); | 483 | ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); |
485 | ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); | 484 | ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); |
@@ -492,35 +491,12 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) | |||
492 | 491 | ||
493 | return 0; | 492 | return 0; |
494 | #undef ATH_ALLOC_BANK | 493 | #undef ATH_ALLOC_BANK |
494 | error: | ||
495 | ath_err(common, "Cannot allocate RF banks\n"); | ||
496 | return -ENOMEM; | ||
495 | } | 497 | } |
496 | 498 | ||
497 | 499 | ||
498 | /** | ||
499 | * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers | ||
500 | * @ah: atheros hardware struture | ||
501 | * For the external AR2133/AR5133 radios banks. | ||
502 | */ | ||
503 | static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) | ||
504 | { | ||
505 | #define ATH_FREE_BANK(bank) do { \ | ||
506 | kfree(bank); \ | ||
507 | bank = NULL; \ | ||
508 | } while (0); | ||
509 | |||
510 | BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); | ||
511 | |||
512 | ATH_FREE_BANK(ah->analogBank0Data); | ||
513 | ATH_FREE_BANK(ah->analogBank1Data); | ||
514 | ATH_FREE_BANK(ah->analogBank2Data); | ||
515 | ATH_FREE_BANK(ah->analogBank3Data); | ||
516 | ATH_FREE_BANK(ah->analogBank6Data); | ||
517 | ATH_FREE_BANK(ah->analogBank6TPCData); | ||
518 | ATH_FREE_BANK(ah->analogBank7Data); | ||
519 | ATH_FREE_BANK(ah->bank6Temp); | ||
520 | |||
521 | #undef ATH_FREE_BANK | ||
522 | } | ||
523 | |||
524 | /* * | 500 | /* * |
525 | * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM | 501 | * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM |
526 | * @ah: atheros hardware structure | 502 | * @ah: atheros hardware structure |
@@ -1380,7 +1356,7 @@ static void ar5008_hw_set_radar_conf(struct ath_hw *ah) | |||
1380 | conf->radar_inband = 8; | 1356 | conf->radar_inband = 8; |
1381 | } | 1357 | } |
1382 | 1358 | ||
1383 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah) | 1359 | int ar5008_hw_attach_phy_ops(struct ath_hw *ah) |
1384 | { | 1360 | { |
1385 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | 1361 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); |
1386 | static const u32 ar5416_cca_regs[6] = { | 1362 | static const u32 ar5416_cca_regs[6] = { |
@@ -1391,12 +1367,15 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) | |||
1391 | AR_PHY_CH1_EXT_CCA, | 1367 | AR_PHY_CH1_EXT_CCA, |
1392 | AR_PHY_CH2_EXT_CCA | 1368 | AR_PHY_CH2_EXT_CCA |
1393 | }; | 1369 | }; |
1370 | int ret; | ||
1371 | |||
1372 | ret = ar5008_hw_rf_alloc_ext_banks(ah); | ||
1373 | if (ret) | ||
1374 | return ret; | ||
1394 | 1375 | ||
1395 | priv_ops->rf_set_freq = ar5008_hw_set_channel; | 1376 | priv_ops->rf_set_freq = ar5008_hw_set_channel; |
1396 | priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; | 1377 | priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; |
1397 | 1378 | ||
1398 | priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks; | ||
1399 | priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks; | ||
1400 | priv_ops->set_rf_regs = ar5008_hw_set_rf_regs; | 1379 | priv_ops->set_rf_regs = ar5008_hw_set_rf_regs; |
1401 | priv_ops->set_channel_regs = ar5008_hw_set_channel_regs; | 1380 | priv_ops->set_channel_regs = ar5008_hw_set_channel_regs; |
1402 | priv_ops->init_bb = ar5008_hw_init_bb; | 1381 | priv_ops->init_bb = ar5008_hw_init_bb; |
@@ -1421,4 +1400,5 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) | |||
1421 | ar5008_hw_set_nf_limits(ah); | 1400 | ar5008_hw_set_nf_limits(ah); |
1422 | ar5008_hw_set_radar_conf(ah); | 1401 | ar5008_hw_set_radar_conf(ah); |
1423 | memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs)); | 1402 | memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs)); |
1403 | return 0; | ||
1424 | } | 1404 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h index ea4a230997ac..59524e1d4678 100644 --- a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h | |||
@@ -460,7 +460,7 @@ static const u32 ar5416Common_9100[][2] = { | |||
460 | }; | 460 | }; |
461 | 461 | ||
462 | static const u32 ar5416Bank6_9100[][3] = { | 462 | static const u32 ar5416Bank6_9100[][3] = { |
463 | /* Addr 5G_HT20 5G_HT40 */ | 463 | /* Addr 5G 2G */ |
464 | {0x0000989c, 0x00000000, 0x00000000}, | 464 | {0x0000989c, 0x00000000, 0x00000000}, |
465 | {0x0000989c, 0x00000000, 0x00000000}, | 465 | {0x0000989c, 0x00000000, 0x00000000}, |
466 | {0x0000989c, 0x00000000, 0x00000000}, | 466 | {0x0000989c, 0x00000000, 0x00000000}, |
@@ -497,7 +497,7 @@ static const u32 ar5416Bank6_9100[][3] = { | |||
497 | }; | 497 | }; |
498 | 498 | ||
499 | static const u32 ar5416Bank6TPC_9100[][3] = { | 499 | static const u32 ar5416Bank6TPC_9100[][3] = { |
500 | /* Addr 5G_HT20 5G_HT40 */ | 500 | /* Addr 5G 2G */ |
501 | {0x0000989c, 0x00000000, 0x00000000}, | 501 | {0x0000989c, 0x00000000, 0x00000000}, |
502 | {0x0000989c, 0x00000000, 0x00000000}, | 502 | {0x0000989c, 0x00000000, 0x00000000}, |
503 | {0x0000989c, 0x00000000, 0x00000000}, | 503 | {0x0000989c, 0x00000000, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 648da3e885e9..f053d978540e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -23,13 +23,13 @@ | |||
23 | 23 | ||
24 | /* General hardware code for the A5008/AR9001/AR9002 hadware families */ | 24 | /* General hardware code for the A5008/AR9001/AR9002 hadware families */ |
25 | 25 | ||
26 | static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | 26 | static int ar9002_hw_init_mode_regs(struct ath_hw *ah) |
27 | { | 27 | { |
28 | if (AR_SREV_9271(ah)) { | 28 | if (AR_SREV_9271(ah)) { |
29 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271); | 29 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271); |
30 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271); | 30 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271); |
31 | INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg); | 31 | INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg); |
32 | return; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | if (ah->config.pcie_clock_req) | 35 | if (ah->config.pcie_clock_req) |
@@ -102,9 +102,9 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
102 | u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns; | 102 | u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns; |
103 | u32 *data; | 103 | u32 *data; |
104 | 104 | ||
105 | data = kmalloc(size, GFP_KERNEL); | 105 | data = devm_kzalloc(ah->dev, size, GFP_KERNEL); |
106 | if (!data) | 106 | if (!data) |
107 | return; | 107 | return -ENOMEM; |
108 | 108 | ||
109 | memcpy(data, addac->ia_array, size); | 109 | memcpy(data, addac->ia_array, size); |
110 | addac->ia_array = data; | 110 | addac->ia_array = data; |
@@ -120,6 +120,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
120 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | 120 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, |
121 | ar9287Common_japan_2484_cck_fir_coeff_9287_1_1); | 121 | ar9287Common_japan_2484_cck_fir_coeff_9287_1_1); |
122 | } | 122 | } |
123 | return 0; | ||
123 | } | 124 | } |
124 | 125 | ||
125 | static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) | 126 | static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) |
@@ -409,22 +410,30 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah) | |||
409 | } | 410 | } |
410 | 411 | ||
411 | /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ | 412 | /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ |
412 | void ar9002_hw_attach_ops(struct ath_hw *ah) | 413 | int ar9002_hw_attach_ops(struct ath_hw *ah) |
413 | { | 414 | { |
414 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | 415 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); |
415 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | 416 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); |
417 | int ret; | ||
418 | |||
419 | ret = ar9002_hw_init_mode_regs(ah); | ||
420 | if (ret) | ||
421 | return ret; | ||
416 | 422 | ||
417 | priv_ops->init_mode_regs = ar9002_hw_init_mode_regs; | ||
418 | priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; | 423 | priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; |
419 | 424 | ||
420 | ops->config_pci_powersave = ar9002_hw_configpcipowersave; | 425 | ops->config_pci_powersave = ar9002_hw_configpcipowersave; |
421 | 426 | ||
422 | ar5008_hw_attach_phy_ops(ah); | 427 | ret = ar5008_hw_attach_phy_ops(ah); |
428 | if (ret) | ||
429 | return ret; | ||
430 | |||
423 | if (AR_SREV_9280_20_OR_LATER(ah)) | 431 | if (AR_SREV_9280_20_OR_LATER(ah)) |
424 | ar9002_hw_attach_phy_ops(ah); | 432 | ar9002_hw_attach_phy_ops(ah); |
425 | 433 | ||
426 | ar9002_hw_attach_calib_ops(ah); | 434 | ar9002_hw_attach_calib_ops(ah); |
427 | ar9002_hw_attach_mac_ops(ah); | 435 | ar9002_hw_attach_mac_ops(ah); |
436 | return 0; | ||
428 | } | 437 | } |
429 | 438 | ||
430 | void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) | 439 | void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 846dd7974eb8..f4003512d8d5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
@@ -555,14 +555,73 @@ static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah, | |||
555 | REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); | 555 | REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); |
556 | } | 556 | } |
557 | 557 | ||
558 | static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, | ||
559 | struct ath_spec_scan *param) | ||
560 | { | ||
561 | u8 count; | ||
562 | |||
563 | if (!param->enabled) { | ||
564 | REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
565 | AR_PHY_SPECTRAL_SCAN_ENABLE); | ||
566 | return; | ||
567 | } | ||
568 | REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA); | ||
569 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); | ||
570 | |||
571 | if (param->short_repeat) | ||
572 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
573 | AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); | ||
574 | else | ||
575 | REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
576 | AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); | ||
577 | |||
578 | /* on AR92xx, the highest bit of count will make the the chip send | ||
579 | * spectral samples endlessly. Check if this really was intended, | ||
580 | * and fix otherwise. | ||
581 | */ | ||
582 | count = param->count; | ||
583 | if (param->endless) | ||
584 | count = 0x80; | ||
585 | else if (count & 0x80) | ||
586 | count = 0x7f; | ||
587 | |||
588 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
589 | AR_PHY_SPECTRAL_SCAN_COUNT, count); | ||
590 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
591 | AR_PHY_SPECTRAL_SCAN_PERIOD, param->period); | ||
592 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
593 | AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period); | ||
594 | |||
595 | return; | ||
596 | } | ||
597 | |||
598 | static void ar9002_hw_spectral_scan_trigger(struct ath_hw *ah) | ||
599 | { | ||
600 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); | ||
601 | /* Activate spectral scan */ | ||
602 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
603 | AR_PHY_SPECTRAL_SCAN_ACTIVE); | ||
604 | } | ||
605 | |||
606 | static void ar9002_hw_spectral_scan_wait(struct ath_hw *ah) | ||
607 | { | ||
608 | struct ath_common *common = ath9k_hw_common(ah); | ||
609 | |||
610 | /* Poll for spectral scan complete */ | ||
611 | if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN, | ||
612 | AR_PHY_SPECTRAL_SCAN_ACTIVE, | ||
613 | 0, AH_WAIT_TIMEOUT)) { | ||
614 | ath_err(common, "spectral scan wait failed\n"); | ||
615 | return; | ||
616 | } | ||
617 | } | ||
618 | |||
558 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah) | 619 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah) |
559 | { | 620 | { |
560 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | 621 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); |
561 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | 622 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); |
562 | 623 | ||
563 | priv_ops->set_rf_regs = NULL; | 624 | priv_ops->set_rf_regs = NULL; |
564 | priv_ops->rf_alloc_ext_banks = NULL; | ||
565 | priv_ops->rf_free_ext_banks = NULL; | ||
566 | priv_ops->rf_set_freq = ar9002_hw_set_channel; | 625 | priv_ops->rf_set_freq = ar9002_hw_set_channel; |
567 | priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate; | 626 | priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate; |
568 | priv_ops->olc_init = ar9002_olc_init; | 627 | priv_ops->olc_init = ar9002_olc_init; |
@@ -571,6 +630,9 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) | |||
571 | 630 | ||
572 | ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; | 631 | ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; |
573 | ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; | 632 | ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; |
633 | ops->spectral_scan_config = ar9002_hw_spectral_scan_config; | ||
634 | ops->spectral_scan_trigger = ar9002_hw_spectral_scan_trigger; | ||
635 | ops->spectral_scan_wait = ar9002_hw_spectral_scan_wait; | ||
574 | 636 | ||
575 | ar9002_hw_set_nf_limits(ah); | 637 | ar9002_hw_set_nf_limits(ah); |
576 | } | 638 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 262e1e036fd7..db5ffada2217 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
@@ -744,6 +744,186 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { | |||
744 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 744 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
745 | }; | 745 | }; |
746 | 746 | ||
747 | static const u32 ar9300Modes_mixed_ob_db_tx_gain_table_2p2[][5] = { | ||
748 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
749 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, | ||
750 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, | ||
751 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, | ||
752 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
753 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
754 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
755 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
756 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
757 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
758 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
759 | {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400}, | ||
760 | {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402}, | ||
761 | {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, | ||
762 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603}, | ||
763 | {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02}, | ||
764 | {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04}, | ||
765 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20}, | ||
766 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20}, | ||
767 | {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22}, | ||
768 | {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24}, | ||
769 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640}, | ||
770 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660}, | ||
771 | {0x0000a544, 0x52022470, 0x52022470, 0x3b001861, 0x3b001861}, | ||
772 | {0x0000a548, 0x55022490, 0x55022490, 0x3e001a81, 0x3e001a81}, | ||
773 | {0x0000a54c, 0x59022492, 0x59022492, 0x42001a83, 0x42001a83}, | ||
774 | {0x0000a550, 0x5d022692, 0x5d022692, 0x44001c84, 0x44001c84}, | ||
775 | {0x0000a554, 0x61022892, 0x61022892, 0x48001ce3, 0x48001ce3}, | ||
776 | {0x0000a558, 0x65024890, 0x65024890, 0x4c001ce5, 0x4c001ce5}, | ||
777 | {0x0000a55c, 0x69024892, 0x69024892, 0x50001ce9, 0x50001ce9}, | ||
778 | {0x0000a560, 0x6e024c92, 0x6e024c92, 0x54001ceb, 0x54001ceb}, | ||
779 | {0x0000a564, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec}, | ||
780 | {0x0000a568, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec}, | ||
781 | {0x0000a56c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec}, | ||
782 | {0x0000a570, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec}, | ||
783 | {0x0000a574, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec}, | ||
784 | {0x0000a578, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec}, | ||
785 | {0x0000a57c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec}, | ||
786 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
787 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
788 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
789 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
790 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
791 | {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400}, | ||
792 | {0x0000a598, 0x21802220, 0x21802220, 0x15800402, 0x15800402}, | ||
793 | {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, | ||
794 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603}, | ||
795 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02}, | ||
796 | {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04}, | ||
797 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20}, | ||
798 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20}, | ||
799 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22}, | ||
800 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24}, | ||
801 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640}, | ||
802 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660}, | ||
803 | {0x0000a5c4, 0x52822470, 0x52822470, 0x3b801861, 0x3b801861}, | ||
804 | {0x0000a5c8, 0x55822490, 0x55822490, 0x3e801a81, 0x3e801a81}, | ||
805 | {0x0000a5cc, 0x59822492, 0x59822492, 0x42801a83, 0x42801a83}, | ||
806 | {0x0000a5d0, 0x5d822692, 0x5d822692, 0x44801c84, 0x44801c84}, | ||
807 | {0x0000a5d4, 0x61822892, 0x61822892, 0x48801ce3, 0x48801ce3}, | ||
808 | {0x0000a5d8, 0x65824890, 0x65824890, 0x4c801ce5, 0x4c801ce5}, | ||
809 | {0x0000a5dc, 0x69824892, 0x69824892, 0x50801ce9, 0x50801ce9}, | ||
810 | {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x54801ceb, 0x54801ceb}, | ||
811 | {0x0000a5e4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec}, | ||
812 | {0x0000a5e8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec}, | ||
813 | {0x0000a5ec, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec}, | ||
814 | {0x0000a5f0, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec}, | ||
815 | {0x0000a5f4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec}, | ||
816 | {0x0000a5f8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec}, | ||
817 | {0x0000a5fc, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec}, | ||
818 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
819 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
820 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
821 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
822 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
823 | {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, | ||
824 | {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, | ||
825 | {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, | ||
826 | {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, | ||
827 | {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, | ||
828 | {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, | ||
829 | {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | ||
830 | {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | ||
831 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | ||
832 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | ||
833 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | ||
834 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, | ||
835 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, | ||
836 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, | ||
837 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
838 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, | ||
839 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, | ||
840 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, | ||
841 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
842 | {0x00016044, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4}, | ||
843 | {0x00016048, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001}, | ||
844 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
845 | {0x00016444, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4}, | ||
846 | {0x00016448, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001}, | ||
847 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
848 | {0x00016844, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4}, | ||
849 | {0x00016848, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001}, | ||
850 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
851 | }; | ||
852 | |||
853 | static const u32 ar9300Modes_type5_tx_gain_table_2p2[][5] = { | ||
854 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
855 | {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | ||
856 | {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | ||
857 | {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | ||
858 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
859 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
860 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
861 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
862 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
863 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
864 | {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, | ||
865 | {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, | ||
866 | {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, | ||
867 | {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, | ||
868 | {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, | ||
869 | {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, | ||
870 | {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, | ||
871 | {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, | ||
872 | {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, | ||
873 | {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, | ||
874 | {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, | ||
875 | {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, | ||
876 | {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, | ||
877 | {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, | ||
878 | {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, | ||
879 | {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83}, | ||
880 | {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84}, | ||
881 | {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, | ||
882 | {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, | ||
883 | {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, | ||
884 | {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, | ||
885 | {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
886 | {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
887 | {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
888 | {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
889 | {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
890 | {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
891 | {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
892 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
893 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
894 | {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | ||
895 | {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | ||
896 | {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | ||
897 | {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, | ||
898 | {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, | ||
899 | {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, | ||
900 | {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, | ||
901 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, | ||
902 | {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, | ||
903 | {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
904 | {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
905 | {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
906 | {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
907 | {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
908 | {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | ||
909 | {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | ||
910 | {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | ||
911 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
912 | {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | ||
913 | {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | ||
914 | {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | ||
915 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
916 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
917 | {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, | ||
918 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
919 | {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
920 | {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, | ||
921 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
922 | {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
923 | {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, | ||
924 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
925 | }; | ||
926 | |||
747 | static const u32 ar9300Common_rx_gain_table_2p2[][2] = { | 927 | static const u32 ar9300Common_rx_gain_table_2p2[][2] = { |
748 | /* Addr allmodes */ | 928 | /* Addr allmodes */ |
749 | {0x0000a000, 0x00010000}, | 929 | {0x0000a000, 0x00010000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8b0d8dcd7625..4cc13940c895 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -32,7 +32,6 @@ struct coeff { | |||
32 | 32 | ||
33 | enum ar9003_cal_types { | 33 | enum ar9003_cal_types { |
34 | IQ_MISMATCH_CAL = BIT(0), | 34 | IQ_MISMATCH_CAL = BIT(0), |
35 | TEMP_COMP_CAL = BIT(1), | ||
36 | }; | 35 | }; |
37 | 36 | ||
38 | static void ar9003_hw_setup_calibration(struct ath_hw *ah, | 37 | static void ar9003_hw_setup_calibration(struct ath_hw *ah, |
@@ -49,7 +48,7 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, | |||
49 | */ | 48 | */ |
50 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | 49 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, |
51 | AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX, | 50 | AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX, |
52 | currCal->calData->calCountMax); | 51 | currCal->calData->calCountMax); |
53 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | 52 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); |
54 | 53 | ||
55 | ath_dbg(common, CALIBRATE, | 54 | ath_dbg(common, CALIBRATE, |
@@ -58,14 +57,8 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, | |||
58 | /* Kick-off cal */ | 57 | /* Kick-off cal */ |
59 | REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); | 58 | REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); |
60 | break; | 59 | break; |
61 | case TEMP_COMP_CAL: | 60 | default: |
62 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, | 61 | ath_err(common, "Invalid calibration type\n"); |
63 | AR_PHY_65NM_CH0_THERM_LOCAL, 1); | ||
64 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, | ||
65 | AR_PHY_65NM_CH0_THERM_START, 1); | ||
66 | |||
67 | ath_dbg(common, CALIBRATE, | ||
68 | "starting Temperature Compensation Calibration\n"); | ||
69 | break; | 62 | break; |
70 | } | 63 | } |
71 | } | 64 | } |
@@ -323,6 +316,14 @@ static const struct ath9k_percal_data iq_cal_single_sample = { | |||
323 | static void ar9003_hw_init_cal_settings(struct ath_hw *ah) | 316 | static void ar9003_hw_init_cal_settings(struct ath_hw *ah) |
324 | { | 317 | { |
325 | ah->iq_caldata.calData = &iq_cal_single_sample; | 318 | ah->iq_caldata.calData = &iq_cal_single_sample; |
319 | |||
320 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
321 | ah->enabled_cals |= TX_IQ_CAL; | ||
322 | if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah)) | ||
323 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; | ||
324 | } | ||
325 | |||
326 | ah->supp_cals = IQ_MISMATCH_CAL; | ||
326 | } | 327 | } |
327 | 328 | ||
328 | /* | 329 | /* |
@@ -959,22 +960,70 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) | |||
959 | AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); | 960 | AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); |
960 | } | 961 | } |
961 | 962 | ||
963 | static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, | ||
964 | struct ath9k_channel *chan) | ||
965 | { | ||
966 | int i; | ||
967 | |||
968 | if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah)) | ||
969 | return; | ||
970 | |||
971 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
972 | if (!(ah->rxchainmask & (1 << i))) | ||
973 | continue; | ||
974 | ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan)); | ||
975 | } | ||
976 | } | ||
977 | |||
978 | static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) | ||
979 | { | ||
980 | u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0, | ||
981 | AR_PHY_CL_TAB_1, | ||
982 | AR_PHY_CL_TAB_2 }; | ||
983 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
984 | bool txclcal_done = false; | ||
985 | int i, j; | ||
986 | |||
987 | if (!caldata || !(ah->enabled_cals & TX_CL_CAL)) | ||
988 | return; | ||
989 | |||
990 | txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
991 | AR_PHY_AGC_CONTROL_CLC_SUCCESS); | ||
992 | |||
993 | if (caldata->done_txclcal_once) { | ||
994 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
995 | if (!(ah->txchainmask & (1 << i))) | ||
996 | continue; | ||
997 | for (j = 0; j < MAX_CL_TAB_ENTRY; j++) | ||
998 | REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]), | ||
999 | caldata->tx_clcal[i][j]); | ||
1000 | } | ||
1001 | } else if (is_reusable && txclcal_done) { | ||
1002 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
1003 | if (!(ah->txchainmask & (1 << i))) | ||
1004 | continue; | ||
1005 | for (j = 0; j < MAX_CL_TAB_ENTRY; j++) | ||
1006 | caldata->tx_clcal[i][j] = | ||
1007 | REG_READ(ah, CL_TAB_ENTRY(cl_idx[i])); | ||
1008 | } | ||
1009 | caldata->done_txclcal_once = true; | ||
1010 | } | ||
1011 | } | ||
1012 | |||
962 | static bool ar9003_hw_init_cal(struct ath_hw *ah, | 1013 | static bool ar9003_hw_init_cal(struct ath_hw *ah, |
963 | struct ath9k_channel *chan) | 1014 | struct ath9k_channel *chan) |
964 | { | 1015 | { |
965 | struct ath_common *common = ath9k_hw_common(ah); | 1016 | struct ath_common *common = ath9k_hw_common(ah); |
966 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 1017 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
967 | bool txiqcal_done = false, txclcal_done = false; | 1018 | bool txiqcal_done = false; |
968 | bool is_reusable = true, status = true; | 1019 | bool is_reusable = true, status = true; |
969 | bool run_rtt_cal = false, run_agc_cal; | 1020 | bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; |
970 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); | 1021 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); |
971 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | | 1022 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | |
972 | AR_PHY_AGC_CONTROL_FLTR_CAL | | 1023 | AR_PHY_AGC_CONTROL_FLTR_CAL | |
973 | AR_PHY_AGC_CONTROL_PKDET_CAL; | 1024 | AR_PHY_AGC_CONTROL_PKDET_CAL; |
974 | int i, j; | 1025 | |
975 | u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0, | 1026 | ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); |
976 | AR_PHY_CL_TAB_1, | ||
977 | AR_PHY_CL_TAB_2 }; | ||
978 | 1027 | ||
979 | if (rtt) { | 1028 | if (rtt) { |
980 | if (!ar9003_hw_rtt_restore(ah, chan)) | 1029 | if (!ar9003_hw_rtt_restore(ah, chan)) |
@@ -1012,7 +1061,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
1012 | } | 1061 | } |
1013 | } | 1062 | } |
1014 | 1063 | ||
1015 | if (!(ah->enabled_cals & TX_IQ_CAL)) | 1064 | if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) || |
1065 | !(ah->enabled_cals & TX_IQ_CAL)) | ||
1016 | goto skip_tx_iqcal; | 1066 | goto skip_tx_iqcal; |
1017 | 1067 | ||
1018 | /* Do Tx IQ Calibration */ | 1068 | /* Do Tx IQ Calibration */ |
@@ -1032,21 +1082,22 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
1032 | REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, | 1082 | REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, |
1033 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); | 1083 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); |
1034 | txiqcal_done = run_agc_cal = true; | 1084 | txiqcal_done = run_agc_cal = true; |
1035 | goto skip_tx_iqcal; | 1085 | } else if (caldata && !caldata->done_txiqcal_once) { |
1036 | } else if (caldata && !caldata->done_txiqcal_once) | ||
1037 | run_agc_cal = true; | 1086 | run_agc_cal = true; |
1087 | sep_iq_cal = true; | ||
1088 | } | ||
1038 | 1089 | ||
1090 | skip_tx_iqcal: | ||
1039 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) | 1091 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
1040 | ar9003_mci_init_cal_req(ah, &is_reusable); | 1092 | ar9003_mci_init_cal_req(ah, &is_reusable); |
1041 | 1093 | ||
1042 | if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) { | 1094 | if (sep_iq_cal) { |
1043 | txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); | 1095 | txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); |
1044 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | 1096 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); |
1045 | udelay(5); | 1097 | udelay(5); |
1046 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 1098 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); |
1047 | } | 1099 | } |
1048 | 1100 | ||
1049 | skip_tx_iqcal: | ||
1050 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { | 1101 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { |
1051 | /* Calibrate the AGC */ | 1102 | /* Calibrate the AGC */ |
1052 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 1103 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, |
@@ -1057,14 +1108,8 @@ skip_tx_iqcal: | |||
1057 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | 1108 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, |
1058 | AR_PHY_AGC_CONTROL_CAL, | 1109 | AR_PHY_AGC_CONTROL_CAL, |
1059 | 0, AH_WAIT_TIMEOUT); | 1110 | 0, AH_WAIT_TIMEOUT); |
1060 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { | 1111 | |
1061 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 1112 | ar9003_hw_do_manual_peak_cal(ah, chan); |
1062 | if (!(ah->rxchainmask & (1 << i))) | ||
1063 | continue; | ||
1064 | ar9003_hw_manual_peak_cal(ah, i, | ||
1065 | IS_CHAN_2GHZ(chan)); | ||
1066 | } | ||
1067 | } | ||
1068 | } | 1113 | } |
1069 | 1114 | ||
1070 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) | 1115 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
@@ -1089,31 +1134,7 @@ skip_tx_iqcal: | |||
1089 | else if (caldata && caldata->done_txiqcal_once) | 1134 | else if (caldata && caldata->done_txiqcal_once) |
1090 | ar9003_hw_tx_iq_cal_reload(ah); | 1135 | ar9003_hw_tx_iq_cal_reload(ah); |
1091 | 1136 | ||
1092 | #define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j)) | 1137 | ar9003_hw_cl_cal_post_proc(ah, is_reusable); |
1093 | if (caldata && (ah->enabled_cals & TX_CL_CAL)) { | ||
1094 | txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
1095 | AR_PHY_AGC_CONTROL_CLC_SUCCESS); | ||
1096 | if (caldata->done_txclcal_once) { | ||
1097 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
1098 | if (!(ah->txchainmask & (1 << i))) | ||
1099 | continue; | ||
1100 | for (j = 0; j < MAX_CL_TAB_ENTRY; j++) | ||
1101 | REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]), | ||
1102 | caldata->tx_clcal[i][j]); | ||
1103 | } | ||
1104 | } else if (is_reusable && txclcal_done) { | ||
1105 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
1106 | if (!(ah->txchainmask & (1 << i))) | ||
1107 | continue; | ||
1108 | for (j = 0; j < MAX_CL_TAB_ENTRY; j++) | ||
1109 | caldata->tx_clcal[i][j] = | ||
1110 | REG_READ(ah, | ||
1111 | CL_TAB_ENTRY(cl_idx[i])); | ||
1112 | } | ||
1113 | caldata->done_txclcal_once = true; | ||
1114 | } | ||
1115 | } | ||
1116 | #undef CL_TAB_ENTRY | ||
1117 | 1138 | ||
1118 | if (run_rtt_cal && caldata) { | 1139 | if (run_rtt_cal && caldata) { |
1119 | if (is_reusable) { | 1140 | if (is_reusable) { |
@@ -1131,20 +1152,10 @@ skip_tx_iqcal: | |||
1131 | 1152 | ||
1132 | /* Initialize list pointers */ | 1153 | /* Initialize list pointers */ |
1133 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | 1154 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; |
1134 | ah->supp_cals = IQ_MISMATCH_CAL; | ||
1135 | |||
1136 | if (ah->supp_cals & IQ_MISMATCH_CAL) { | ||
1137 | INIT_CAL(&ah->iq_caldata); | ||
1138 | INSERT_CAL(ah, &ah->iq_caldata); | ||
1139 | ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); | ||
1140 | } | ||
1141 | 1155 | ||
1142 | if (ah->supp_cals & TEMP_COMP_CAL) { | 1156 | INIT_CAL(&ah->iq_caldata); |
1143 | INIT_CAL(&ah->tempCompCalData); | 1157 | INSERT_CAL(ah, &ah->iq_caldata); |
1144 | INSERT_CAL(ah, &ah->tempCompCalData); | 1158 | ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); |
1145 | ath_dbg(common, CALIBRATE, | ||
1146 | "enabling Temperature Compensation Calibration\n"); | ||
1147 | } | ||
1148 | 1159 | ||
1149 | /* Initialize current pointer to first element in list */ | 1160 | /* Initialize current pointer to first element in list */ |
1150 | ah->cal_list_curr = ah->cal_list; | 1161 | ah->cal_list_curr = ah->cal_list; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 562186ca9b52..881e989ea470 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -4586,14 +4586,14 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | |||
4586 | return 0; | 4586 | return 0; |
4587 | } | 4587 | } |
4588 | 4588 | ||
4589 | static int ar9003_hw_power_control_override(struct ath_hw *ah, | 4589 | static void ar9003_hw_power_control_override(struct ath_hw *ah, |
4590 | int frequency, | 4590 | int frequency, |
4591 | int *correction, | 4591 | int *correction, |
4592 | int *voltage, int *temperature) | 4592 | int *voltage, int *temperature) |
4593 | { | 4593 | { |
4594 | int tempSlope = 0; | 4594 | int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0; |
4595 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 4595 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
4596 | int f[8], t[8], i; | 4596 | int f[8], t[8], t1[3], t2[3], i; |
4597 | 4597 | ||
4598 | REG_RMW(ah, AR_PHY_TPC_11_B0, | 4598 | REG_RMW(ah, AR_PHY_TPC_11_B0, |
4599 | (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), | 4599 | (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), |
@@ -4624,38 +4624,108 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, | |||
4624 | * enable temperature compensation | 4624 | * enable temperature compensation |
4625 | * Need to use register names | 4625 | * Need to use register names |
4626 | */ | 4626 | */ |
4627 | if (frequency < 4000) | 4627 | if (frequency < 4000) { |
4628 | tempSlope = eep->modalHeader2G.tempSlope; | 4628 | temp_slope = eep->modalHeader2G.tempSlope; |
4629 | else if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) { | 4629 | } else { |
4630 | for (i = 0; i < 8; i++) { | 4630 | if (AR_SREV_9550(ah)) { |
4631 | t[i] = eep->base_ext1.tempslopextension[i]; | 4631 | t[0] = eep->base_ext1.tempslopextension[2]; |
4632 | f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0); | 4632 | t1[0] = eep->base_ext1.tempslopextension[3]; |
4633 | t2[0] = eep->base_ext1.tempslopextension[4]; | ||
4634 | f[0] = 5180; | ||
4635 | |||
4636 | t[1] = eep->modalHeader5G.tempSlope; | ||
4637 | t1[1] = eep->base_ext1.tempslopextension[0]; | ||
4638 | t2[1] = eep->base_ext1.tempslopextension[1]; | ||
4639 | f[1] = 5500; | ||
4640 | |||
4641 | t[2] = eep->base_ext1.tempslopextension[5]; | ||
4642 | t1[2] = eep->base_ext1.tempslopextension[6]; | ||
4643 | t2[2] = eep->base_ext1.tempslopextension[7]; | ||
4644 | f[2] = 5785; | ||
4645 | |||
4646 | temp_slope = ar9003_hw_power_interpolate(frequency, | ||
4647 | f, t, 3); | ||
4648 | temp_slope1 = ar9003_hw_power_interpolate(frequency, | ||
4649 | f, t1, 3); | ||
4650 | temp_slope2 = ar9003_hw_power_interpolate(frequency, | ||
4651 | f, t2, 3); | ||
4652 | |||
4653 | goto tempslope; | ||
4633 | } | 4654 | } |
4634 | tempSlope = ar9003_hw_power_interpolate((s32) frequency, | ||
4635 | f, t, 8); | ||
4636 | } else if (eep->base_ext2.tempSlopeLow != 0) { | ||
4637 | t[0] = eep->base_ext2.tempSlopeLow; | ||
4638 | f[0] = 5180; | ||
4639 | t[1] = eep->modalHeader5G.tempSlope; | ||
4640 | f[1] = 5500; | ||
4641 | t[2] = eep->base_ext2.tempSlopeHigh; | ||
4642 | f[2] = 5785; | ||
4643 | tempSlope = ar9003_hw_power_interpolate((s32) frequency, | ||
4644 | f, t, 3); | ||
4645 | } else | ||
4646 | tempSlope = eep->modalHeader5G.tempSlope; | ||
4647 | 4655 | ||
4648 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); | 4656 | if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) { |
4657 | for (i = 0; i < 8; i++) { | ||
4658 | t[i] = eep->base_ext1.tempslopextension[i]; | ||
4659 | f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0); | ||
4660 | } | ||
4661 | temp_slope = ar9003_hw_power_interpolate((s32) frequency, | ||
4662 | f, t, 8); | ||
4663 | } else if (eep->base_ext2.tempSlopeLow != 0) { | ||
4664 | t[0] = eep->base_ext2.tempSlopeLow; | ||
4665 | f[0] = 5180; | ||
4666 | t[1] = eep->modalHeader5G.tempSlope; | ||
4667 | f[1] = 5500; | ||
4668 | t[2] = eep->base_ext2.tempSlopeHigh; | ||
4669 | f[2] = 5785; | ||
4670 | temp_slope = ar9003_hw_power_interpolate((s32) frequency, | ||
4671 | f, t, 3); | ||
4672 | } else { | ||
4673 | temp_slope = eep->modalHeader5G.tempSlope; | ||
4674 | } | ||
4675 | } | ||
4676 | |||
4677 | tempslope: | ||
4678 | if (AR_SREV_9550(ah)) { | ||
4679 | /* | ||
4680 | * AR955x has tempSlope register for each chain. | ||
4681 | * Check whether temp_compensation feature is enabled or not. | ||
4682 | */ | ||
4683 | if (eep->baseEepHeader.featureEnable & 0x1) { | ||
4684 | if (frequency < 4000) { | ||
4685 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | ||
4686 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4687 | eep->base_ext2.tempSlopeLow); | ||
4688 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | ||
4689 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4690 | temp_slope); | ||
4691 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | ||
4692 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4693 | eep->base_ext2.tempSlopeHigh); | ||
4694 | } else { | ||
4695 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | ||
4696 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4697 | temp_slope); | ||
4698 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | ||
4699 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4700 | temp_slope1); | ||
4701 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | ||
4702 | AR_PHY_TPC_19_ALPHA_THERM, | ||
4703 | temp_slope2); | ||
4704 | } | ||
4705 | } else { | ||
4706 | /* | ||
4707 | * If temp compensation is not enabled, | ||
4708 | * set all registers to 0. | ||
4709 | */ | ||
4710 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | ||
4711 | AR_PHY_TPC_19_ALPHA_THERM, 0); | ||
4712 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | ||
4713 | AR_PHY_TPC_19_ALPHA_THERM, 0); | ||
4714 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2, | ||
4715 | AR_PHY_TPC_19_ALPHA_THERM, 0); | ||
4716 | } | ||
4717 | } else { | ||
4718 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, | ||
4719 | AR_PHY_TPC_19_ALPHA_THERM, temp_slope); | ||
4720 | } | ||
4649 | 4721 | ||
4650 | if (AR_SREV_9462_20(ah)) | 4722 | if (AR_SREV_9462_20(ah)) |
4651 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, | 4723 | REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, |
4652 | AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope); | 4724 | AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope); |
4653 | 4725 | ||
4654 | 4726 | ||
4655 | REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, | 4727 | REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, |
4656 | temperature[0]); | 4728 | temperature[0]); |
4657 | |||
4658 | return 0; | ||
4659 | } | 4729 | } |
4660 | 4730 | ||
4661 | /* Apply the recorded correction values. */ | 4731 | /* Apply the recorded correction values. */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 59bf5f31e212..a3523c969a3a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -507,28 +507,59 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah) | |||
507 | else if (AR_SREV_9580(ah)) | 507 | else if (AR_SREV_9580(ah)) |
508 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 508 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
509 | ar9580_1p0_mixed_ob_db_tx_gain_table); | 509 | ar9580_1p0_mixed_ob_db_tx_gain_table); |
510 | else | ||
511 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
512 | ar9300Modes_mixed_ob_db_tx_gain_table_2p2); | ||
513 | } | ||
514 | |||
515 | static void ar9003_tx_gain_table_mode5(struct ath_hw *ah) | ||
516 | { | ||
517 | if (AR_SREV_9485_11(ah)) | ||
518 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
519 | ar9485Modes_green_ob_db_tx_gain_1_1); | ||
520 | else if (AR_SREV_9340(ah)) | ||
521 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
522 | ar9340Modes_ub124_tx_gain_table_1p0); | ||
523 | else if (AR_SREV_9580(ah)) | ||
524 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
525 | ar9580_1p0_type5_tx_gain_table); | ||
526 | else if (AR_SREV_9300_22(ah)) | ||
527 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
528 | ar9300Modes_type5_tx_gain_table_2p2); | ||
510 | } | 529 | } |
511 | 530 | ||
531 | static void ar9003_tx_gain_table_mode6(struct ath_hw *ah) | ||
532 | { | ||
533 | if (AR_SREV_9340(ah)) | ||
534 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
535 | ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0); | ||
536 | else if (AR_SREV_9485_11(ah)) | ||
537 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
538 | ar9485Modes_green_spur_ob_db_tx_gain_1_1); | ||
539 | else if (AR_SREV_9580(ah)) | ||
540 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
541 | ar9580_1p0_type6_tx_gain_table); | ||
542 | } | ||
543 | |||
544 | typedef void (*ath_txgain_tab)(struct ath_hw *ah); | ||
545 | |||
512 | static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | 546 | static void ar9003_tx_gain_table_apply(struct ath_hw *ah) |
513 | { | 547 | { |
514 | switch (ar9003_hw_get_tx_gain_idx(ah)) { | 548 | static const ath_txgain_tab modes[] = { |
515 | case 0: | 549 | ar9003_tx_gain_table_mode0, |
516 | default: | 550 | ar9003_tx_gain_table_mode1, |
517 | ar9003_tx_gain_table_mode0(ah); | 551 | ar9003_tx_gain_table_mode2, |
518 | break; | 552 | ar9003_tx_gain_table_mode3, |
519 | case 1: | 553 | ar9003_tx_gain_table_mode4, |
520 | ar9003_tx_gain_table_mode1(ah); | 554 | ar9003_tx_gain_table_mode5, |
521 | break; | 555 | ar9003_tx_gain_table_mode6, |
522 | case 2: | 556 | }; |
523 | ar9003_tx_gain_table_mode2(ah); | 557 | int idx = ar9003_hw_get_tx_gain_idx(ah); |
524 | break; | 558 | |
525 | case 3: | 559 | if (idx >= ARRAY_SIZE(modes)) |
526 | ar9003_tx_gain_table_mode3(ah); | 560 | idx = 0; |
527 | break; | 561 | |
528 | case 4: | 562 | modes[idx](ah); |
529 | ar9003_tx_gain_table_mode4(ah); | ||
530 | break; | ||
531 | } | ||
532 | } | 563 | } |
533 | 564 | ||
534 | static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) | 565 | static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) |
@@ -673,7 +704,7 @@ void ar9003_hw_attach_ops(struct ath_hw *ah) | |||
673 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | 704 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); |
674 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | 705 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); |
675 | 706 | ||
676 | priv_ops->init_mode_regs = ar9003_hw_init_mode_regs; | 707 | ar9003_hw_init_mode_regs(ah); |
677 | priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; | 708 | priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; |
678 | 709 | ||
679 | ops->config_pci_powersave = ar9003_hw_configpcipowersave; | 710 | ops->config_pci_powersave = ar9003_hw_configpcipowersave; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index ce19c09fa8e8..2bf6548dd143 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -68,7 +68,7 @@ static const int m2ThreshExt_off = 127; | |||
68 | static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | 68 | static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) |
69 | { | 69 | { |
70 | u16 bMode, fracMode = 0, aModeRefSel = 0; | 70 | u16 bMode, fracMode = 0, aModeRefSel = 0; |
71 | u32 freq, channelSel = 0, reg32 = 0; | 71 | u32 freq, chan_frac, div, channelSel = 0, reg32 = 0; |
72 | struct chan_centers centers; | 72 | struct chan_centers centers; |
73 | int loadSynthChannel; | 73 | int loadSynthChannel; |
74 | 74 | ||
@@ -77,9 +77,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
77 | 77 | ||
78 | if (freq < 4800) { /* 2 GHz, fractional mode */ | 78 | if (freq < 4800) { /* 2 GHz, fractional mode */ |
79 | if (AR_SREV_9330(ah)) { | 79 | if (AR_SREV_9330(ah)) { |
80 | u32 chan_frac; | ||
81 | u32 div; | ||
82 | |||
83 | if (ah->is_clk_25mhz) | 80 | if (ah->is_clk_25mhz) |
84 | div = 75; | 81 | div = 75; |
85 | else | 82 | else |
@@ -89,34 +86,40 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
89 | chan_frac = (((freq * 4) % div) * 0x20000) / div; | 86 | chan_frac = (((freq * 4) % div) * 0x20000) / div; |
90 | channelSel = (channelSel << 17) | chan_frac; | 87 | channelSel = (channelSel << 17) | chan_frac; |
91 | } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { | 88 | } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { |
92 | u32 chan_frac; | ||
93 | |||
94 | /* | 89 | /* |
95 | * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0 | 90 | * freq_ref = 40 / (refdiva >> amoderefsel); |
91 | * where refdiva=1 and amoderefsel=0 | ||
96 | * ndiv = ((chan_mhz * 4) / 3) / freq_ref; | 92 | * ndiv = ((chan_mhz * 4) / 3) / freq_ref; |
97 | * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 | 93 | * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 |
98 | */ | 94 | */ |
99 | channelSel = (freq * 4) / 120; | 95 | channelSel = (freq * 4) / 120; |
100 | chan_frac = (((freq * 4) % 120) * 0x20000) / 120; | 96 | chan_frac = (((freq * 4) % 120) * 0x20000) / 120; |
101 | channelSel = (channelSel << 17) | chan_frac; | 97 | channelSel = (channelSel << 17) | chan_frac; |
102 | } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) { | 98 | } else if (AR_SREV_9340(ah)) { |
103 | if (ah->is_clk_25mhz) { | 99 | if (ah->is_clk_25mhz) { |
104 | u32 chan_frac; | ||
105 | |||
106 | channelSel = (freq * 2) / 75; | 100 | channelSel = (freq * 2) / 75; |
107 | chan_frac = (((freq * 2) % 75) * 0x20000) / 75; | 101 | chan_frac = (((freq * 2) % 75) * 0x20000) / 75; |
108 | channelSel = (channelSel << 17) | chan_frac; | 102 | channelSel = (channelSel << 17) | chan_frac; |
109 | } else | 103 | } else { |
110 | channelSel = CHANSEL_2G(freq) >> 1; | 104 | channelSel = CHANSEL_2G(freq) >> 1; |
111 | } else | 105 | } |
106 | } else if (AR_SREV_9550(ah)) { | ||
107 | if (ah->is_clk_25mhz) | ||
108 | div = 75; | ||
109 | else | ||
110 | div = 120; | ||
111 | |||
112 | channelSel = (freq * 4) / div; | ||
113 | chan_frac = (((freq * 4) % div) * 0x20000) / div; | ||
114 | channelSel = (channelSel << 17) | chan_frac; | ||
115 | } else { | ||
112 | channelSel = CHANSEL_2G(freq); | 116 | channelSel = CHANSEL_2G(freq); |
117 | } | ||
113 | /* Set to 2G mode */ | 118 | /* Set to 2G mode */ |
114 | bMode = 1; | 119 | bMode = 1; |
115 | } else { | 120 | } else { |
116 | if ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) && | 121 | if ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) && |
117 | ah->is_clk_25mhz) { | 122 | ah->is_clk_25mhz) { |
118 | u32 chan_frac; | ||
119 | |||
120 | channelSel = freq / 75; | 123 | channelSel = freq / 75; |
121 | chan_frac = ((freq % 75) * 0x20000) / 75; | 124 | chan_frac = ((freq % 75) * 0x20000) / 75; |
122 | channelSel = (channelSel << 17) | chan_frac; | 125 | channelSel = (channelSel << 17) | chan_frac; |
@@ -586,32 +589,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, | |||
586 | ath9k_hw_synth_delay(ah, chan, synthDelay); | 589 | ath9k_hw_synth_delay(ah, chan, synthDelay); |
587 | } | 590 | } |
588 | 591 | ||
589 | static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) | 592 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) |
590 | { | 593 | { |
591 | switch (rx) { | 594 | if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5) |
592 | case 0x5: | ||
593 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | 595 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, |
594 | AR_PHY_SWAP_ALT_CHAIN); | 596 | AR_PHY_SWAP_ALT_CHAIN); |
595 | case 0x3: | 597 | |
596 | case 0x1: | 598 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); |
597 | case 0x2: | 599 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); |
598 | case 0x7: | ||
599 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); | ||
600 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); | ||
601 | break; | ||
602 | default: | ||
603 | break; | ||
604 | } | ||
605 | 600 | ||
606 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) | 601 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) |
607 | REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); | 602 | tx = 3; |
608 | else | ||
609 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); | ||
610 | 603 | ||
611 | if (tx == 0x5) { | 604 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); |
612 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
613 | AR_PHY_SWAP_ALT_CHAIN); | ||
614 | } | ||
615 | } | 605 | } |
616 | 606 | ||
617 | /* | 607 | /* |
@@ -1450,6 +1440,67 @@ set_rfmode: | |||
1450 | return 0; | 1440 | return 0; |
1451 | } | 1441 | } |
1452 | 1442 | ||
1443 | static void ar9003_hw_spectral_scan_config(struct ath_hw *ah, | ||
1444 | struct ath_spec_scan *param) | ||
1445 | { | ||
1446 | u8 count; | ||
1447 | |||
1448 | if (!param->enabled) { | ||
1449 | REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
1450 | AR_PHY_SPECTRAL_SCAN_ENABLE); | ||
1451 | return; | ||
1452 | } | ||
1453 | |||
1454 | REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA); | ||
1455 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); | ||
1456 | |||
1457 | /* on AR93xx and newer, count = 0 will make the the chip send | ||
1458 | * spectral samples endlessly. Check if this really was intended, | ||
1459 | * and fix otherwise. | ||
1460 | */ | ||
1461 | count = param->count; | ||
1462 | if (param->endless) | ||
1463 | count = 0; | ||
1464 | else if (param->count == 0) | ||
1465 | count = 1; | ||
1466 | |||
1467 | if (param->short_repeat) | ||
1468 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
1469 | AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); | ||
1470 | else | ||
1471 | REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
1472 | AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); | ||
1473 | |||
1474 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
1475 | AR_PHY_SPECTRAL_SCAN_COUNT, count); | ||
1476 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
1477 | AR_PHY_SPECTRAL_SCAN_PERIOD, param->period); | ||
1478 | REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, | ||
1479 | AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period); | ||
1480 | |||
1481 | return; | ||
1482 | } | ||
1483 | |||
1484 | static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah) | ||
1485 | { | ||
1486 | /* Activate spectral scan */ | ||
1487 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, | ||
1488 | AR_PHY_SPECTRAL_SCAN_ACTIVE); | ||
1489 | } | ||
1490 | |||
1491 | static void ar9003_hw_spectral_scan_wait(struct ath_hw *ah) | ||
1492 | { | ||
1493 | struct ath_common *common = ath9k_hw_common(ah); | ||
1494 | |||
1495 | /* Poll for spectral scan complete */ | ||
1496 | if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN, | ||
1497 | AR_PHY_SPECTRAL_SCAN_ACTIVE, | ||
1498 | 0, AH_WAIT_TIMEOUT)) { | ||
1499 | ath_err(common, "spectral scan wait failed\n"); | ||
1500 | return; | ||
1501 | } | ||
1502 | } | ||
1503 | |||
1453 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | 1504 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah) |
1454 | { | 1505 | { |
1455 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | 1506 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); |
@@ -1483,6 +1534,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | |||
1483 | ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; | 1534 | ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; |
1484 | ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; | 1535 | ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; |
1485 | ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv; | 1536 | ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv; |
1537 | ops->spectral_scan_config = ar9003_hw_spectral_scan_config; | ||
1538 | ops->spectral_scan_trigger = ar9003_hw_spectral_scan_trigger; | ||
1539 | ops->spectral_scan_wait = ar9003_hw_spectral_scan_wait; | ||
1486 | 1540 | ||
1487 | ar9003_hw_set_nf_limits(ah); | 1541 | ar9003_hw_set_nf_limits(ah); |
1488 | ar9003_hw_set_radar_conf(ah); | 1542 | ar9003_hw_set_radar_conf(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 107956298488..e71774196c01 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -1028,7 +1028,7 @@ | |||
1028 | #define AR_PHY_TPC_5_B2 (AR_SM2_BASE + 0x208) | 1028 | #define AR_PHY_TPC_5_B2 (AR_SM2_BASE + 0x208) |
1029 | #define AR_PHY_TPC_6_B2 (AR_SM2_BASE + 0x20c) | 1029 | #define AR_PHY_TPC_6_B2 (AR_SM2_BASE + 0x20c) |
1030 | #define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220) | 1030 | #define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220) |
1031 | #define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240) | 1031 | #define AR_PHY_TPC_19_B2 (AR_SM2_BASE + 0x240) |
1032 | #define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c) | 1032 | #define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c) |
1033 | #define AR_PHY_TX_IQCAL_CORR_COEFF_B2(_i) (AR_SM2_BASE + 0x450 + ((_i) << 2)) | 1033 | #define AR_PHY_TX_IQCAL_CORR_COEFF_B2(_i) (AR_SM2_BASE + 0x450 + ((_i) << 2)) |
1034 | 1034 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h index f69d292bdc02..25db9215985a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h | |||
@@ -1172,6 +1172,106 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { | |||
1172 | {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, | 1172 | {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, |
1173 | }; | 1173 | }; |
1174 | 1174 | ||
1175 | static const u32 ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0[][5] = { | ||
1176 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1177 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a}, | ||
1178 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac}, | ||
1179 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00}, | ||
1180 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000}, | ||
1181 | {0x0000a394, 0x00000444, 0x00000444, 0x00000404, 0x00000404}, | ||
1182 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
1183 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1184 | {0x0000a504, 0x06000003, 0x06000003, 0x02000001, 0x02000001}, | ||
1185 | {0x0000a508, 0x0a000020, 0x0a000020, 0x05000003, 0x05000003}, | ||
1186 | {0x0000a50c, 0x10000023, 0x10000023, 0x0a000005, 0x0a000005}, | ||
1187 | {0x0000a510, 0x16000220, 0x16000220, 0x0e000201, 0x0e000201}, | ||
1188 | {0x0000a514, 0x1c000223, 0x1c000223, 0x11000203, 0x11000203}, | ||
1189 | {0x0000a518, 0x21002220, 0x21002220, 0x14000401, 0x14000401}, | ||
1190 | {0x0000a51c, 0x27002223, 0x27002223, 0x18000403, 0x18000403}, | ||
1191 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000602, 0x1b000602}, | ||
1192 | {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000802, 0x1f000802}, | ||
1193 | {0x0000a528, 0x34022225, 0x34022225, 0x21000620, 0x21000620}, | ||
1194 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x25000820, 0x25000820}, | ||
1195 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x29000822, 0x29000822}, | ||
1196 | {0x0000a534, 0x4202242a, 0x4202242a, 0x2d000824, 0x2d000824}, | ||
1197 | {0x0000a538, 0x4702244a, 0x4702244a, 0x30000828, 0x30000828}, | ||
1198 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x3400082a, 0x3400082a}, | ||
1199 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38000849, 0x38000849}, | ||
1200 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3b000a2c, 0x3b000a2c}, | ||
1201 | {0x0000a548, 0x5702286c, 0x5702286c, 0x3e000e2b, 0x3e000e2b}, | ||
1202 | {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42000e2d, 0x42000e2d}, | ||
1203 | {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4500124a, 0x4500124a}, | ||
1204 | {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4900124c, 0x4900124c}, | ||
1205 | {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c00126c, 0x4c00126c}, | ||
1206 | {0x0000a55c, 0x7002708c, 0x7002708c, 0x4f00128c, 0x4f00128c}, | ||
1207 | {0x0000a560, 0x7302b08a, 0x7302b08a, 0x52001290, 0x52001290}, | ||
1208 | {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292}, | ||
1209 | {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292}, | ||
1210 | {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292}, | ||
1211 | {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292}, | ||
1212 | {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292}, | ||
1213 | {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292}, | ||
1214 | {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292}, | ||
1215 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
1216 | {0x0000a584, 0x06800003, 0x06800003, 0x02800001, 0x02800001}, | ||
1217 | {0x0000a588, 0x0a800020, 0x0a800020, 0x05800003, 0x05800003}, | ||
1218 | {0x0000a58c, 0x10800023, 0x10800023, 0x0a800005, 0x0a800005}, | ||
1219 | {0x0000a590, 0x16800220, 0x16800220, 0x0e800201, 0x0e800201}, | ||
1220 | {0x0000a594, 0x1c800223, 0x1c800223, 0x11800203, 0x11800203}, | ||
1221 | {0x0000a598, 0x21820220, 0x21820220, 0x14800401, 0x14800401}, | ||
1222 | {0x0000a59c, 0x27820223, 0x27820223, 0x18800403, 0x18800403}, | ||
1223 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800602, 0x1b800602}, | ||
1224 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800802, 0x1f800802}, | ||
1225 | {0x0000a5a8, 0x34822225, 0x34822225, 0x21800620, 0x21800620}, | ||
1226 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x25800820, 0x25800820}, | ||
1227 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x29800822, 0x29800822}, | ||
1228 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2d800824, 0x2d800824}, | ||
1229 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x30800828, 0x30800828}, | ||
1230 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x3480082a, 0x3480082a}, | ||
1231 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38800849, 0x38800849}, | ||
1232 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b800a2c, 0x3b800a2c}, | ||
1233 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e800e2b, 0x3e800e2b}, | ||
1234 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42800e2d, 0x42800e2d}, | ||
1235 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4580124a, 0x4580124a}, | ||
1236 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4980124c, 0x4980124c}, | ||
1237 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c80126c, 0x4c80126c}, | ||
1238 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x4f80128c, 0x4f80128c}, | ||
1239 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x52801290, 0x52801290}, | ||
1240 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292}, | ||
1241 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292}, | ||
1242 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292}, | ||
1243 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292}, | ||
1244 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292}, | ||
1245 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292}, | ||
1246 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292}, | ||
1247 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1248 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1249 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1250 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1251 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1252 | {0x0000a614, 0x01404000, 0x01404000, 0x01404501, 0x01404501}, | ||
1253 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | ||
1254 | {0x0000a61c, 0x02008802, 0x02008802, 0x01404501, 0x01404501}, | ||
1255 | {0x0000a620, 0x0300cc03, 0x0300cc03, 0x03c0cf02, 0x03c0cf02}, | ||
1256 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03c0cf03, 0x03c0cf03}, | ||
1257 | {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04011004, 0x04011004}, | ||
1258 | {0x0000a62c, 0x03810c03, 0x03810c03, 0x05419405, 0x05419405}, | ||
1259 | {0x0000a630, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506}, | ||
1260 | {0x0000a634, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506}, | ||
1261 | {0x0000a638, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506}, | ||
1262 | {0x0000a63c, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506}, | ||
1263 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a}, | ||
1264 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac}, | ||
1265 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00}, | ||
1266 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000}, | ||
1267 | {0x00016044, 0x022492db, 0x022492db, 0x022492db, 0x022492db}, | ||
1268 | {0x00016048, 0x24925666, 0x24925666, 0x24925266, 0x24925266}, | ||
1269 | {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, | ||
1270 | {0x00016288, 0xf0318000, 0xf0318000, 0xf0318000, 0xf0318000}, | ||
1271 | {0x00016444, 0x022492db, 0x022492db, 0x022492db, 0x022492db}, | ||
1272 | {0x00016448, 0x24925666, 0x24925666, 0x24925266, 0x24925266}, | ||
1273 | }; | ||
1274 | |||
1175 | static const u32 ar9340_1p0_mac_core[][2] = { | 1275 | static const u32 ar9340_1p0_mac_core[][2] = { |
1176 | /* Addr allmodes */ | 1276 | /* Addr allmodes */ |
1177 | {0x00000008, 0x00000000}, | 1277 | {0x00000008, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index a3710f3bb90c..712f415b8c08 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -260,6 +260,79 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | |||
260 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | 260 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, |
261 | }; | 261 | }; |
262 | 262 | ||
263 | static const u32 ar9485Modes_green_ob_db_tx_gain_1_1[][5] = { | ||
264 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
265 | {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, | ||
266 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
267 | {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, | ||
268 | {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, | ||
269 | {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201}, | ||
270 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203}, | ||
271 | {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401}, | ||
272 | {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403}, | ||
273 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405}, | ||
274 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604}, | ||
275 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605}, | ||
276 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04}, | ||
277 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06}, | ||
278 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24}, | ||
279 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21}, | ||
280 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20}, | ||
281 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20}, | ||
282 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
283 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
284 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
285 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
286 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
287 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
288 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
289 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
290 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, | ||
291 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
292 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
293 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
294 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
295 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
296 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
297 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
298 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
299 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
300 | {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
301 | {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
302 | {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
303 | {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
304 | {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
305 | {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
306 | {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
307 | {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
308 | {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
309 | {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
310 | {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
311 | {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a}, | ||
312 | {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a}, | ||
313 | {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a}, | ||
314 | {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
315 | {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
316 | {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
317 | {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
318 | {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
319 | {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
320 | {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
321 | {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
322 | {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
323 | {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
324 | {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
325 | {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
326 | {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
327 | {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
328 | {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
329 | {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
330 | {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
331 | {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
332 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
333 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
334 | }; | ||
335 | |||
263 | static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { | 336 | static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { |
264 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 337 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
265 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | 338 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, |
@@ -450,6 +523,79 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { | |||
450 | 523 | ||
451 | #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 | 524 | #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 |
452 | 525 | ||
526 | static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = { | ||
527 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
528 | {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, | ||
529 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
530 | {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, | ||
531 | {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, | ||
532 | {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201}, | ||
533 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x07000203, 0x07000203}, | ||
534 | {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401}, | ||
535 | {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403}, | ||
536 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405}, | ||
537 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x14000406, 0x14000406}, | ||
538 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1800040a, 0x1800040a}, | ||
539 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000460, 0x1c000460}, | ||
540 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x22000463, 0x22000463}, | ||
541 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x26000465, 0x26000465}, | ||
542 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2e0006e0, 0x2e0006e0}, | ||
543 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x310006e0, 0x310006e0}, | ||
544 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x330006e0, 0x330006e0}, | ||
545 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x3e0008e3, 0x3e0008e3}, | ||
546 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x410008e5, 0x410008e5}, | ||
547 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x430008e6, 0x430008e6}, | ||
548 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4a0008ec, 0x4a0008ec}, | ||
549 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4e0008f1, 0x4e0008f1}, | ||
550 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x520008f3, 0x520008f3}, | ||
551 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x54000eed, 0x54000eed}, | ||
552 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x58000ef1, 0x58000ef1}, | ||
553 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5c000ef3, 0x5c000ef3}, | ||
554 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x60000ef5, 0x60000ef5}, | ||
555 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x62000ef6, 0x62000ef6}, | ||
556 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x62000ef6, 0x62000ef6}, | ||
557 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, | ||
558 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, | ||
559 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, | ||
560 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, | ||
561 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, | ||
562 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, | ||
563 | {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
564 | {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
565 | {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
566 | {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
567 | {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
568 | {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
569 | {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
570 | {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
571 | {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
572 | {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
573 | {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
574 | {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a}, | ||
575 | {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a}, | ||
576 | {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a}, | ||
577 | {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
578 | {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
579 | {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
580 | {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
581 | {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
582 | {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
583 | {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
584 | {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
585 | {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
586 | {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
587 | {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
588 | {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
589 | {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
590 | {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
591 | {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
592 | {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
593 | {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
594 | {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
595 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
596 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
597 | }; | ||
598 | |||
453 | static const u32 ar9485_1_1[][2] = { | 599 | static const u32 ar9485_1_1[][2] = { |
454 | /* Addr allmodes */ | 600 | /* Addr allmodes */ |
455 | {0x0000a580, 0x00000000}, | 601 | {0x0000a580, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h index df97f21c52dc..ccc5b6c99add 100644 --- a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h | |||
@@ -23,16 +23,16 @@ | |||
23 | static const u32 ar955x_1p0_radio_postamble[][5] = { | 23 | static const u32 ar955x_1p0_radio_postamble[][5] = { |
24 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 24 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
25 | {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xd28b3330, 0xd28b3330}, | 25 | {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xd28b3330, 0xd28b3330}, |
26 | {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x06345f2a, 0x06345f2a}, | 26 | {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x0a566f3a, 0x0a566f3a}, |
27 | {0x000160ac, 0xa4647c00, 0xa4647c00, 0xa4646800, 0xa4646800}, | 27 | {0x000160ac, 0xa4647c00, 0xa4647c00, 0x24647c00, 0x24647c00}, |
28 | {0x000160b0, 0x01885f52, 0x01885f52, 0x04accf3a, 0x04accf3a}, | 28 | {0x000160b0, 0x01885f52, 0x01885f52, 0x01885f52, 0x01885f52}, |
29 | {0x00016104, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001}, | 29 | {0x00016104, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001}, |
30 | {0x0001610c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000}, | 30 | {0x0001610c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000}, |
31 | {0x00016140, 0x10804008, 0x10804008, 0x10804008, 0x10804008}, | 31 | {0x00016140, 0x10804008, 0x10804008, 0x10804008, 0x10804008}, |
32 | {0x00016504, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001}, | 32 | {0x00016504, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001}, |
33 | {0x0001650c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000}, | 33 | {0x0001650c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000}, |
34 | {0x00016540, 0x10804008, 0x10804008, 0x10804008, 0x10804008}, | 34 | {0x00016540, 0x10804008, 0x10804008, 0x10804008, 0x10804008}, |
35 | {0x00016904, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001}, | 35 | {0x00016904, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001}, |
36 | {0x0001690c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000}, | 36 | {0x0001690c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000}, |
37 | {0x00016940, 0x10804008, 0x10804008, 0x10804008, 0x10804008}, | 37 | {0x00016940, 0x10804008, 0x10804008, 0x10804008, 0x10804008}, |
38 | }; | 38 | }; |
@@ -69,15 +69,15 @@ static const u32 ar955x_1p0_baseband_postamble[][5] = { | |||
69 | {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0}, | 69 | {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0}, |
70 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | 70 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, |
71 | {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f}, | 71 | {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f}, |
72 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, | 72 | {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, |
73 | {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, | 73 | {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, |
74 | {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018}, | 74 | {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018}, |
75 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | 75 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, |
76 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | 76 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, |
77 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | 77 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, |
78 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | 78 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e}, |
79 | {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, | 79 | {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, |
80 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | 80 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e}, |
81 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | 81 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, |
82 | {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, | 82 | {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, |
83 | {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, | 83 | {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, |
@@ -125,7 +125,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { | |||
125 | {0x00016094, 0x00000000}, | 125 | {0x00016094, 0x00000000}, |
126 | {0x000160a0, 0x0a108ffe}, | 126 | {0x000160a0, 0x0a108ffe}, |
127 | {0x000160a4, 0x812fc370}, | 127 | {0x000160a4, 0x812fc370}, |
128 | {0x000160a8, 0x423c8000}, | 128 | {0x000160a8, 0x423c8100}, |
129 | {0x000160b4, 0x92480080}, | 129 | {0x000160b4, 0x92480080}, |
130 | {0x000160c0, 0x006db6d0}, | 130 | {0x000160c0, 0x006db6d0}, |
131 | {0x000160c4, 0x6db6db60}, | 131 | {0x000160c4, 0x6db6db60}, |
@@ -134,7 +134,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { | |||
134 | {0x00016100, 0x11999601}, | 134 | {0x00016100, 0x11999601}, |
135 | {0x00016108, 0x00080010}, | 135 | {0x00016108, 0x00080010}, |
136 | {0x00016144, 0x02084080}, | 136 | {0x00016144, 0x02084080}, |
137 | {0x00016148, 0x000080c0}, | 137 | {0x00016148, 0x00008040}, |
138 | {0x00016280, 0x01800804}, | 138 | {0x00016280, 0x01800804}, |
139 | {0x00016284, 0x00038dc5}, | 139 | {0x00016284, 0x00038dc5}, |
140 | {0x00016288, 0x00000000}, | 140 | {0x00016288, 0x00000000}, |
@@ -178,7 +178,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { | |||
178 | {0x00016500, 0x11999601}, | 178 | {0x00016500, 0x11999601}, |
179 | {0x00016508, 0x00080010}, | 179 | {0x00016508, 0x00080010}, |
180 | {0x00016544, 0x02084080}, | 180 | {0x00016544, 0x02084080}, |
181 | {0x00016548, 0x000080c0}, | 181 | {0x00016548, 0x00008040}, |
182 | {0x00016780, 0x00000000}, | 182 | {0x00016780, 0x00000000}, |
183 | {0x00016784, 0x00000000}, | 183 | {0x00016784, 0x00000000}, |
184 | {0x00016788, 0x00400705}, | 184 | {0x00016788, 0x00400705}, |
@@ -218,7 +218,7 @@ static const u32 ar955x_1p0_radio_core[][2] = { | |||
218 | {0x00016900, 0x11999601}, | 218 | {0x00016900, 0x11999601}, |
219 | {0x00016908, 0x00080010}, | 219 | {0x00016908, 0x00080010}, |
220 | {0x00016944, 0x02084080}, | 220 | {0x00016944, 0x02084080}, |
221 | {0x00016948, 0x000080c0}, | 221 | {0x00016948, 0x00008040}, |
222 | {0x00016b80, 0x00000000}, | 222 | {0x00016b80, 0x00000000}, |
223 | {0x00016b84, 0x00000000}, | 223 | {0x00016b84, 0x00000000}, |
224 | {0x00016b88, 0x00400705}, | 224 | {0x00016b88, 0x00400705}, |
@@ -245,9 +245,9 @@ static const u32 ar955x_1p0_radio_core[][2] = { | |||
245 | 245 | ||
246 | static const u32 ar955x_1p0_modes_xpa_tx_gain_table[][9] = { | 246 | static const u32 ar955x_1p0_modes_xpa_tx_gain_table[][9] = { |
247 | /* Addr 5G_HT20_L 5G_HT40_L 5G_HT20_M 5G_HT40_M 5G_HT20_H 5G_HT40_H 2G_HT40 2G_HT20 */ | 247 | /* Addr 5G_HT20_L 5G_HT40_L 5G_HT20_M 5G_HT40_M 5G_HT20_H 5G_HT40_H 2G_HT40 2G_HT20 */ |
248 | {0x0000a2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa}, | 248 | {0x0000a2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa}, |
249 | {0x0000a2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc}, | 249 | {0x0000a2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc}, |
250 | {0x0000a2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0}, | 250 | {0x0000a2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0}, |
251 | {0x0000a2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00}, | 251 | {0x0000a2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00}, |
252 | {0x0000a410, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050da, 0x000050da}, | 252 | {0x0000a410, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050da, 0x000050da}, |
253 | {0x0000a500, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000000, 0x00000000}, | 253 | {0x0000a500, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000000, 0x00000000}, |
@@ -256,63 +256,63 @@ static const u32 ar955x_1p0_modes_xpa_tx_gain_table[][9] = { | |||
256 | {0x0000a50c, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c000006, 0x0c000006}, | 256 | {0x0000a50c, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c000006, 0x0c000006}, |
257 | {0x0000a510, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x0f00000a, 0x0f00000a}, | 257 | {0x0000a510, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x0f00000a, 0x0f00000a}, |
258 | {0x0000a514, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x1300000c, 0x1300000c}, | 258 | {0x0000a514, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x1300000c, 0x1300000c}, |
259 | {0x0000a518, 0x19004008, 0x19004008, 0x19004008, 0x19004008, 0x18004008, 0x18004008, 0x1700000e, 0x1700000e}, | 259 | {0x0000a518, 0x1700002b, 0x1700002b, 0x1700002b, 0x1700002b, 0x1600002b, 0x1600002b, 0x1700000e, 0x1700000e}, |
260 | {0x0000a51c, 0x1d00400a, 0x1d00400a, 0x1d00400a, 0x1d00400a, 0x1c00400a, 0x1c00400a, 0x1b000064, 0x1b000064}, | 260 | {0x0000a51c, 0x1b00002d, 0x1b00002d, 0x1b00002d, 0x1b00002d, 0x1a00002d, 0x1a00002d, 0x1b000064, 0x1b000064}, |
261 | {0x0000a520, 0x230020a2, 0x230020a2, 0x210020a2, 0x210020a2, 0x200020a2, 0x200020a2, 0x1f000242, 0x1f000242}, | 261 | {0x0000a520, 0x20000031, 0x20000031, 0x1f000031, 0x1f000031, 0x1e000031, 0x1e000031, 0x1f000242, 0x1f000242}, |
262 | {0x0000a524, 0x2500006e, 0x2500006e, 0x2500006e, 0x2500006e, 0x2400006e, 0x2400006e, 0x23000229, 0x23000229}, | 262 | {0x0000a524, 0x24000051, 0x24000051, 0x23000051, 0x23000051, 0x23000051, 0x23000051, 0x23000229, 0x23000229}, |
263 | {0x0000a528, 0x29022221, 0x29022221, 0x28022221, 0x28022221, 0x27022221, 0x27022221, 0x270002a2, 0x270002a2}, | 263 | {0x0000a528, 0x27000071, 0x27000071, 0x27000071, 0x27000071, 0x26000071, 0x26000071, 0x270002a2, 0x270002a2}, |
264 | {0x0000a52c, 0x2d00062a, 0x2d00062a, 0x2c00062a, 0x2c00062a, 0x2a00062a, 0x2a00062a, 0x2c001203, 0x2c001203}, | 264 | {0x0000a52c, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2c001203, 0x2c001203}, |
265 | {0x0000a530, 0x340220a5, 0x340220a5, 0x320220a5, 0x320220a5, 0x2f0220a5, 0x2f0220a5, 0x30001803, 0x30001803}, | 265 | {0x0000a530, 0x3000028c, 0x3000028c, 0x2f00028c, 0x2f00028c, 0x2e00028c, 0x2e00028c, 0x30001803, 0x30001803}, |
266 | {0x0000a534, 0x380022c5, 0x380022c5, 0x350022c5, 0x350022c5, 0x320022c5, 0x320022c5, 0x33000881, 0x33000881}, | 266 | {0x0000a534, 0x34000290, 0x34000290, 0x33000290, 0x33000290, 0x32000290, 0x32000290, 0x33000881, 0x33000881}, |
267 | {0x0000a538, 0x3b002486, 0x3b002486, 0x39002486, 0x39002486, 0x36002486, 0x36002486, 0x38001809, 0x38001809}, | 267 | {0x0000a538, 0x37000292, 0x37000292, 0x36000292, 0x36000292, 0x35000292, 0x35000292, 0x38001809, 0x38001809}, |
268 | {0x0000a53c, 0x3f00248a, 0x3f00248a, 0x3d00248a, 0x3d00248a, 0x3a00248a, 0x3a00248a, 0x3a000814, 0x3a000814}, | 268 | {0x0000a53c, 0x3b02028d, 0x3b02028d, 0x3a02028d, 0x3a02028d, 0x3902028d, 0x3902028d, 0x3a000814, 0x3a000814}, |
269 | {0x0000a540, 0x4202242c, 0x4202242c, 0x4102242c, 0x4102242c, 0x3f02242c, 0x3f02242c, 0x3f001a0c, 0x3f001a0c}, | 269 | {0x0000a540, 0x3f020291, 0x3f020291, 0x3e020291, 0x3e020291, 0x3d020291, 0x3d020291, 0x3f001a0c, 0x3f001a0c}, |
270 | {0x0000a544, 0x490044c6, 0x490044c6, 0x460044c6, 0x460044c6, 0x420044c6, 0x420044c6, 0x43001a0e, 0x43001a0e}, | 270 | {0x0000a544, 0x44020490, 0x44020490, 0x43020490, 0x43020490, 0x42020490, 0x42020490, 0x43001a0e, 0x43001a0e}, |
271 | {0x0000a548, 0x4d024485, 0x4d024485, 0x4a024485, 0x4a024485, 0x46024485, 0x46024485, 0x46001812, 0x46001812}, | 271 | {0x0000a548, 0x48020492, 0x48020492, 0x47020492, 0x47020492, 0x46020492, 0x46020492, 0x46001812, 0x46001812}, |
272 | {0x0000a54c, 0x51044483, 0x51044483, 0x4e044483, 0x4e044483, 0x4a044483, 0x4a044483, 0x49001884, 0x49001884}, | 272 | {0x0000a54c, 0x4c020692, 0x4c020692, 0x4b020692, 0x4b020692, 0x4a020692, 0x4a020692, 0x49001884, 0x49001884}, |
273 | {0x0000a550, 0x5404a40c, 0x5404a40c, 0x5204a40c, 0x5204a40c, 0x4d04a40c, 0x4d04a40c, 0x4d001e84, 0x4d001e84}, | 273 | {0x0000a550, 0x50020892, 0x50020892, 0x4f020892, 0x4f020892, 0x4e020892, 0x4e020892, 0x4d001e84, 0x4d001e84}, |
274 | {0x0000a554, 0x57024632, 0x57024632, 0x55024632, 0x55024632, 0x52024632, 0x52024632, 0x50001e69, 0x50001e69}, | 274 | {0x0000a554, 0x53040891, 0x53040891, 0x53040891, 0x53040891, 0x52040891, 0x52040891, 0x50001e69, 0x50001e69}, |
275 | {0x0000a558, 0x5c00a634, 0x5c00a634, 0x5900a634, 0x5900a634, 0x5600a634, 0x5600a634, 0x550006f4, 0x550006f4}, | 275 | {0x0000a558, 0x58040893, 0x58040893, 0x57040893, 0x57040893, 0x56040893, 0x56040893, 0x550006f4, 0x550006f4}, |
276 | {0x0000a55c, 0x5f026832, 0x5f026832, 0x5d026832, 0x5d026832, 0x5a026832, 0x5a026832, 0x59000ad3, 0x59000ad3}, | 276 | {0x0000a55c, 0x5c0408b4, 0x5c0408b4, 0x5a0408b4, 0x5a0408b4, 0x5a0408b4, 0x5a0408b4, 0x59000ad3, 0x59000ad3}, |
277 | {0x0000a560, 0x6602b012, 0x6602b012, 0x6202b012, 0x6202b012, 0x5d02b012, 0x5d02b012, 0x5e000ad5, 0x5e000ad5}, | 277 | {0x0000a560, 0x610408b6, 0x610408b6, 0x5e0408b6, 0x5e0408b6, 0x5e0408b6, 0x5e0408b6, 0x5e000ad5, 0x5e000ad5}, |
278 | {0x0000a564, 0x6e02d0e1, 0x6e02d0e1, 0x6802d0e1, 0x6802d0e1, 0x6002d0e1, 0x6002d0e1, 0x61001ced, 0x61001ced}, | 278 | {0x0000a564, 0x670408f6, 0x670408f6, 0x620408f6, 0x620408f6, 0x620408f6, 0x620408f6, 0x61001ced, 0x61001ced}, |
279 | {0x0000a568, 0x7202b4c4, 0x7202b4c4, 0x6c02b4c4, 0x6c02b4c4, 0x6502b4c4, 0x6502b4c4, 0x660018d4, 0x660018d4}, | 279 | {0x0000a568, 0x6a040cf6, 0x6a040cf6, 0x66040cf6, 0x66040cf6, 0x66040cf6, 0x66040cf6, 0x660018d4, 0x660018d4}, |
280 | {0x0000a56c, 0x75007894, 0x75007894, 0x70007894, 0x70007894, 0x6b007894, 0x6b007894, 0x660018d4, 0x660018d4}, | 280 | {0x0000a56c, 0x6d040d76, 0x6d040d76, 0x6a040d76, 0x6a040d76, 0x6a040d76, 0x6a040d76, 0x660018d4, 0x660018d4}, |
281 | {0x0000a570, 0x7b025c74, 0x7b025c74, 0x75025c74, 0x75025c74, 0x70025c74, 0x70025c74, 0x660018d4, 0x660018d4}, | 281 | {0x0000a570, 0x70060db6, 0x70060db6, 0x6e060db6, 0x6e060db6, 0x6e060db6, 0x6e060db6, 0x660018d4, 0x660018d4}, |
282 | {0x0000a574, 0x8300bcb5, 0x8300bcb5, 0x7a00bcb5, 0x7a00bcb5, 0x7600bcb5, 0x7600bcb5, 0x660018d4, 0x660018d4}, | 282 | {0x0000a574, 0x730a0df6, 0x730a0df6, 0x720a0df6, 0x720a0df6, 0x720a0df6, 0x720a0df6, 0x660018d4, 0x660018d4}, |
283 | {0x0000a578, 0x8a04dc74, 0x8a04dc74, 0x7f04dc74, 0x7f04dc74, 0x7c04dc74, 0x7c04dc74, 0x660018d4, 0x660018d4}, | 283 | {0x0000a578, 0x770a13f6, 0x770a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x660018d4, 0x660018d4}, |
284 | {0x0000a57c, 0x8a04dc74, 0x8a04dc74, 0x7f04dc74, 0x7f04dc74, 0x7c04dc74, 0x7c04dc74, 0x660018d4, 0x660018d4}, | 284 | {0x0000a57c, 0x770a13f6, 0x770a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x660018d4, 0x660018d4}, |
285 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 285 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
286 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 286 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
287 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 287 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
288 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x03804000, 0x03804000}, | 288 | {0x0000a60c, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x03804000, 0x03804000}, |
289 | {0x0000a610, 0x04c08c01, 0x04c08c01, 0x04808b01, 0x04808b01, 0x04808a01, 0x04808a01, 0x0300ca02, 0x0300ca02}, | 289 | {0x0000a610, 0x04008b01, 0x04008b01, 0x04008b01, 0x04008b01, 0x03c08b01, 0x03c08b01, 0x0300ca02, 0x0300ca02}, |
290 | {0x0000a614, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00000e04, 0x00000e04}, | 290 | {0x0000a614, 0x05811403, 0x05811403, 0x05411303, 0x05411303, 0x05411303, 0x05411303, 0x00000e04, 0x00000e04}, |
291 | {0x0000a618, 0x04010c01, 0x04010c01, 0x03c10b01, 0x03c10b01, 0x03810a01, 0x03810a01, 0x03014000, 0x03014000}, | 291 | {0x0000a618, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03014000, 0x03014000}, |
292 | {0x0000a61c, 0x03814e05, 0x03814e05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03414d05, 0x00000000, 0x00000000}, | 292 | {0x0000a61c, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x00000000, 0x00000000}, |
293 | {0x0000a620, 0x04010303, 0x04010303, 0x03c10303, 0x03c10303, 0x03810303, 0x03810303, 0x00000000, 0x00000000}, | 293 | {0x0000a620, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x00000000, 0x00000000}, |
294 | {0x0000a624, 0x03814e05, 0x03814e05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03014000, 0x03014000}, | 294 | {0x0000a624, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03014000, 0x03014000}, |
295 | {0x0000a628, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x03804c05, 0x03804c05}, | 295 | {0x0000a628, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03804c05, 0x03804c05}, |
296 | {0x0000a62c, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x0701de06, 0x0701de06}, | 296 | {0x0000a62c, 0x06815604, 0x06815604, 0x06415504, 0x06415504, 0x06015504, 0x06015504, 0x0701de06, 0x0701de06}, |
297 | {0x0000a630, 0x03418000, 0x03418000, 0x03018000, 0x03018000, 0x02c18000, 0x02c18000, 0x07819c07, 0x07819c07}, | 297 | {0x0000a630, 0x07819a05, 0x07819a05, 0x07419905, 0x07419905, 0x07019805, 0x07019805, 0x07819c07, 0x07819c07}, |
298 | {0x0000a634, 0x03815004, 0x03815004, 0x03414f04, 0x03414f04, 0x03414e04, 0x03414e04, 0x0701dc07, 0x0701dc07}, | 298 | {0x0000a634, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07}, |
299 | {0x0000a638, 0x03005302, 0x03005302, 0x02c05202, 0x02c05202, 0x02805202, 0x02805202, 0x0701dc07, 0x0701dc07}, | 299 | {0x0000a638, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07}, |
300 | {0x0000a63c, 0x04c09302, 0x04c09302, 0x04809202, 0x04809202, 0x04809202, 0x04809202, 0x0701dc07, 0x0701dc07}, | 300 | {0x0000a63c, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07}, |
301 | {0x0000b2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa}, | 301 | {0x0000b2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa}, |
302 | {0x0000b2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc}, | 302 | {0x0000b2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc}, |
303 | {0x0000b2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0}, | 303 | {0x0000b2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0}, |
304 | {0x0000b2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00}, | 304 | {0x0000b2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00}, |
305 | {0x0000c2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa}, | 305 | {0x0000c2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa}, |
306 | {0x0000c2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc}, | 306 | {0x0000c2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc}, |
307 | {0x0000c2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0}, | 307 | {0x0000c2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0}, |
308 | {0x0000c2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00}, | 308 | {0x0000c2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00}, |
309 | {0x00016044, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4}, | 309 | {0x00016044, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4}, |
310 | {0x00016048, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401}, | 310 | {0x00016048, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401}, |
311 | {0x00016280, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01808e84, 0x01808e84}, | 311 | {0x00016280, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01808e84, 0x01808e84}, |
312 | {0x00016444, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4}, | 312 | {0x00016444, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4}, |
313 | {0x00016448, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401}, | 313 | {0x00016448, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401}, |
314 | {0x00016844, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4}, | 314 | {0x00016844, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4}, |
315 | {0x00016848, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401}, | 315 | {0x00016848, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401}, |
316 | }; | 316 | }; |
317 | 317 | ||
318 | static const u32 ar955x_1p0_mac_core[][2] = { | 318 | static const u32 ar955x_1p0_mac_core[][2] = { |
@@ -846,7 +846,7 @@ static const u32 ar955x_1p0_baseband_core[][2] = { | |||
846 | {0x0000a44c, 0x00000001}, | 846 | {0x0000a44c, 0x00000001}, |
847 | {0x0000a450, 0x00010000}, | 847 | {0x0000a450, 0x00010000}, |
848 | {0x0000a458, 0x00000000}, | 848 | {0x0000a458, 0x00000000}, |
849 | {0x0000a644, 0x3fad9d74}, | 849 | {0x0000a644, 0xbfad9d74}, |
850 | {0x0000a648, 0x0048060a}, | 850 | {0x0000a648, 0x0048060a}, |
851 | {0x0000a64c, 0x00003c37}, | 851 | {0x0000a64c, 0x00003c37}, |
852 | {0x0000a670, 0x03020100}, | 852 | {0x0000a670, 0x03020100}, |
@@ -1277,7 +1277,7 @@ static const u32 ar955x_1p0_modes_fast_clock[][3] = { | |||
1277 | {0x0000801c, 0x148ec02b, 0x148ec057}, | 1277 | {0x0000801c, 0x148ec02b, 0x148ec057}, |
1278 | {0x00008318, 0x000044c0, 0x00008980}, | 1278 | {0x00008318, 0x000044c0, 0x00008980}, |
1279 | {0x00009e00, 0x0372131c, 0x0372131c}, | 1279 | {0x00009e00, 0x0372131c, 0x0372131c}, |
1280 | {0x0000a230, 0x0000000b, 0x00000016}, | 1280 | {0x0000a230, 0x0000400b, 0x00004016}, |
1281 | {0x0000a254, 0x00000898, 0x00001130}, | 1281 | {0x0000a254, 0x00000898, 0x00001130}, |
1282 | }; | 1282 | }; |
1283 | 1283 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index 6e1915aee712..28fd99203f64 100644 --- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h | |||
@@ -685,6 +685,82 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = { | |||
685 | 685 | ||
686 | #define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 | 686 | #define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 |
687 | 687 | ||
688 | #define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2 | ||
689 | |||
690 | static const u32 ar9580_1p0_type6_tx_gain_table[][5] = { | ||
691 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
692 | {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | ||
693 | {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | ||
694 | {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | ||
695 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
696 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
697 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
698 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
699 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
700 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
701 | {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, | ||
702 | {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, | ||
703 | {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, | ||
704 | {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, | ||
705 | {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, | ||
706 | {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, | ||
707 | {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, | ||
708 | {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, | ||
709 | {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, | ||
710 | {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, | ||
711 | {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, | ||
712 | {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, | ||
713 | {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, | ||
714 | {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, | ||
715 | {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, | ||
716 | {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83}, | ||
717 | {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84}, | ||
718 | {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, | ||
719 | {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, | ||
720 | {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, | ||
721 | {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, | ||
722 | {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
723 | {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
724 | {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
725 | {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
726 | {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
727 | {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
728 | {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, | ||
729 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
730 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
731 | {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | ||
732 | {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | ||
733 | {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, | ||
734 | {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, | ||
735 | {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, | ||
736 | {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, | ||
737 | {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, | ||
738 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, | ||
739 | {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, | ||
740 | {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
741 | {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
742 | {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
743 | {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
744 | {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, | ||
745 | {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | ||
746 | {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | ||
747 | {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | ||
748 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
749 | {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, | ||
750 | {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, | ||
751 | {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, | ||
752 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, | ||
753 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
754 | {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, | ||
755 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
756 | {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
757 | {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, | ||
758 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
759 | {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
760 | {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, | ||
761 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
762 | }; | ||
763 | |||
688 | static const u32 ar9580_1p0_soc_preamble[][2] = { | 764 | static const u32 ar9580_1p0_soc_preamble[][2] = { |
689 | /* Addr allmodes */ | 765 | /* Addr allmodes */ |
690 | {0x000040a4, 0x00a0c1c9}, | 766 | {0x000040a4, 0x00a0c1c9}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 86e26a19efda..b2d6c18d1678 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -109,14 +109,11 @@ struct ath_descdma { | |||
109 | void *dd_desc; | 109 | void *dd_desc; |
110 | dma_addr_t dd_desc_paddr; | 110 | dma_addr_t dd_desc_paddr; |
111 | u32 dd_desc_len; | 111 | u32 dd_desc_len; |
112 | struct ath_buf *dd_bufptr; | ||
113 | }; | 112 | }; |
114 | 113 | ||
115 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | 114 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, |
116 | struct list_head *head, const char *name, | 115 | struct list_head *head, const char *name, |
117 | int nbuf, int ndesc, bool is_tx); | 116 | int nbuf, int ndesc, bool is_tx); |
118 | void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | ||
119 | struct list_head *head); | ||
120 | 117 | ||
121 | /***********/ | 118 | /***********/ |
122 | /* RX / TX */ | 119 | /* RX / TX */ |
@@ -317,10 +314,8 @@ struct ath_rx { | |||
317 | u32 *rxlink; | 314 | u32 *rxlink; |
318 | u32 num_pkts; | 315 | u32 num_pkts; |
319 | unsigned int rxfilter; | 316 | unsigned int rxfilter; |
320 | spinlock_t rxbuflock; | ||
321 | struct list_head rxbuf; | 317 | struct list_head rxbuf; |
322 | struct ath_descdma rxdma; | 318 | struct ath_descdma rxdma; |
323 | struct ath_buf *rx_bufptr; | ||
324 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; | 319 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; |
325 | 320 | ||
326 | struct sk_buff *frag; | 321 | struct sk_buff *frag; |
@@ -328,7 +323,6 @@ struct ath_rx { | |||
328 | 323 | ||
329 | int ath_startrecv(struct ath_softc *sc); | 324 | int ath_startrecv(struct ath_softc *sc); |
330 | bool ath_stoprecv(struct ath_softc *sc); | 325 | bool ath_stoprecv(struct ath_softc *sc); |
331 | void ath_flushrecv(struct ath_softc *sc); | ||
332 | u32 ath_calcrxfilter(struct ath_softc *sc); | 326 | u32 ath_calcrxfilter(struct ath_softc *sc); |
333 | int ath_rx_init(struct ath_softc *sc, int nbufs); | 327 | int ath_rx_init(struct ath_softc *sc, int nbufs); |
334 | void ath_rx_cleanup(struct ath_softc *sc); | 328 | void ath_rx_cleanup(struct ath_softc *sc); |
@@ -338,14 +332,12 @@ void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq); | |||
338 | void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq); | 332 | void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq); |
339 | void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq); | 333 | void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq); |
340 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 334 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
341 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | 335 | bool ath_drain_all_txq(struct ath_softc *sc); |
342 | void ath_draintxq(struct ath_softc *sc, | 336 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq); |
343 | struct ath_txq *txq, bool retry_tx); | ||
344 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | 337 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); |
345 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); | 338 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); |
346 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); | 339 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); |
347 | int ath_tx_init(struct ath_softc *sc, int nbufs); | 340 | int ath_tx_init(struct ath_softc *sc, int nbufs); |
348 | void ath_tx_cleanup(struct ath_softc *sc); | ||
349 | int ath_txq_update(struct ath_softc *sc, int qnum, | 341 | int ath_txq_update(struct ath_softc *sc, int qnum, |
350 | struct ath9k_tx_queue_info *q); | 342 | struct ath9k_tx_queue_info *q); |
351 | void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop); | 343 | void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop); |
@@ -646,7 +638,6 @@ void ath_ant_comb_update(struct ath_softc *sc); | |||
646 | enum sc_op_flags { | 638 | enum sc_op_flags { |
647 | SC_OP_INVALID, | 639 | SC_OP_INVALID, |
648 | SC_OP_BEACONS, | 640 | SC_OP_BEACONS, |
649 | SC_OP_RXFLUSH, | ||
650 | SC_OP_ANI_RUN, | 641 | SC_OP_ANI_RUN, |
651 | SC_OP_PRIM_STA_VIF, | 642 | SC_OP_PRIM_STA_VIF, |
652 | SC_OP_HW_RESET, | 643 | SC_OP_HW_RESET, |
@@ -675,6 +666,23 @@ struct ath9k_vif_iter_data { | |||
675 | int nadhocs; /* number of adhoc vifs */ | 666 | int nadhocs; /* number of adhoc vifs */ |
676 | }; | 667 | }; |
677 | 668 | ||
669 | /* enum spectral_mode: | ||
670 | * | ||
671 | * @SPECTRAL_DISABLED: spectral mode is disabled | ||
672 | * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with | ||
673 | * something else. | ||
674 | * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples | ||
675 | * is performed manually. | ||
676 | * @SPECTRAL_CHANSCAN: Like manual, but also triggered when changing channels | ||
677 | * during a channel scan. | ||
678 | */ | ||
679 | enum spectral_mode { | ||
680 | SPECTRAL_DISABLED = 0, | ||
681 | SPECTRAL_BACKGROUND, | ||
682 | SPECTRAL_MANUAL, | ||
683 | SPECTRAL_CHANSCAN, | ||
684 | }; | ||
685 | |||
678 | struct ath_softc { | 686 | struct ath_softc { |
679 | struct ieee80211_hw *hw; | 687 | struct ieee80211_hw *hw; |
680 | struct device *dev; | 688 | struct device *dev; |
@@ -743,6 +751,10 @@ struct ath_softc { | |||
743 | u8 ant_tx, ant_rx; | 751 | u8 ant_tx, ant_rx; |
744 | struct dfs_pattern_detector *dfs_detector; | 752 | struct dfs_pattern_detector *dfs_detector; |
745 | u32 wow_enabled; | 753 | u32 wow_enabled; |
754 | /* relay(fs) channel for spectral scan */ | ||
755 | struct rchan *rfs_chan_spec_scan; | ||
756 | enum spectral_mode spectral_mode; | ||
757 | int scanning; | ||
746 | 758 | ||
747 | #ifdef CONFIG_PM_SLEEP | 759 | #ifdef CONFIG_PM_SLEEP |
748 | atomic_t wow_got_bmiss_intr; | 760 | atomic_t wow_got_bmiss_intr; |
@@ -751,6 +763,133 @@ struct ath_softc { | |||
751 | #endif | 763 | #endif |
752 | }; | 764 | }; |
753 | 765 | ||
766 | #define SPECTRAL_SCAN_BITMASK 0x10 | ||
767 | /* Radar info packet format, used for DFS and spectral formats. */ | ||
768 | struct ath_radar_info { | ||
769 | u8 pulse_length_pri; | ||
770 | u8 pulse_length_ext; | ||
771 | u8 pulse_bw_info; | ||
772 | } __packed; | ||
773 | |||
774 | /* The HT20 spectral data has 4 bytes of additional information at it's end. | ||
775 | * | ||
776 | * [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]} | ||
777 | * [7:0]: all bins max_magnitude[9:2] | ||
778 | * [7:0]: all bins {max_index[5:0], max_magnitude[11:10]} | ||
779 | * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned) | ||
780 | */ | ||
781 | struct ath_ht20_mag_info { | ||
782 | u8 all_bins[3]; | ||
783 | u8 max_exp; | ||
784 | } __packed; | ||
785 | |||
786 | #define SPECTRAL_HT20_NUM_BINS 56 | ||
787 | |||
788 | /* WARNING: don't actually use this struct! MAC may vary the amount of | ||
789 | * data by -1/+2. This struct is for reference only. | ||
790 | */ | ||
791 | struct ath_ht20_fft_packet { | ||
792 | u8 data[SPECTRAL_HT20_NUM_BINS]; | ||
793 | struct ath_ht20_mag_info mag_info; | ||
794 | struct ath_radar_info radar_info; | ||
795 | } __packed; | ||
796 | |||
797 | #define SPECTRAL_HT20_TOTAL_DATA_LEN (sizeof(struct ath_ht20_fft_packet)) | ||
798 | |||
799 | /* Dynamic 20/40 mode: | ||
800 | * | ||
801 | * [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]} | ||
802 | * [7:0]: lower bins max_magnitude[9:2] | ||
803 | * [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]} | ||
804 | * [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]} | ||
805 | * [7:0]: upper bins max_magnitude[9:2] | ||
806 | * [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]} | ||
807 | * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned) | ||
808 | */ | ||
809 | struct ath_ht20_40_mag_info { | ||
810 | u8 lower_bins[3]; | ||
811 | u8 upper_bins[3]; | ||
812 | u8 max_exp; | ||
813 | } __packed; | ||
814 | |||
815 | #define SPECTRAL_HT20_40_NUM_BINS 128 | ||
816 | |||
817 | /* WARNING: don't actually use this struct! MAC may vary the amount of | ||
818 | * data. This struct is for reference only. | ||
819 | */ | ||
820 | struct ath_ht20_40_fft_packet { | ||
821 | u8 data[SPECTRAL_HT20_40_NUM_BINS]; | ||
822 | struct ath_ht20_40_mag_info mag_info; | ||
823 | struct ath_radar_info radar_info; | ||
824 | } __packed; | ||
825 | |||
826 | |||
827 | #define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet)) | ||
828 | |||
829 | /* grabs the max magnitude from the all/upper/lower bins */ | ||
830 | static inline u16 spectral_max_magnitude(u8 *bins) | ||
831 | { | ||
832 | return (bins[0] & 0xc0) >> 6 | | ||
833 | (bins[1] & 0xff) << 2 | | ||
834 | (bins[2] & 0x03) << 10; | ||
835 | } | ||
836 | |||
837 | /* return the max magnitude from the all/upper/lower bins */ | ||
838 | static inline u8 spectral_max_index(u8 *bins) | ||
839 | { | ||
840 | s8 m = (bins[2] & 0xfc) >> 2; | ||
841 | |||
842 | /* TODO: this still doesn't always report the right values ... */ | ||
843 | if (m > 32) | ||
844 | m |= 0xe0; | ||
845 | else | ||
846 | m &= ~0xe0; | ||
847 | |||
848 | return m + 29; | ||
849 | } | ||
850 | |||
851 | /* return the bitmap weight from the all/upper/lower bins */ | ||
852 | static inline u8 spectral_bitmap_weight(u8 *bins) | ||
853 | { | ||
854 | return bins[0] & 0x3f; | ||
855 | } | ||
856 | |||
857 | /* FFT sample format given to userspace via debugfs. | ||
858 | * | ||
859 | * Please keep the type/length at the front position and change | ||
860 | * other fields after adding another sample type | ||
861 | * | ||
862 | * TODO: this might need rework when switching to nl80211-based | ||
863 | * interface. | ||
864 | */ | ||
865 | enum ath_fft_sample_type { | ||
866 | ATH_FFT_SAMPLE_HT20 = 0, | ||
867 | }; | ||
868 | |||
869 | struct fft_sample_tlv { | ||
870 | u8 type; /* see ath_fft_sample */ | ||
871 | u16 length; | ||
872 | /* type dependent data follows */ | ||
873 | } __packed; | ||
874 | |||
875 | struct fft_sample_ht20 { | ||
876 | struct fft_sample_tlv tlv; | ||
877 | |||
878 | u8 __alignment; | ||
879 | |||
880 | u16 freq; | ||
881 | s8 rssi; | ||
882 | s8 noise; | ||
883 | |||
884 | u16 max_magnitude; | ||
885 | u8 max_index; | ||
886 | u8 bitmap_weight; | ||
887 | |||
888 | u64 tsf; | ||
889 | |||
890 | u16 data[SPECTRAL_HT20_NUM_BINS]; | ||
891 | } __packed; | ||
892 | |||
754 | void ath9k_tasklet(unsigned long data); | 893 | void ath9k_tasklet(unsigned long data); |
755 | int ath_cabq_update(struct ath_softc *); | 894 | int ath_cabq_update(struct ath_softc *); |
756 | 895 | ||
@@ -773,6 +912,10 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | |||
773 | void ath9k_reload_chainmask_settings(struct ath_softc *sc); | 912 | void ath9k_reload_chainmask_settings(struct ath_softc *sc); |
774 | 913 | ||
775 | bool ath9k_uses_beacons(int type); | 914 | bool ath9k_uses_beacons(int type); |
915 | void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw); | ||
916 | int ath9k_spectral_scan_config(struct ieee80211_hw *hw, | ||
917 | enum spectral_mode spectral_mode); | ||
918 | |||
776 | 919 | ||
777 | #ifdef CONFIG_ATH9K_PCI | 920 | #ifdef CONFIG_ATH9K_PCI |
778 | int ath_pci_init(void); | 921 | int ath_pci_init(void); |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 531fffd801a3..dd3771954bd7 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, | |||
147 | skb->len, DMA_TO_DEVICE); | 147 | skb->len, DMA_TO_DEVICE); |
148 | dev_kfree_skb_any(skb); | 148 | dev_kfree_skb_any(skb); |
149 | bf->bf_buf_addr = 0; | 149 | bf->bf_buf_addr = 0; |
150 | bf->bf_mpdu = NULL; | ||
150 | } | 151 | } |
151 | 152 | ||
152 | skb = ieee80211_beacon_get(hw, vif); | 153 | skb = ieee80211_beacon_get(hw, vif); |
@@ -198,7 +199,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, | |||
198 | if (sc->nvifs > 1) { | 199 | if (sc->nvifs > 1) { |
199 | ath_dbg(common, BEACON, | 200 | ath_dbg(common, BEACON, |
200 | "Flushing previous cabq traffic\n"); | 201 | "Flushing previous cabq traffic\n"); |
201 | ath_draintxq(sc, cabq, false); | 202 | ath_draintxq(sc, cabq); |
202 | } | 203 | } |
203 | } | 204 | } |
204 | 205 | ||
@@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
359 | return; | 360 | return; |
360 | 361 | ||
361 | bf = ath9k_beacon_generate(sc->hw, vif); | 362 | bf = ath9k_beacon_generate(sc->hw, vif); |
362 | WARN_ON(!bf); | ||
363 | 363 | ||
364 | if (sc->beacon.bmisscnt != 0) { | 364 | if (sc->beacon.bmisscnt != 0) { |
365 | ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", | 365 | ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 13ff9edc2401..6c5d313ebcb7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/export.h> | 19 | #include <linux/export.h> |
20 | #include <linux/relay.h> | ||
20 | #include <asm/unaligned.h> | 21 | #include <asm/unaligned.h> |
21 | 22 | ||
22 | #include "ath9k.h" | 23 | #include "ath9k.h" |
@@ -861,7 +862,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
861 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); | 862 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); |
862 | RXS_ERR("RX-OOM-ERR", rx_oom_err); | 863 | RXS_ERR("RX-OOM-ERR", rx_oom_err); |
863 | RXS_ERR("RX-RATE-ERR", rx_rate_err); | 864 | RXS_ERR("RX-RATE-ERR", rx_rate_err); |
864 | RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush); | ||
865 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); | 865 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); |
866 | 866 | ||
867 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); | 867 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); |
@@ -966,6 +966,112 @@ static const struct file_operations fops_recv = { | |||
966 | .llseek = default_llseek, | 966 | .llseek = default_llseek, |
967 | }; | 967 | }; |
968 | 968 | ||
969 | static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, | ||
970 | size_t count, loff_t *ppos) | ||
971 | { | ||
972 | struct ath_softc *sc = file->private_data; | ||
973 | char *mode = ""; | ||
974 | unsigned int len; | ||
975 | |||
976 | switch (sc->spectral_mode) { | ||
977 | case SPECTRAL_DISABLED: | ||
978 | mode = "disable"; | ||
979 | break; | ||
980 | case SPECTRAL_BACKGROUND: | ||
981 | mode = "background"; | ||
982 | break; | ||
983 | case SPECTRAL_CHANSCAN: | ||
984 | mode = "chanscan"; | ||
985 | break; | ||
986 | case SPECTRAL_MANUAL: | ||
987 | mode = "manual"; | ||
988 | break; | ||
989 | } | ||
990 | len = strlen(mode); | ||
991 | return simple_read_from_buffer(user_buf, count, ppos, mode, len); | ||
992 | } | ||
993 | |||
994 | static ssize_t write_file_spec_scan_ctl(struct file *file, | ||
995 | const char __user *user_buf, | ||
996 | size_t count, loff_t *ppos) | ||
997 | { | ||
998 | struct ath_softc *sc = file->private_data; | ||
999 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1000 | char buf[32]; | ||
1001 | ssize_t len; | ||
1002 | |||
1003 | len = min(count, sizeof(buf) - 1); | ||
1004 | if (copy_from_user(buf, user_buf, len)) | ||
1005 | return -EFAULT; | ||
1006 | |||
1007 | buf[len] = '\0'; | ||
1008 | |||
1009 | if (strncmp("trigger", buf, 7) == 0) { | ||
1010 | ath9k_spectral_scan_trigger(sc->hw); | ||
1011 | } else if (strncmp("background", buf, 9) == 0) { | ||
1012 | ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND); | ||
1013 | ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n"); | ||
1014 | } else if (strncmp("chanscan", buf, 8) == 0) { | ||
1015 | ath9k_spectral_scan_config(sc->hw, SPECTRAL_CHANSCAN); | ||
1016 | ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n"); | ||
1017 | } else if (strncmp("manual", buf, 6) == 0) { | ||
1018 | ath9k_spectral_scan_config(sc->hw, SPECTRAL_MANUAL); | ||
1019 | ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n"); | ||
1020 | } else if (strncmp("disable", buf, 7) == 0) { | ||
1021 | ath9k_spectral_scan_config(sc->hw, SPECTRAL_DISABLED); | ||
1022 | ath_dbg(common, CONFIG, "spectral scan: disabled\n"); | ||
1023 | } else { | ||
1024 | return -EINVAL; | ||
1025 | } | ||
1026 | |||
1027 | return count; | ||
1028 | } | ||
1029 | |||
1030 | static const struct file_operations fops_spec_scan_ctl = { | ||
1031 | .read = read_file_spec_scan_ctl, | ||
1032 | .write = write_file_spec_scan_ctl, | ||
1033 | .open = simple_open, | ||
1034 | .owner = THIS_MODULE, | ||
1035 | .llseek = default_llseek, | ||
1036 | }; | ||
1037 | |||
1038 | static struct dentry *create_buf_file_handler(const char *filename, | ||
1039 | struct dentry *parent, | ||
1040 | umode_t mode, | ||
1041 | struct rchan_buf *buf, | ||
1042 | int *is_global) | ||
1043 | { | ||
1044 | struct dentry *buf_file; | ||
1045 | |||
1046 | buf_file = debugfs_create_file(filename, mode, parent, buf, | ||
1047 | &relay_file_operations); | ||
1048 | *is_global = 1; | ||
1049 | return buf_file; | ||
1050 | } | ||
1051 | |||
1052 | static int remove_buf_file_handler(struct dentry *dentry) | ||
1053 | { | ||
1054 | debugfs_remove(dentry); | ||
1055 | |||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | void ath_debug_send_fft_sample(struct ath_softc *sc, | ||
1060 | struct fft_sample_tlv *fft_sample_tlv) | ||
1061 | { | ||
1062 | if (!sc->rfs_chan_spec_scan) | ||
1063 | return; | ||
1064 | |||
1065 | relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv, | ||
1066 | fft_sample_tlv->length + sizeof(*fft_sample_tlv)); | ||
1067 | } | ||
1068 | |||
1069 | static struct rchan_callbacks rfs_spec_scan_cb = { | ||
1070 | .create_buf_file = create_buf_file_handler, | ||
1071 | .remove_buf_file = remove_buf_file_handler, | ||
1072 | }; | ||
1073 | |||
1074 | |||
969 | static ssize_t read_file_regidx(struct file *file, char __user *user_buf, | 1075 | static ssize_t read_file_regidx(struct file *file, char __user *user_buf, |
970 | size_t count, loff_t *ppos) | 1076 | size_t count, loff_t *ppos) |
971 | { | 1077 | { |
@@ -1780,6 +1886,14 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1780 | &fops_base_eeprom); | 1886 | &fops_base_eeprom); |
1781 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, | 1887 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, |
1782 | &fops_modal_eeprom); | 1888 | &fops_modal_eeprom); |
1889 | sc->rfs_chan_spec_scan = relay_open("spectral_scan", | ||
1890 | sc->debug.debugfs_phy, | ||
1891 | 262144, 4, &rfs_spec_scan_cb, | ||
1892 | NULL); | ||
1893 | debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR, | ||
1894 | sc->debug.debugfs_phy, sc, | ||
1895 | &fops_spec_scan_ctl); | ||
1896 | |||
1783 | #ifdef CONFIG_ATH9K_MAC_DEBUG | 1897 | #ifdef CONFIG_ATH9K_MAC_DEBUG |
1784 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, | 1898 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, |
1785 | &fops_samps); | 1899 | &fops_samps); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 375c3b46411e..a22c0d780700 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | struct ath_txq; | 24 | struct ath_txq; |
25 | struct ath_buf; | 25 | struct ath_buf; |
26 | struct fft_sample_tlv; | ||
26 | 27 | ||
27 | #ifdef CONFIG_ATH9K_DEBUGFS | 28 | #ifdef CONFIG_ATH9K_DEBUGFS |
28 | #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ | 29 | #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ |
@@ -216,7 +217,6 @@ struct ath_tx_stats { | |||
216 | * @rx_oom_err: No. of frames dropped due to OOM issues. | 217 | * @rx_oom_err: No. of frames dropped due to OOM issues. |
217 | * @rx_rate_err: No. of frames dropped due to rate errors. | 218 | * @rx_rate_err: No. of frames dropped due to rate errors. |
218 | * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. | 219 | * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. |
219 | * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH. | ||
220 | * @rx_beacons: No. of beacons received. | 220 | * @rx_beacons: No. of beacons received. |
221 | * @rx_frags: No. of rx-fragements received. | 221 | * @rx_frags: No. of rx-fragements received. |
222 | */ | 222 | */ |
@@ -235,7 +235,6 @@ struct ath_rx_stats { | |||
235 | u32 rx_oom_err; | 235 | u32 rx_oom_err; |
236 | u32 rx_rate_err; | 236 | u32 rx_rate_err; |
237 | u32 rx_too_many_frags_err; | 237 | u32 rx_too_many_frags_err; |
238 | u32 rx_drop_rxflush; | ||
239 | u32 rx_beacons; | 238 | u32 rx_beacons; |
240 | u32 rx_frags; | 239 | u32 rx_frags; |
241 | }; | 240 | }; |
@@ -323,6 +322,10 @@ void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw, | |||
323 | struct ieee80211_vif *vif, | 322 | struct ieee80211_vif *vif, |
324 | struct ieee80211_sta *sta, | 323 | struct ieee80211_sta *sta, |
325 | struct dentry *dir); | 324 | struct dentry *dir); |
325 | |||
326 | void ath_debug_send_fft_sample(struct ath_softc *sc, | ||
327 | struct fft_sample_tlv *fft_sample); | ||
328 | |||
326 | #else | 329 | #else |
327 | 330 | ||
328 | #define RX_STAT_INC(c) /* NOP */ | 331 | #define RX_STAT_INC(c) /* NOP */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index b2f85cb5ed30..716058b67557 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -280,14 +280,14 @@ err: | |||
280 | return ret; | 280 | return ret; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int ath9k_reg_notifier(struct wiphy *wiphy, | 283 | static void ath9k_reg_notifier(struct wiphy *wiphy, |
284 | struct regulatory_request *request) | 284 | struct regulatory_request *request) |
285 | { | 285 | { |
286 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 286 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
287 | struct ath9k_htc_priv *priv = hw->priv; | 287 | struct ath9k_htc_priv *priv = hw->priv; |
288 | 288 | ||
289 | return ath_reg_notifier_apply(wiphy, request, | 289 | ath_reg_notifier_apply(wiphy, request, |
290 | ath9k_hw_regulatory(priv->ah)); | 290 | ath9k_hw_regulatory(priv->ah)); |
291 | } | 291 | } |
292 | 292 | ||
293 | static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset) | 293 | static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9c07a8fa5134..a8016d70088a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1628,7 +1628,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1628 | if (!ret) | 1628 | if (!ret) |
1629 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1629 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1630 | break; | 1630 | break; |
1631 | case IEEE80211_AMPDU_TX_STOP: | 1631 | case IEEE80211_AMPDU_TX_STOP_CONT: |
1632 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
1633 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
1632 | ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid); | 1634 | ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid); |
1633 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1635 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1634 | break; | 1636 | break; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 4a9570dfba72..aac4a406a513 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | |||
344 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, | 344 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, |
345 | skb, htc_hdr->endpoint_id, | 345 | skb, htc_hdr->endpoint_id, |
346 | txok); | 346 | txok); |
347 | } else { | ||
348 | kfree_skb(skb); | ||
347 | } | 349 | } |
348 | } | 350 | } |
349 | 351 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 0f2b97f6b739..14b701140b49 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
@@ -101,22 +101,6 @@ static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah, | |||
101 | ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan); | 101 | ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan); |
102 | } | 102 | } |
103 | 103 | ||
104 | static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah) | ||
105 | { | ||
106 | if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks) | ||
107 | return 0; | ||
108 | |||
109 | return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah); | ||
110 | } | ||
111 | |||
112 | static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah) | ||
113 | { | ||
114 | if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks) | ||
115 | return; | ||
116 | |||
117 | ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah); | ||
118 | } | ||
119 | |||
120 | static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | 104 | static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah, |
121 | struct ath9k_channel *chan, | 105 | struct ath9k_channel *chan, |
122 | u16 modesIndex) | 106 | u16 modesIndex) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7cb787065913..42cf3c7f1e25 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -54,11 +54,6 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah) | |||
54 | ath9k_hw_private_ops(ah)->init_cal_settings(ah); | 54 | ath9k_hw_private_ops(ah)->init_cal_settings(ah); |
55 | } | 55 | } |
56 | 56 | ||
57 | static void ath9k_hw_init_mode_regs(struct ath_hw *ah) | ||
58 | { | ||
59 | ath9k_hw_private_ops(ah)->init_mode_regs(ah); | ||
60 | } | ||
61 | |||
62 | static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, | 57 | static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, |
63 | struct ath9k_channel *chan) | 58 | struct ath9k_channel *chan) |
64 | { | 59 | { |
@@ -208,7 +203,7 @@ void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, | |||
208 | udelay(hw_delay + BASE_ACTIVATE_DELAY); | 203 | udelay(hw_delay + BASE_ACTIVATE_DELAY); |
209 | } | 204 | } |
210 | 205 | ||
211 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, | 206 | void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array, |
212 | int column, unsigned int *writecnt) | 207 | int column, unsigned int *writecnt) |
213 | { | 208 | { |
214 | int r; | 209 | int r; |
@@ -554,28 +549,19 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
554 | ah->eep_ops->get_eeprom_ver(ah), | 549 | ah->eep_ops->get_eeprom_ver(ah), |
555 | ah->eep_ops->get_eeprom_rev(ah)); | 550 | ah->eep_ops->get_eeprom_rev(ah)); |
556 | 551 | ||
557 | ecode = ath9k_hw_rf_alloc_ext_banks(ah); | 552 | if (ah->config.enable_ani) |
558 | if (ecode) { | ||
559 | ath_err(ath9k_hw_common(ah), | ||
560 | "Failed allocating banks for external radio\n"); | ||
561 | ath9k_hw_rf_free_ext_banks(ah); | ||
562 | return ecode; | ||
563 | } | ||
564 | |||
565 | if (ah->config.enable_ani) { | ||
566 | ath9k_hw_ani_setup(ah); | ||
567 | ath9k_hw_ani_init(ah); | 553 | ath9k_hw_ani_init(ah); |
568 | } | ||
569 | 554 | ||
570 | return 0; | 555 | return 0; |
571 | } | 556 | } |
572 | 557 | ||
573 | static void ath9k_hw_attach_ops(struct ath_hw *ah) | 558 | static int ath9k_hw_attach_ops(struct ath_hw *ah) |
574 | { | 559 | { |
575 | if (AR_SREV_9300_20_OR_LATER(ah)) | 560 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
576 | ar9003_hw_attach_ops(ah); | 561 | return ar9002_hw_attach_ops(ah); |
577 | else | 562 | |
578 | ar9002_hw_attach_ops(ah); | 563 | ar9003_hw_attach_ops(ah); |
564 | return 0; | ||
579 | } | 565 | } |
580 | 566 | ||
581 | /* Called for all hardware families */ | 567 | /* Called for all hardware families */ |
@@ -611,7 +597,9 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
611 | ath9k_hw_init_defaults(ah); | 597 | ath9k_hw_init_defaults(ah); |
612 | ath9k_hw_init_config(ah); | 598 | ath9k_hw_init_config(ah); |
613 | 599 | ||
614 | ath9k_hw_attach_ops(ah); | 600 | r = ath9k_hw_attach_ops(ah); |
601 | if (r) | ||
602 | return r; | ||
615 | 603 | ||
616 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { | 604 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { |
617 | ath_err(common, "Couldn't wakeup chip\n"); | 605 | ath_err(common, "Couldn't wakeup chip\n"); |
@@ -675,8 +663,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
675 | if (!AR_SREV_9300_20_OR_LATER(ah)) | 663 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
676 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; | 664 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; |
677 | 665 | ||
678 | ath9k_hw_init_mode_regs(ah); | ||
679 | |||
680 | if (!ah->is_pciexpress) | 666 | if (!ah->is_pciexpress) |
681 | ath9k_hw_disablepcie(ah); | 667 | ath9k_hw_disablepcie(ah); |
682 | 668 | ||
@@ -1153,12 +1139,9 @@ void ath9k_hw_deinit(struct ath_hw *ah) | |||
1153 | struct ath_common *common = ath9k_hw_common(ah); | 1139 | struct ath_common *common = ath9k_hw_common(ah); |
1154 | 1140 | ||
1155 | if (common->state < ATH_HW_INITIALIZED) | 1141 | if (common->state < ATH_HW_INITIALIZED) |
1156 | goto free_hw; | 1142 | return; |
1157 | 1143 | ||
1158 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 1144 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); |
1159 | |||
1160 | free_hw: | ||
1161 | ath9k_hw_rf_free_ext_banks(ah); | ||
1162 | } | 1145 | } |
1163 | EXPORT_SYMBOL(ath9k_hw_deinit); | 1146 | EXPORT_SYMBOL(ath9k_hw_deinit); |
1164 | 1147 | ||
@@ -2576,12 +2559,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2576 | rx_chainmask >>= 1; | 2559 | rx_chainmask >>= 1; |
2577 | } | 2560 | } |
2578 | 2561 | ||
2579 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
2580 | ah->enabled_cals |= TX_IQ_CAL; | ||
2581 | if (AR_SREV_9485_OR_LATER(ah)) | ||
2582 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; | ||
2583 | } | ||
2584 | |||
2585 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { | 2562 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { |
2586 | if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) | 2563 | if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) |
2587 | pCap->hw_caps |= ATH9K_HW_CAP_MCI; | 2564 | pCap->hw_caps |= ATH9K_HW_CAP_MCI; |
@@ -2590,7 +2567,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2590 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; | 2567 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; |
2591 | } | 2568 | } |
2592 | 2569 | ||
2593 | |||
2594 | if (AR_SREV_9280_20_OR_LATER(ah)) { | 2570 | if (AR_SREV_9280_20_OR_LATER(ah)) { |
2595 | pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE | | 2571 | pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE | |
2596 | ATH9K_HW_WOW_PATTERN_MATCH_EXACT; | 2572 | ATH9K_HW_WOW_PATTERN_MATCH_EXACT; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7f1a8e91c908..784e81ccb903 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -397,6 +397,7 @@ enum ath9k_int { | |||
397 | #define MAX_RTT_TABLE_ENTRY 6 | 397 | #define MAX_RTT_TABLE_ENTRY 6 |
398 | #define MAX_IQCAL_MEASUREMENT 8 | 398 | #define MAX_IQCAL_MEASUREMENT 8 |
399 | #define MAX_CL_TAB_ENTRY 16 | 399 | #define MAX_CL_TAB_ENTRY 16 |
400 | #define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j)) | ||
400 | 401 | ||
401 | struct ath9k_hw_cal_data { | 402 | struct ath9k_hw_cal_data { |
402 | u16 channel; | 403 | u16 channel; |
@@ -599,13 +600,10 @@ struct ath_hw_radar_conf { | |||
599 | * @init_cal_settings: setup types of calibrations supported | 600 | * @init_cal_settings: setup types of calibrations supported |
600 | * @init_cal: starts actual calibration | 601 | * @init_cal: starts actual calibration |
601 | * | 602 | * |
602 | * @init_mode_regs: Initializes mode registers | ||
603 | * @init_mode_gain_regs: Initialize TX/RX gain registers | 603 | * @init_mode_gain_regs: Initialize TX/RX gain registers |
604 | * | 604 | * |
605 | * @rf_set_freq: change frequency | 605 | * @rf_set_freq: change frequency |
606 | * @spur_mitigate_freq: spur mitigation | 606 | * @spur_mitigate_freq: spur mitigation |
607 | * @rf_alloc_ext_banks: | ||
608 | * @rf_free_ext_banks: | ||
609 | * @set_rf_regs: | 607 | * @set_rf_regs: |
610 | * @compute_pll_control: compute the PLL control value to use for | 608 | * @compute_pll_control: compute the PLL control value to use for |
611 | * AR_RTC_PLL_CONTROL for a given channel | 609 | * AR_RTC_PLL_CONTROL for a given channel |
@@ -620,7 +618,6 @@ struct ath_hw_private_ops { | |||
620 | void (*init_cal_settings)(struct ath_hw *ah); | 618 | void (*init_cal_settings)(struct ath_hw *ah); |
621 | bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan); | 619 | bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan); |
622 | 620 | ||
623 | void (*init_mode_regs)(struct ath_hw *ah); | ||
624 | void (*init_mode_gain_regs)(struct ath_hw *ah); | 621 | void (*init_mode_gain_regs)(struct ath_hw *ah); |
625 | void (*setup_calibration)(struct ath_hw *ah, | 622 | void (*setup_calibration)(struct ath_hw *ah, |
626 | struct ath9k_cal_list *currCal); | 623 | struct ath9k_cal_list *currCal); |
@@ -630,8 +627,6 @@ struct ath_hw_private_ops { | |||
630 | struct ath9k_channel *chan); | 627 | struct ath9k_channel *chan); |
631 | void (*spur_mitigate_freq)(struct ath_hw *ah, | 628 | void (*spur_mitigate_freq)(struct ath_hw *ah, |
632 | struct ath9k_channel *chan); | 629 | struct ath9k_channel *chan); |
633 | int (*rf_alloc_ext_banks)(struct ath_hw *ah); | ||
634 | void (*rf_free_ext_banks)(struct ath_hw *ah); | ||
635 | bool (*set_rf_regs)(struct ath_hw *ah, | 630 | bool (*set_rf_regs)(struct ath_hw *ah, |
636 | struct ath9k_channel *chan, | 631 | struct ath9k_channel *chan, |
637 | u16 modesIndex); | 632 | u16 modesIndex); |
@@ -661,6 +656,37 @@ struct ath_hw_private_ops { | |||
661 | }; | 656 | }; |
662 | 657 | ||
663 | /** | 658 | /** |
659 | * struct ath_spec_scan - parameters for Atheros spectral scan | ||
660 | * | ||
661 | * @enabled: enable/disable spectral scan | ||
662 | * @short_repeat: controls whether the chip is in spectral scan mode | ||
663 | * for 4 usec (enabled) or 204 usec (disabled) | ||
664 | * @count: number of scan results requested. There are special meanings | ||
665 | * in some chip revisions: | ||
666 | * AR92xx: highest bit set (>=128) for endless mode | ||
667 | * (spectral scan won't stopped until explicitly disabled) | ||
668 | * AR9300 and newer: 0 for endless mode | ||
669 | * @endless: true if endless mode is intended. Otherwise, count value is | ||
670 | * corrected to the next possible value. | ||
671 | * @period: time duration between successive spectral scan entry points | ||
672 | * (period*256*Tclk). Tclk = ath_common->clockrate | ||
673 | * @fft_period: PHY passes FFT frames to MAC every (fft_period+1)*4uS | ||
674 | * | ||
675 | * Note: Tclk = 40MHz or 44MHz depending upon operating mode. | ||
676 | * Typically it's 44MHz in 2/5GHz on later chips, but there's | ||
677 | * a "fast clock" check for this in 5GHz. | ||
678 | * | ||
679 | */ | ||
680 | struct ath_spec_scan { | ||
681 | bool enabled; | ||
682 | bool short_repeat; | ||
683 | bool endless; | ||
684 | u8 count; | ||
685 | u8 period; | ||
686 | u8 fft_period; | ||
687 | }; | ||
688 | |||
689 | /** | ||
664 | * struct ath_hw_ops - callbacks used by hardware code and driver code | 690 | * struct ath_hw_ops - callbacks used by hardware code and driver code |
665 | * | 691 | * |
666 | * This structure contains callbacks designed to to be used internally by | 692 | * This structure contains callbacks designed to to be used internally by |
@@ -668,6 +694,10 @@ struct ath_hw_private_ops { | |||
668 | * | 694 | * |
669 | * @config_pci_powersave: | 695 | * @config_pci_powersave: |
670 | * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC | 696 | * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC |
697 | * | ||
698 | * @spectral_scan_config: set parameters for spectral scan and enable/disable it | ||
699 | * @spectral_scan_trigger: trigger a spectral scan run | ||
700 | * @spectral_scan_wait: wait for a spectral scan run to finish | ||
671 | */ | 701 | */ |
672 | struct ath_hw_ops { | 702 | struct ath_hw_ops { |
673 | void (*config_pci_powersave)(struct ath_hw *ah, | 703 | void (*config_pci_powersave)(struct ath_hw *ah, |
@@ -688,6 +718,10 @@ struct ath_hw_ops { | |||
688 | void (*antdiv_comb_conf_set)(struct ath_hw *ah, | 718 | void (*antdiv_comb_conf_set)(struct ath_hw *ah, |
689 | struct ath_hw_antcomb_conf *antconf); | 719 | struct ath_hw_antcomb_conf *antconf); |
690 | void (*antctrl_shared_chain_lnadiv)(struct ath_hw *hw, bool enable); | 720 | void (*antctrl_shared_chain_lnadiv)(struct ath_hw *hw, bool enable); |
721 | void (*spectral_scan_config)(struct ath_hw *ah, | ||
722 | struct ath_spec_scan *param); | ||
723 | void (*spectral_scan_trigger)(struct ath_hw *ah); | ||
724 | void (*spectral_scan_wait)(struct ath_hw *ah); | ||
691 | }; | 725 | }; |
692 | 726 | ||
693 | struct ath_nf_limits { | 727 | struct ath_nf_limits { |
@@ -710,6 +744,7 @@ enum ath_cal_list { | |||
710 | struct ath_hw { | 744 | struct ath_hw { |
711 | struct ath_ops reg_ops; | 745 | struct ath_ops reg_ops; |
712 | 746 | ||
747 | struct device *dev; | ||
713 | struct ieee80211_hw *hw; | 748 | struct ieee80211_hw *hw; |
714 | struct ath_common common; | 749 | struct ath_common common; |
715 | struct ath9k_hw_version hw_version; | 750 | struct ath9k_hw_version hw_version; |
@@ -771,7 +806,6 @@ struct ath_hw { | |||
771 | struct ath9k_cal_list iq_caldata; | 806 | struct ath9k_cal_list iq_caldata; |
772 | struct ath9k_cal_list adcgain_caldata; | 807 | struct ath9k_cal_list adcgain_caldata; |
773 | struct ath9k_cal_list adcdc_caldata; | 808 | struct ath9k_cal_list adcdc_caldata; |
774 | struct ath9k_cal_list tempCompCalData; | ||
775 | struct ath9k_cal_list *cal_list; | 809 | struct ath9k_cal_list *cal_list; |
776 | struct ath9k_cal_list *cal_list_last; | 810 | struct ath9k_cal_list *cal_list_last; |
777 | struct ath9k_cal_list *cal_list_curr; | 811 | struct ath9k_cal_list *cal_list_curr; |
@@ -830,10 +864,6 @@ struct ath_hw { | |||
830 | /* ANI */ | 864 | /* ANI */ |
831 | u32 proc_phyerr; | 865 | u32 proc_phyerr; |
832 | u32 aniperiod; | 866 | u32 aniperiod; |
833 | int totalSizeDesired[5]; | ||
834 | int coarse_high[5]; | ||
835 | int coarse_low[5]; | ||
836 | int firpwr[5]; | ||
837 | enum ath9k_ani_cmd ani_function; | 867 | enum ath9k_ani_cmd ani_function; |
838 | u32 ani_skip_count; | 868 | u32 ani_skip_count; |
839 | 869 | ||
@@ -979,7 +1009,7 @@ void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | |||
979 | void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, | 1009 | void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, |
980 | int hw_delay); | 1010 | int hw_delay); |
981 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); | 1011 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); |
982 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, | 1012 | void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array, |
983 | int column, unsigned int *writecnt); | 1013 | int column, unsigned int *writecnt); |
984 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); | 1014 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); |
985 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, | 1015 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, |
@@ -1066,16 +1096,17 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); | |||
1066 | int ar9003_paprd_init_table(struct ath_hw *ah); | 1096 | int ar9003_paprd_init_table(struct ath_hw *ah); |
1067 | bool ar9003_paprd_is_done(struct ath_hw *ah); | 1097 | bool ar9003_paprd_is_done(struct ath_hw *ah); |
1068 | bool ar9003_is_paprd_enabled(struct ath_hw *ah); | 1098 | bool ar9003_is_paprd_enabled(struct ath_hw *ah); |
1099 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); | ||
1069 | 1100 | ||
1070 | /* Hardware family op attach helpers */ | 1101 | /* Hardware family op attach helpers */ |
1071 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); | 1102 | int ar5008_hw_attach_phy_ops(struct ath_hw *ah); |
1072 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah); | 1103 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah); |
1073 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah); | 1104 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah); |
1074 | 1105 | ||
1075 | void ar9002_hw_attach_calib_ops(struct ath_hw *ah); | 1106 | void ar9002_hw_attach_calib_ops(struct ath_hw *ah); |
1076 | void ar9003_hw_attach_calib_ops(struct ath_hw *ah); | 1107 | void ar9003_hw_attach_calib_ops(struct ath_hw *ah); |
1077 | 1108 | ||
1078 | void ar9002_hw_attach_ops(struct ath_hw *ah); | 1109 | int ar9002_hw_attach_ops(struct ath_hw *ah); |
1079 | void ar9003_hw_attach_ops(struct ath_hw *ah); | 1110 | void ar9003_hw_attach_ops(struct ath_hw *ah); |
1080 | 1111 | ||
1081 | void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); | 1112 | void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index f69ef5d48c7b..4b1abc7da98c 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/ath9k_platform.h> | 21 | #include <linux/ath9k_platform.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/relay.h> | ||
23 | 24 | ||
24 | #include "ath9k.h" | 25 | #include "ath9k.h" |
25 | 26 | ||
@@ -302,16 +303,15 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
302 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | 303 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; |
303 | } | 304 | } |
304 | 305 | ||
305 | static int ath9k_reg_notifier(struct wiphy *wiphy, | 306 | static void ath9k_reg_notifier(struct wiphy *wiphy, |
306 | struct regulatory_request *request) | 307 | struct regulatory_request *request) |
307 | { | 308 | { |
308 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 309 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
309 | struct ath_softc *sc = hw->priv; | 310 | struct ath_softc *sc = hw->priv; |
310 | struct ath_hw *ah = sc->sc_ah; | 311 | struct ath_hw *ah = sc->sc_ah; |
311 | struct ath_regulatory *reg = ath9k_hw_regulatory(ah); | 312 | struct ath_regulatory *reg = ath9k_hw_regulatory(ah); |
312 | int ret; | ||
313 | 313 | ||
314 | ret = ath_reg_notifier_apply(wiphy, request, reg); | 314 | ath_reg_notifier_apply(wiphy, request, reg); |
315 | 315 | ||
316 | /* Set tx power */ | 316 | /* Set tx power */ |
317 | if (ah->curchan) { | 317 | if (ah->curchan) { |
@@ -321,8 +321,6 @@ static int ath9k_reg_notifier(struct wiphy *wiphy, | |||
321 | sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; | 321 | sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; |
322 | ath9k_ps_restore(sc); | 322 | ath9k_ps_restore(sc); |
323 | } | 323 | } |
324 | |||
325 | return ret; | ||
326 | } | 324 | } |
327 | 325 | ||
328 | /* | 326 | /* |
@@ -337,7 +335,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
337 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 335 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
338 | u8 *ds; | 336 | u8 *ds; |
339 | struct ath_buf *bf; | 337 | struct ath_buf *bf; |
340 | int i, bsize, error, desc_len; | 338 | int i, bsize, desc_len; |
341 | 339 | ||
342 | ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n", | 340 | ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n", |
343 | name, nbuf, ndesc); | 341 | name, nbuf, ndesc); |
@@ -353,8 +351,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
353 | if ((desc_len % 4) != 0) { | 351 | if ((desc_len % 4) != 0) { |
354 | ath_err(common, "ath_desc not DWORD aligned\n"); | 352 | ath_err(common, "ath_desc not DWORD aligned\n"); |
355 | BUG_ON((desc_len % 4) != 0); | 353 | BUG_ON((desc_len % 4) != 0); |
356 | error = -ENOMEM; | 354 | return -ENOMEM; |
357 | goto fail; | ||
358 | } | 355 | } |
359 | 356 | ||
360 | dd->dd_desc_len = desc_len * nbuf * ndesc; | 357 | dd->dd_desc_len = desc_len * nbuf * ndesc; |
@@ -378,12 +375,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
378 | } | 375 | } |
379 | 376 | ||
380 | /* allocate descriptors */ | 377 | /* allocate descriptors */ |
381 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | 378 | dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len, |
382 | &dd->dd_desc_paddr, GFP_KERNEL); | 379 | &dd->dd_desc_paddr, GFP_KERNEL); |
383 | if (dd->dd_desc == NULL) { | 380 | if (!dd->dd_desc) |
384 | error = -ENOMEM; | 381 | return -ENOMEM; |
385 | goto fail; | 382 | |
386 | } | ||
387 | ds = (u8 *) dd->dd_desc; | 383 | ds = (u8 *) dd->dd_desc; |
388 | ath_dbg(common, CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | 384 | ath_dbg(common, CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", |
389 | name, ds, (u32) dd->dd_desc_len, | 385 | name, ds, (u32) dd->dd_desc_len, |
@@ -391,12 +387,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
391 | 387 | ||
392 | /* allocate buffers */ | 388 | /* allocate buffers */ |
393 | bsize = sizeof(struct ath_buf) * nbuf; | 389 | bsize = sizeof(struct ath_buf) * nbuf; |
394 | bf = kzalloc(bsize, GFP_KERNEL); | 390 | bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); |
395 | if (bf == NULL) { | 391 | if (!bf) |
396 | error = -ENOMEM; | 392 | return -ENOMEM; |
397 | goto fail2; | ||
398 | } | ||
399 | dd->dd_bufptr = bf; | ||
400 | 393 | ||
401 | for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { | 394 | for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { |
402 | bf->bf_desc = ds; | 395 | bf->bf_desc = ds; |
@@ -422,12 +415,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
422 | list_add_tail(&bf->list, head); | 415 | list_add_tail(&bf->list, head); |
423 | } | 416 | } |
424 | return 0; | 417 | return 0; |
425 | fail2: | ||
426 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
427 | dd->dd_desc_paddr); | ||
428 | fail: | ||
429 | memset(dd, 0, sizeof(*dd)); | ||
430 | return error; | ||
431 | } | 418 | } |
432 | 419 | ||
433 | static int ath9k_init_queues(struct ath_softc *sc) | 420 | static int ath9k_init_queues(struct ath_softc *sc) |
@@ -457,11 +444,13 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) | |||
457 | ATH9K_NUM_CHANNELS); | 444 | ATH9K_NUM_CHANNELS); |
458 | 445 | ||
459 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { | 446 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { |
460 | channels = kmemdup(ath9k_2ghz_chantable, | 447 | channels = devm_kzalloc(sc->dev, |
461 | sizeof(ath9k_2ghz_chantable), GFP_KERNEL); | 448 | sizeof(ath9k_2ghz_chantable), GFP_KERNEL); |
462 | if (!channels) | 449 | if (!channels) |
463 | return -ENOMEM; | 450 | return -ENOMEM; |
464 | 451 | ||
452 | memcpy(channels, ath9k_2ghz_chantable, | ||
453 | sizeof(ath9k_2ghz_chantable)); | ||
465 | sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; | 454 | sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; |
466 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | 455 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; |
467 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | 456 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = |
@@ -472,14 +461,13 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) | |||
472 | } | 461 | } |
473 | 462 | ||
474 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { | 463 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { |
475 | channels = kmemdup(ath9k_5ghz_chantable, | 464 | channels = devm_kzalloc(sc->dev, |
476 | sizeof(ath9k_5ghz_chantable), GFP_KERNEL); | 465 | sizeof(ath9k_5ghz_chantable), GFP_KERNEL); |
477 | if (!channels) { | 466 | if (!channels) |
478 | if (sc->sbands[IEEE80211_BAND_2GHZ].channels) | ||
479 | kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); | ||
480 | return -ENOMEM; | 467 | return -ENOMEM; |
481 | } | ||
482 | 468 | ||
469 | memcpy(channels, ath9k_5ghz_chantable, | ||
470 | sizeof(ath9k_5ghz_chantable)); | ||
483 | sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; | 471 | sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; |
484 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | 472 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; |
485 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | 473 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = |
@@ -565,10 +553,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
565 | int ret = 0, i; | 553 | int ret = 0, i; |
566 | int csz = 0; | 554 | int csz = 0; |
567 | 555 | ||
568 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | 556 | ah = devm_kzalloc(sc->dev, sizeof(struct ath_hw), GFP_KERNEL); |
569 | if (!ah) | 557 | if (!ah) |
570 | return -ENOMEM; | 558 | return -ENOMEM; |
571 | 559 | ||
560 | ah->dev = sc->dev; | ||
572 | ah->hw = sc->hw; | 561 | ah->hw = sc->hw; |
573 | ah->hw_version.devid = devid; | 562 | ah->hw_version.devid = devid; |
574 | ah->reg_ops.read = ath9k_ioread32; | 563 | ah->reg_ops.read = ath9k_ioread32; |
@@ -636,7 +625,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
636 | if (pdata && pdata->eeprom_name) { | 625 | if (pdata && pdata->eeprom_name) { |
637 | ret = ath9k_eeprom_request(sc, pdata->eeprom_name); | 626 | ret = ath9k_eeprom_request(sc, pdata->eeprom_name); |
638 | if (ret) | 627 | if (ret) |
639 | goto err_eeprom; | 628 | return ret; |
640 | } | 629 | } |
641 | 630 | ||
642 | /* Initializes the hardware for all supported chipsets */ | 631 | /* Initializes the hardware for all supported chipsets */ |
@@ -676,10 +665,6 @@ err_queues: | |||
676 | ath9k_hw_deinit(ah); | 665 | ath9k_hw_deinit(ah); |
677 | err_hw: | 666 | err_hw: |
678 | ath9k_eeprom_release(sc); | 667 | ath9k_eeprom_release(sc); |
679 | err_eeprom: | ||
680 | kfree(ah); | ||
681 | sc->sc_ah = NULL; | ||
682 | |||
683 | return ret; | 668 | return ret; |
684 | } | 669 | } |
685 | 670 | ||
@@ -844,8 +829,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
844 | 829 | ||
845 | /* Bring up device */ | 830 | /* Bring up device */ |
846 | error = ath9k_init_softc(devid, sc, bus_ops); | 831 | error = ath9k_init_softc(devid, sc, bus_ops); |
847 | if (error != 0) | 832 | if (error) |
848 | goto error_init; | 833 | return error; |
849 | 834 | ||
850 | ah = sc->sc_ah; | 835 | ah = sc->sc_ah; |
851 | common = ath9k_hw_common(ah); | 836 | common = ath9k_hw_common(ah); |
@@ -855,19 +840,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
855 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, | 840 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, |
856 | ath9k_reg_notifier); | 841 | ath9k_reg_notifier); |
857 | if (error) | 842 | if (error) |
858 | goto error_regd; | 843 | goto deinit; |
859 | 844 | ||
860 | reg = &common->regulatory; | 845 | reg = &common->regulatory; |
861 | 846 | ||
862 | /* Setup TX DMA */ | 847 | /* Setup TX DMA */ |
863 | error = ath_tx_init(sc, ATH_TXBUF); | 848 | error = ath_tx_init(sc, ATH_TXBUF); |
864 | if (error != 0) | 849 | if (error != 0) |
865 | goto error_tx; | 850 | goto deinit; |
866 | 851 | ||
867 | /* Setup RX DMA */ | 852 | /* Setup RX DMA */ |
868 | error = ath_rx_init(sc, ATH_RXBUF); | 853 | error = ath_rx_init(sc, ATH_RXBUF); |
869 | if (error != 0) | 854 | if (error != 0) |
870 | goto error_rx; | 855 | goto deinit; |
871 | 856 | ||
872 | ath9k_init_txpower_limits(sc); | 857 | ath9k_init_txpower_limits(sc); |
873 | 858 | ||
@@ -881,19 +866,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
881 | /* Register with mac80211 */ | 866 | /* Register with mac80211 */ |
882 | error = ieee80211_register_hw(hw); | 867 | error = ieee80211_register_hw(hw); |
883 | if (error) | 868 | if (error) |
884 | goto error_register; | 869 | goto rx_cleanup; |
885 | 870 | ||
886 | error = ath9k_init_debug(ah); | 871 | error = ath9k_init_debug(ah); |
887 | if (error) { | 872 | if (error) { |
888 | ath_err(common, "Unable to create debugfs files\n"); | 873 | ath_err(common, "Unable to create debugfs files\n"); |
889 | goto error_world; | 874 | goto unregister; |
890 | } | 875 | } |
891 | 876 | ||
892 | /* Handle world regulatory */ | 877 | /* Handle world regulatory */ |
893 | if (!ath_is_world_regd(reg)) { | 878 | if (!ath_is_world_regd(reg)) { |
894 | error = regulatory_hint(hw->wiphy, reg->alpha2); | 879 | error = regulatory_hint(hw->wiphy, reg->alpha2); |
895 | if (error) | 880 | if (error) |
896 | goto error_world; | 881 | goto unregister; |
897 | } | 882 | } |
898 | 883 | ||
899 | ath_init_leds(sc); | 884 | ath_init_leds(sc); |
@@ -901,17 +886,12 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
901 | 886 | ||
902 | return 0; | 887 | return 0; |
903 | 888 | ||
904 | error_world: | 889 | unregister: |
905 | ieee80211_unregister_hw(hw); | 890 | ieee80211_unregister_hw(hw); |
906 | error_register: | 891 | rx_cleanup: |
907 | ath_rx_cleanup(sc); | 892 | ath_rx_cleanup(sc); |
908 | error_rx: | 893 | deinit: |
909 | ath_tx_cleanup(sc); | ||
910 | error_tx: | ||
911 | /* Nothing */ | ||
912 | error_regd: | ||
913 | ath9k_deinit_softc(sc); | 894 | ath9k_deinit_softc(sc); |
914 | error_init: | ||
915 | return error; | 895 | return error; |
916 | } | 896 | } |
917 | 897 | ||
@@ -923,12 +903,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
923 | { | 903 | { |
924 | int i = 0; | 904 | int i = 0; |
925 | 905 | ||
926 | if (sc->sbands[IEEE80211_BAND_2GHZ].channels) | ||
927 | kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); | ||
928 | |||
929 | if (sc->sbands[IEEE80211_BAND_5GHZ].channels) | ||
930 | kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); | ||
931 | |||
932 | ath9k_deinit_btcoex(sc); | 906 | ath9k_deinit_btcoex(sc); |
933 | 907 | ||
934 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 908 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
@@ -940,8 +914,11 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
940 | sc->dfs_detector->exit(sc->dfs_detector); | 914 | sc->dfs_detector->exit(sc->dfs_detector); |
941 | 915 | ||
942 | ath9k_eeprom_release(sc); | 916 | ath9k_eeprom_release(sc); |
943 | kfree(sc->sc_ah); | 917 | |
944 | sc->sc_ah = NULL; | 918 | if (sc->rfs_chan_spec_scan) { |
919 | relay_close(sc->rfs_chan_spec_scan); | ||
920 | sc->rfs_chan_spec_scan = NULL; | ||
921 | } | ||
945 | } | 922 | } |
946 | 923 | ||
947 | void ath9k_deinit_device(struct ath_softc *sc) | 924 | void ath9k_deinit_device(struct ath_softc *sc) |
@@ -957,22 +934,9 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
957 | 934 | ||
958 | ieee80211_unregister_hw(hw); | 935 | ieee80211_unregister_hw(hw); |
959 | ath_rx_cleanup(sc); | 936 | ath_rx_cleanup(sc); |
960 | ath_tx_cleanup(sc); | ||
961 | ath9k_deinit_softc(sc); | 937 | ath9k_deinit_softc(sc); |
962 | } | 938 | } |
963 | 939 | ||
964 | void ath_descdma_cleanup(struct ath_softc *sc, | ||
965 | struct ath_descdma *dd, | ||
966 | struct list_head *head) | ||
967 | { | ||
968 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
969 | dd->dd_desc_paddr); | ||
970 | |||
971 | INIT_LIST_HEAD(head); | ||
972 | kfree(dd->dd_bufptr); | ||
973 | memset(dd, 0, sizeof(*dd)); | ||
974 | } | ||
975 | |||
976 | /************************/ | 940 | /************************/ |
977 | /* Module Hooks */ | 941 | /* Module Hooks */ |
978 | /************************/ | 942 | /************************/ |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 4a745e68dd94..1ff817061ebc 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -226,7 +226,8 @@ enum ath9k_phyerr { | |||
226 | ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35, | 226 | ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35, |
227 | ATH9K_PHYERR_HT_RATE_ILLEGAL = 36, | 227 | ATH9K_PHYERR_HT_RATE_ILLEGAL = 36, |
228 | 228 | ||
229 | ATH9K_PHYERR_MAX = 37, | 229 | ATH9K_PHYERR_SPECTRAL = 38, |
230 | ATH9K_PHYERR_MAX = 39, | ||
230 | }; | 231 | }; |
231 | 232 | ||
232 | struct ath_desc { | 233 | struct ath_desc { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index be30a9af1528..4b72b660f180 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc) | |||
182 | ath_start_ani(sc); | 182 | ath_start_ani(sc); |
183 | } | 183 | } |
184 | 184 | ||
185 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | 185 | static bool ath_prepare_reset(struct ath_softc *sc) |
186 | { | 186 | { |
187 | struct ath_hw *ah = sc->sc_ah; | 187 | struct ath_hw *ah = sc->sc_ah; |
188 | bool ret = true; | 188 | bool ret = true; |
@@ -196,20 +196,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | |||
196 | ath9k_debug_samp_bb_mac(sc); | 196 | ath9k_debug_samp_bb_mac(sc); |
197 | ath9k_hw_disable_interrupts(ah); | 197 | ath9k_hw_disable_interrupts(ah); |
198 | 198 | ||
199 | if (!ath_stoprecv(sc)) | 199 | if (!ath_drain_all_txq(sc)) |
200 | ret = false; | 200 | ret = false; |
201 | 201 | ||
202 | if (!ath_drain_all_txq(sc, retry_tx)) | 202 | if (!ath_stoprecv(sc)) |
203 | ret = false; | 203 | ret = false; |
204 | 204 | ||
205 | if (!flush) { | ||
206 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
207 | ath_rx_tasklet(sc, 1, true); | ||
208 | ath_rx_tasklet(sc, 1, false); | ||
209 | } else { | ||
210 | ath_flushrecv(sc); | ||
211 | } | ||
212 | |||
213 | return ret; | 205 | return ret; |
214 | } | 206 | } |
215 | 207 | ||
@@ -255,18 +247,17 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
255 | return true; | 247 | return true; |
256 | } | 248 | } |
257 | 249 | ||
258 | static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | 250 | static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) |
259 | bool retry_tx) | ||
260 | { | 251 | { |
261 | struct ath_hw *ah = sc->sc_ah; | 252 | struct ath_hw *ah = sc->sc_ah; |
262 | struct ath_common *common = ath9k_hw_common(ah); | 253 | struct ath_common *common = ath9k_hw_common(ah); |
263 | struct ath9k_hw_cal_data *caldata = NULL; | 254 | struct ath9k_hw_cal_data *caldata = NULL; |
264 | bool fastcc = true; | 255 | bool fastcc = true; |
265 | bool flush = false; | ||
266 | int r; | 256 | int r; |
267 | 257 | ||
268 | __ath_cancel_work(sc); | 258 | __ath_cancel_work(sc); |
269 | 259 | ||
260 | tasklet_disable(&sc->intr_tq); | ||
270 | spin_lock_bh(&sc->sc_pcu_lock); | 261 | spin_lock_bh(&sc->sc_pcu_lock); |
271 | 262 | ||
272 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { | 263 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { |
@@ -276,11 +267,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
276 | 267 | ||
277 | if (!hchan) { | 268 | if (!hchan) { |
278 | fastcc = false; | 269 | fastcc = false; |
279 | flush = true; | ||
280 | hchan = ah->curchan; | 270 | hchan = ah->curchan; |
281 | } | 271 | } |
282 | 272 | ||
283 | if (!ath_prepare_reset(sc, retry_tx, flush)) | 273 | if (!ath_prepare_reset(sc)) |
284 | fastcc = false; | 274 | fastcc = false; |
285 | 275 | ||
286 | ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", | 276 | ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", |
@@ -302,6 +292,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
302 | 292 | ||
303 | out: | 293 | out: |
304 | spin_unlock_bh(&sc->sc_pcu_lock); | 294 | spin_unlock_bh(&sc->sc_pcu_lock); |
295 | tasklet_enable(&sc->intr_tq); | ||
296 | |||
305 | return r; | 297 | return r; |
306 | } | 298 | } |
307 | 299 | ||
@@ -319,7 +311,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
319 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) | 311 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
320 | return -EIO; | 312 | return -EIO; |
321 | 313 | ||
322 | r = ath_reset_internal(sc, hchan, false); | 314 | r = ath_reset_internal(sc, hchan); |
323 | 315 | ||
324 | return r; | 316 | return r; |
325 | } | 317 | } |
@@ -549,23 +541,21 @@ chip_reset: | |||
549 | #undef SCHED_INTR | 541 | #undef SCHED_INTR |
550 | } | 542 | } |
551 | 543 | ||
552 | static int ath_reset(struct ath_softc *sc, bool retry_tx) | 544 | static int ath_reset(struct ath_softc *sc) |
553 | { | 545 | { |
554 | int r; | 546 | int i, r; |
555 | 547 | ||
556 | ath9k_ps_wakeup(sc); | 548 | ath9k_ps_wakeup(sc); |
557 | 549 | ||
558 | r = ath_reset_internal(sc, NULL, retry_tx); | 550 | r = ath_reset_internal(sc, NULL); |
559 | 551 | ||
560 | if (retry_tx) { | 552 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
561 | int i; | 553 | if (!ATH_TXQ_SETUP(sc, i)) |
562 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 554 | continue; |
563 | if (ATH_TXQ_SETUP(sc, i)) { | 555 | |
564 | spin_lock_bh(&sc->tx.txq[i].axq_lock); | 556 | spin_lock_bh(&sc->tx.txq[i].axq_lock); |
565 | ath_txq_schedule(sc, &sc->tx.txq[i]); | 557 | ath_txq_schedule(sc, &sc->tx.txq[i]); |
566 | spin_unlock_bh(&sc->tx.txq[i].axq_lock); | 558 | spin_unlock_bh(&sc->tx.txq[i].axq_lock); |
567 | } | ||
568 | } | ||
569 | } | 559 | } |
570 | 560 | ||
571 | ath9k_ps_restore(sc); | 561 | ath9k_ps_restore(sc); |
@@ -586,7 +576,7 @@ void ath_reset_work(struct work_struct *work) | |||
586 | { | 576 | { |
587 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); | 577 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); |
588 | 578 | ||
589 | ath_reset(sc, true); | 579 | ath_reset(sc); |
590 | } | 580 | } |
591 | 581 | ||
592 | /**********************/ | 582 | /**********************/ |
@@ -804,7 +794,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
804 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); | 794 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); |
805 | } | 795 | } |
806 | 796 | ||
807 | ath_prepare_reset(sc, false, true); | 797 | ath_prepare_reset(sc); |
808 | 798 | ||
809 | if (sc->rx.frag) { | 799 | if (sc->rx.frag) { |
810 | dev_kfree_skb_any(sc->rx.frag); | 800 | dev_kfree_skb_any(sc->rx.frag); |
@@ -1075,6 +1065,86 @@ static void ath9k_disable_ps(struct ath_softc *sc) | |||
1075 | ath_dbg(common, PS, "PowerSave disabled\n"); | 1065 | ath_dbg(common, PS, "PowerSave disabled\n"); |
1076 | } | 1066 | } |
1077 | 1067 | ||
1068 | void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw) | ||
1069 | { | ||
1070 | struct ath_softc *sc = hw->priv; | ||
1071 | struct ath_hw *ah = sc->sc_ah; | ||
1072 | struct ath_common *common = ath9k_hw_common(ah); | ||
1073 | u32 rxfilter; | ||
1074 | |||
1075 | if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { | ||
1076 | ath_err(common, "spectrum analyzer not implemented on this hardware\n"); | ||
1077 | return; | ||
1078 | } | ||
1079 | |||
1080 | ath9k_ps_wakeup(sc); | ||
1081 | rxfilter = ath9k_hw_getrxfilter(ah); | ||
1082 | ath9k_hw_setrxfilter(ah, rxfilter | | ||
1083 | ATH9K_RX_FILTER_PHYRADAR | | ||
1084 | ATH9K_RX_FILTER_PHYERR); | ||
1085 | |||
1086 | /* TODO: usually this should not be neccesary, but for some reason | ||
1087 | * (or in some mode?) the trigger must be called after the | ||
1088 | * configuration, otherwise the register will have its values reset | ||
1089 | * (on my ar9220 to value 0x01002310) | ||
1090 | */ | ||
1091 | ath9k_spectral_scan_config(hw, sc->spectral_mode); | ||
1092 | ath9k_hw_ops(ah)->spectral_scan_trigger(ah); | ||
1093 | ath9k_ps_restore(sc); | ||
1094 | } | ||
1095 | |||
1096 | int ath9k_spectral_scan_config(struct ieee80211_hw *hw, | ||
1097 | enum spectral_mode spectral_mode) | ||
1098 | { | ||
1099 | struct ath_softc *sc = hw->priv; | ||
1100 | struct ath_hw *ah = sc->sc_ah; | ||
1101 | struct ath_common *common = ath9k_hw_common(ah); | ||
1102 | struct ath_spec_scan param; | ||
1103 | |||
1104 | if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { | ||
1105 | ath_err(common, "spectrum analyzer not implemented on this hardware\n"); | ||
1106 | return -1; | ||
1107 | } | ||
1108 | |||
1109 | /* NOTE: this will generate a few samples ... | ||
1110 | * | ||
1111 | * TODO: review default parameters, and/or define an interface to set | ||
1112 | * them. | ||
1113 | */ | ||
1114 | param.enabled = 1; | ||
1115 | param.short_repeat = true; | ||
1116 | param.count = 8; | ||
1117 | param.endless = false; | ||
1118 | param.period = 0xFF; | ||
1119 | param.fft_period = 0xF; | ||
1120 | |||
1121 | switch (spectral_mode) { | ||
1122 | case SPECTRAL_DISABLED: | ||
1123 | param.enabled = 0; | ||
1124 | break; | ||
1125 | case SPECTRAL_BACKGROUND: | ||
1126 | /* send endless samples. | ||
1127 | * TODO: is this really useful for "background"? | ||
1128 | */ | ||
1129 | param.endless = 1; | ||
1130 | break; | ||
1131 | case SPECTRAL_CHANSCAN: | ||
1132 | break; | ||
1133 | case SPECTRAL_MANUAL: | ||
1134 | break; | ||
1135 | default: | ||
1136 | return -1; | ||
1137 | } | ||
1138 | |||
1139 | ath9k_ps_wakeup(sc); | ||
1140 | ath9k_hw_ops(ah)->spectral_scan_config(ah, ¶m); | ||
1141 | ath9k_ps_restore(sc); | ||
1142 | |||
1143 | sc->spectral_mode = spectral_mode; | ||
1144 | |||
1145 | return 0; | ||
1146 | } | ||
1147 | |||
1078 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1148 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
1079 | { | 1149 | { |
1080 | struct ath_softc *sc = hw->priv; | 1150 | struct ath_softc *sc = hw->priv; |
@@ -1188,6 +1258,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1188 | */ | 1258 | */ |
1189 | if (old_pos >= 0) | 1259 | if (old_pos >= 0) |
1190 | ath_update_survey_nf(sc, old_pos); | 1260 | ath_update_survey_nf(sc, old_pos); |
1261 | |||
1262 | /* perform spectral scan if requested. */ | ||
1263 | if (sc->scanning && sc->spectral_mode == SPECTRAL_CHANSCAN) | ||
1264 | ath9k_spectral_scan_trigger(hw); | ||
1265 | |||
1191 | } | 1266 | } |
1192 | 1267 | ||
1193 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 1268 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
@@ -1610,7 +1685,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1610 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1685 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1611 | ath9k_ps_restore(sc); | 1686 | ath9k_ps_restore(sc); |
1612 | break; | 1687 | break; |
1613 | case IEEE80211_AMPDU_TX_STOP: | 1688 | case IEEE80211_AMPDU_TX_STOP_CONT: |
1689 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
1690 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
1614 | ath9k_ps_wakeup(sc); | 1691 | ath9k_ps_wakeup(sc); |
1615 | ath_tx_aggr_stop(sc, sta, tid); | 1692 | ath_tx_aggr_stop(sc, sta, tid); |
1616 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1693 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
@@ -1729,11 +1806,11 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
1729 | if (drop) { | 1806 | if (drop) { |
1730 | ath9k_ps_wakeup(sc); | 1807 | ath9k_ps_wakeup(sc); |
1731 | spin_lock_bh(&sc->sc_pcu_lock); | 1808 | spin_lock_bh(&sc->sc_pcu_lock); |
1732 | drain_txq = ath_drain_all_txq(sc, false); | 1809 | drain_txq = ath_drain_all_txq(sc); |
1733 | spin_unlock_bh(&sc->sc_pcu_lock); | 1810 | spin_unlock_bh(&sc->sc_pcu_lock); |
1734 | 1811 | ||
1735 | if (!drain_txq) | 1812 | if (!drain_txq) |
1736 | ath_reset(sc, false); | 1813 | ath_reset(sc); |
1737 | 1814 | ||
1738 | ath9k_ps_restore(sc); | 1815 | ath9k_ps_restore(sc); |
1739 | ieee80211_wake_queues(hw); | 1816 | ieee80211_wake_queues(hw); |
@@ -1833,6 +1910,9 @@ static u32 fill_chainmask(u32 cap, u32 new) | |||
1833 | 1910 | ||
1834 | static bool validate_antenna_mask(struct ath_hw *ah, u32 val) | 1911 | static bool validate_antenna_mask(struct ath_hw *ah, u32 val) |
1835 | { | 1912 | { |
1913 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
1914 | return true; | ||
1915 | |||
1836 | switch (val & 0x7) { | 1916 | switch (val & 0x7) { |
1837 | case 0x1: | 1917 | case 0x1: |
1838 | case 0x3: | 1918 | case 0x3: |
@@ -2238,6 +2318,19 @@ static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) | |||
2238 | } | 2318 | } |
2239 | 2319 | ||
2240 | #endif | 2320 | #endif |
2321 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | ||
2322 | { | ||
2323 | struct ath_softc *sc = hw->priv; | ||
2324 | |||
2325 | sc->scanning = 1; | ||
2326 | } | ||
2327 | |||
2328 | static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | ||
2329 | { | ||
2330 | struct ath_softc *sc = hw->priv; | ||
2331 | |||
2332 | sc->scanning = 0; | ||
2333 | } | ||
2241 | 2334 | ||
2242 | struct ieee80211_ops ath9k_ops = { | 2335 | struct ieee80211_ops ath9k_ops = { |
2243 | .tx = ath9k_tx, | 2336 | .tx = ath9k_tx, |
@@ -2284,4 +2377,6 @@ struct ieee80211_ops ath9k_ops = { | |||
2284 | .sta_add_debugfs = ath9k_sta_add_debugfs, | 2377 | .sta_add_debugfs = ath9k_sta_add_debugfs, |
2285 | .sta_remove_debugfs = ath9k_sta_remove_debugfs, | 2378 | .sta_remove_debugfs = ath9k_sta_remove_debugfs, |
2286 | #endif | 2379 | #endif |
2380 | .sw_scan_start = ath9k_sw_scan_start, | ||
2381 | .sw_scan_complete = ath9k_sw_scan_complete, | ||
2287 | }; | 2382 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 5c02702f21e7..d2074334ec9b 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -438,7 +438,7 @@ int ath_mci_setup(struct ath_softc *sc) | |||
438 | struct ath_mci_buf *buf = &mci->sched_buf; | 438 | struct ath_mci_buf *buf = &mci->sched_buf; |
439 | int ret; | 439 | int ret; |
440 | 440 | ||
441 | buf->bf_addr = dma_alloc_coherent(sc->dev, | 441 | buf->bf_addr = dmam_alloc_coherent(sc->dev, |
442 | ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, | 442 | ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, |
443 | &buf->bf_paddr, GFP_KERNEL); | 443 | &buf->bf_paddr, GFP_KERNEL); |
444 | 444 | ||
@@ -477,11 +477,6 @@ void ath_mci_cleanup(struct ath_softc *sc) | |||
477 | struct ath_mci_coex *mci = &sc->mci_coex; | 477 | struct ath_mci_coex *mci = &sc->mci_coex; |
478 | struct ath_mci_buf *buf = &mci->sched_buf; | 478 | struct ath_mci_buf *buf = &mci->sched_buf; |
479 | 479 | ||
480 | if (buf->bf_addr) | ||
481 | dma_free_coherent(sc->dev, | ||
482 | ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, | ||
483 | buf->bf_addr, buf->bf_paddr); | ||
484 | |||
485 | ar9003_mci_cleanup(ah); | 480 | ar9003_mci_cleanup(ah); |
486 | 481 | ||
487 | ath_dbg(common, MCI, "MCI De-Initialized\n"); | 482 | ath_dbg(common, MCI, "MCI De-Initialized\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 7ae73fbd9136..0e0d39583837 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -147,7 +147,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = { | |||
147 | 147 | ||
148 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 148 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
149 | { | 149 | { |
150 | void __iomem *mem; | ||
151 | struct ath_softc *sc; | 150 | struct ath_softc *sc; |
152 | struct ieee80211_hw *hw; | 151 | struct ieee80211_hw *hw; |
153 | u8 csz; | 152 | u8 csz; |
@@ -155,19 +154,19 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
155 | int ret = 0; | 154 | int ret = 0; |
156 | char hw_name[64]; | 155 | char hw_name[64]; |
157 | 156 | ||
158 | if (pci_enable_device(pdev)) | 157 | if (pcim_enable_device(pdev)) |
159 | return -EIO; | 158 | return -EIO; |
160 | 159 | ||
161 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 160 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
162 | if (ret) { | 161 | if (ret) { |
163 | pr_err("32-bit DMA not available\n"); | 162 | pr_err("32-bit DMA not available\n"); |
164 | goto err_dma; | 163 | return ret; |
165 | } | 164 | } |
166 | 165 | ||
167 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 166 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
168 | if (ret) { | 167 | if (ret) { |
169 | pr_err("32-bit DMA consistent DMA enable failed\n"); | 168 | pr_err("32-bit DMA consistent DMA enable failed\n"); |
170 | goto err_dma; | 169 | return ret; |
171 | } | 170 | } |
172 | 171 | ||
173 | /* | 172 | /* |
@@ -203,25 +202,16 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
203 | if ((val & 0x0000ff00) != 0) | 202 | if ((val & 0x0000ff00) != 0) |
204 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | 203 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); |
205 | 204 | ||
206 | ret = pci_request_region(pdev, 0, "ath9k"); | 205 | ret = pcim_iomap_regions(pdev, BIT(0), "ath9k"); |
207 | if (ret) { | 206 | if (ret) { |
208 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | 207 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); |
209 | ret = -ENODEV; | 208 | return -ENODEV; |
210 | goto err_region; | ||
211 | } | ||
212 | |||
213 | mem = pci_iomap(pdev, 0, 0); | ||
214 | if (!mem) { | ||
215 | pr_err("PCI memory map error\n") ; | ||
216 | ret = -EIO; | ||
217 | goto err_iomap; | ||
218 | } | 209 | } |
219 | 210 | ||
220 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); | 211 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); |
221 | if (!hw) { | 212 | if (!hw) { |
222 | dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); | 213 | dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); |
223 | ret = -ENOMEM; | 214 | return -ENOMEM; |
224 | goto err_alloc_hw; | ||
225 | } | 215 | } |
226 | 216 | ||
227 | SET_IEEE80211_DEV(hw, &pdev->dev); | 217 | SET_IEEE80211_DEV(hw, &pdev->dev); |
@@ -230,7 +220,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
230 | sc = hw->priv; | 220 | sc = hw->priv; |
231 | sc->hw = hw; | 221 | sc->hw = hw; |
232 | sc->dev = &pdev->dev; | 222 | sc->dev = &pdev->dev; |
233 | sc->mem = mem; | 223 | sc->mem = pcim_iomap_table(pdev)[0]; |
234 | 224 | ||
235 | /* Will be cleared in ath9k_start() */ | 225 | /* Will be cleared in ath9k_start() */ |
236 | set_bit(SC_OP_INVALID, &sc->sc_flags); | 226 | set_bit(SC_OP_INVALID, &sc->sc_flags); |
@@ -251,7 +241,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
251 | 241 | ||
252 | ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); | 242 | ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); |
253 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", | 243 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", |
254 | hw_name, (unsigned long)mem, pdev->irq); | 244 | hw_name, (unsigned long)sc->mem, pdev->irq); |
255 | 245 | ||
256 | return 0; | 246 | return 0; |
257 | 247 | ||
@@ -259,14 +249,6 @@ err_init: | |||
259 | free_irq(sc->irq, sc); | 249 | free_irq(sc->irq, sc); |
260 | err_irq: | 250 | err_irq: |
261 | ieee80211_free_hw(hw); | 251 | ieee80211_free_hw(hw); |
262 | err_alloc_hw: | ||
263 | pci_iounmap(pdev, mem); | ||
264 | err_iomap: | ||
265 | pci_release_region(pdev, 0); | ||
266 | err_region: | ||
267 | /* Nothing */ | ||
268 | err_dma: | ||
269 | pci_disable_device(pdev); | ||
270 | return ret; | 252 | return ret; |
271 | } | 253 | } |
272 | 254 | ||
@@ -274,17 +256,12 @@ static void ath_pci_remove(struct pci_dev *pdev) | |||
274 | { | 256 | { |
275 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 257 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
276 | struct ath_softc *sc = hw->priv; | 258 | struct ath_softc *sc = hw->priv; |
277 | void __iomem *mem = sc->mem; | ||
278 | 259 | ||
279 | if (!is_ath9k_unloaded) | 260 | if (!is_ath9k_unloaded) |
280 | sc->sc_ah->ah_flags |= AH_UNPLUGGED; | 261 | sc->sc_ah->ah_flags |= AH_UNPLUGGED; |
281 | ath9k_deinit_device(sc); | 262 | ath9k_deinit_device(sc); |
282 | free_irq(sc->irq, sc); | 263 | free_irq(sc->irq, sc); |
283 | ieee80211_free_hw(sc->hw); | 264 | ieee80211_free_hw(sc->hw); |
284 | |||
285 | pci_iounmap(pdev, mem); | ||
286 | pci_disable_device(pdev); | ||
287 | pci_release_region(pdev, 0); | ||
288 | } | 265 | } |
289 | 266 | ||
290 | #ifdef CONFIG_PM_SLEEP | 267 | #ifdef CONFIG_PM_SLEEP |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index d4df98a938bf..d7c129bb571b 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/relay.h> | ||
18 | #include "ath9k.h" | 19 | #include "ath9k.h" |
19 | #include "ar9003_mac.h" | 20 | #include "ar9003_mac.h" |
20 | 21 | ||
@@ -180,11 +181,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) | |||
180 | bf->bf_mpdu = NULL; | 181 | bf->bf_mpdu = NULL; |
181 | } | 182 | } |
182 | } | 183 | } |
183 | |||
184 | INIT_LIST_HEAD(&sc->rx.rxbuf); | ||
185 | |||
186 | kfree(sc->rx.rx_bufptr); | ||
187 | sc->rx.rx_bufptr = NULL; | ||
188 | } | 184 | } |
189 | 185 | ||
190 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) | 186 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) |
@@ -211,12 +207,11 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) | |||
211 | ah->caps.rx_hp_qdepth); | 207 | ah->caps.rx_hp_qdepth); |
212 | 208 | ||
213 | size = sizeof(struct ath_buf) * nbufs; | 209 | size = sizeof(struct ath_buf) * nbufs; |
214 | bf = kzalloc(size, GFP_KERNEL); | 210 | bf = devm_kzalloc(sc->dev, size, GFP_KERNEL); |
215 | if (!bf) | 211 | if (!bf) |
216 | return -ENOMEM; | 212 | return -ENOMEM; |
217 | 213 | ||
218 | INIT_LIST_HEAD(&sc->rx.rxbuf); | 214 | INIT_LIST_HEAD(&sc->rx.rxbuf); |
219 | sc->rx.rx_bufptr = bf; | ||
220 | 215 | ||
221 | for (i = 0; i < nbufs; i++, bf++) { | 216 | for (i = 0; i < nbufs; i++, bf++) { |
222 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL); | 217 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL); |
@@ -254,8 +249,6 @@ rx_init_fail: | |||
254 | 249 | ||
255 | static void ath_edma_start_recv(struct ath_softc *sc) | 250 | static void ath_edma_start_recv(struct ath_softc *sc) |
256 | { | 251 | { |
257 | spin_lock_bh(&sc->rx.rxbuflock); | ||
258 | |||
259 | ath9k_hw_rxena(sc->sc_ah); | 252 | ath9k_hw_rxena(sc->sc_ah); |
260 | 253 | ||
261 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, | 254 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, |
@@ -267,8 +260,6 @@ static void ath_edma_start_recv(struct ath_softc *sc) | |||
267 | ath_opmode_init(sc); | 260 | ath_opmode_init(sc); |
268 | 261 | ||
269 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); | 262 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
270 | |||
271 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
272 | } | 263 | } |
273 | 264 | ||
274 | static void ath_edma_stop_recv(struct ath_softc *sc) | 265 | static void ath_edma_stop_recv(struct ath_softc *sc) |
@@ -285,8 +276,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
285 | int error = 0; | 276 | int error = 0; |
286 | 277 | ||
287 | spin_lock_init(&sc->sc_pcu_lock); | 278 | spin_lock_init(&sc->sc_pcu_lock); |
288 | spin_lock_init(&sc->rx.rxbuflock); | ||
289 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
290 | 279 | ||
291 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + | 280 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + |
292 | sc->sc_ah->caps.rx_status_len; | 281 | sc->sc_ah->caps.rx_status_len; |
@@ -363,9 +352,6 @@ void ath_rx_cleanup(struct ath_softc *sc) | |||
363 | bf->bf_mpdu = NULL; | 352 | bf->bf_mpdu = NULL; |
364 | } | 353 | } |
365 | } | 354 | } |
366 | |||
367 | if (sc->rx.rxdma.dd_desc_len != 0) | ||
368 | ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf); | ||
369 | } | 355 | } |
370 | } | 356 | } |
371 | 357 | ||
@@ -447,7 +433,6 @@ int ath_startrecv(struct ath_softc *sc) | |||
447 | return 0; | 433 | return 0; |
448 | } | 434 | } |
449 | 435 | ||
450 | spin_lock_bh(&sc->rx.rxbuflock); | ||
451 | if (list_empty(&sc->rx.rxbuf)) | 436 | if (list_empty(&sc->rx.rxbuf)) |
452 | goto start_recv; | 437 | goto start_recv; |
453 | 438 | ||
@@ -468,26 +453,31 @@ start_recv: | |||
468 | ath_opmode_init(sc); | 453 | ath_opmode_init(sc); |
469 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); | 454 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
470 | 455 | ||
471 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
472 | |||
473 | return 0; | 456 | return 0; |
474 | } | 457 | } |
475 | 458 | ||
459 | static void ath_flushrecv(struct ath_softc *sc) | ||
460 | { | ||
461 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
462 | ath_rx_tasklet(sc, 1, true); | ||
463 | ath_rx_tasklet(sc, 1, false); | ||
464 | } | ||
465 | |||
476 | bool ath_stoprecv(struct ath_softc *sc) | 466 | bool ath_stoprecv(struct ath_softc *sc) |
477 | { | 467 | { |
478 | struct ath_hw *ah = sc->sc_ah; | 468 | struct ath_hw *ah = sc->sc_ah; |
479 | bool stopped, reset = false; | 469 | bool stopped, reset = false; |
480 | 470 | ||
481 | spin_lock_bh(&sc->rx.rxbuflock); | ||
482 | ath9k_hw_abortpcurecv(ah); | 471 | ath9k_hw_abortpcurecv(ah); |
483 | ath9k_hw_setrxfilter(ah, 0); | 472 | ath9k_hw_setrxfilter(ah, 0); |
484 | stopped = ath9k_hw_stopdmarecv(ah, &reset); | 473 | stopped = ath9k_hw_stopdmarecv(ah, &reset); |
485 | 474 | ||
475 | ath_flushrecv(sc); | ||
476 | |||
486 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 477 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
487 | ath_edma_stop_recv(sc); | 478 | ath_edma_stop_recv(sc); |
488 | else | 479 | else |
489 | sc->rx.rxlink = NULL; | 480 | sc->rx.rxlink = NULL; |
490 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
491 | 481 | ||
492 | if (!(ah->ah_flags & AH_UNPLUGGED) && | 482 | if (!(ah->ah_flags & AH_UNPLUGGED) && |
493 | unlikely(!stopped)) { | 483 | unlikely(!stopped)) { |
@@ -499,15 +489,6 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
499 | return stopped && !reset; | 489 | return stopped && !reset; |
500 | } | 490 | } |
501 | 491 | ||
502 | void ath_flushrecv(struct ath_softc *sc) | ||
503 | { | ||
504 | set_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
505 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
506 | ath_rx_tasklet(sc, 1, true); | ||
507 | ath_rx_tasklet(sc, 1, false); | ||
508 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
509 | } | ||
510 | |||
511 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) | 492 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) |
512 | { | 493 | { |
513 | /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ | 494 | /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ |
@@ -744,6 +725,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
744 | return NULL; | 725 | return NULL; |
745 | } | 726 | } |
746 | 727 | ||
728 | list_del(&bf->list); | ||
747 | if (!bf->bf_mpdu) | 729 | if (!bf->bf_mpdu) |
748 | return bf; | 730 | return bf; |
749 | 731 | ||
@@ -1034,6 +1016,108 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, | |||
1034 | rxs->flag &= ~RX_FLAG_DECRYPTED; | 1016 | rxs->flag &= ~RX_FLAG_DECRYPTED; |
1035 | } | 1017 | } |
1036 | 1018 | ||
1019 | static s8 fix_rssi_inv_only(u8 rssi_val) | ||
1020 | { | ||
1021 | if (rssi_val == 128) | ||
1022 | rssi_val = 0; | ||
1023 | return (s8) rssi_val; | ||
1024 | } | ||
1025 | |||
1026 | |||
1027 | static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, | ||
1028 | struct ath_rx_status *rs, u64 tsf) | ||
1029 | { | ||
1030 | #ifdef CONFIG_ATH_DEBUG | ||
1031 | struct ath_hw *ah = sc->sc_ah; | ||
1032 | u8 bins[SPECTRAL_HT20_NUM_BINS]; | ||
1033 | u8 *vdata = (u8 *)hdr; | ||
1034 | struct fft_sample_ht20 fft_sample; | ||
1035 | struct ath_radar_info *radar_info; | ||
1036 | struct ath_ht20_mag_info *mag_info; | ||
1037 | int len = rs->rs_datalen; | ||
1038 | int i, dc_pos; | ||
1039 | |||
1040 | /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer | ||
1041 | * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT | ||
1042 | * yet, but this is supposed to be possible as well. | ||
1043 | */ | ||
1044 | if (rs->rs_phyerr != ATH9K_PHYERR_RADAR && | ||
1045 | rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT && | ||
1046 | rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL) | ||
1047 | return; | ||
1048 | |||
1049 | /* Variation in the data length is possible and will be fixed later. | ||
1050 | * Note that we only support HT20 for now. | ||
1051 | * | ||
1052 | * TODO: add HT20_40 support as well. | ||
1053 | */ | ||
1054 | if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) || | ||
1055 | (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1)) | ||
1056 | return; | ||
1057 | |||
1058 | /* check if spectral scan bit is set. This does not have to be checked | ||
1059 | * if received through a SPECTRAL phy error, but shouldn't hurt. | ||
1060 | */ | ||
1061 | radar_info = ((struct ath_radar_info *)&vdata[len]) - 1; | ||
1062 | if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK)) | ||
1063 | return; | ||
1064 | |||
1065 | fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20; | ||
1066 | fft_sample.tlv.length = sizeof(fft_sample) - sizeof(fft_sample.tlv); | ||
1067 | |||
1068 | fft_sample.freq = ah->curchan->chan->center_freq; | ||
1069 | fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0); | ||
1070 | fft_sample.noise = ah->noise; | ||
1071 | |||
1072 | switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) { | ||
1073 | case 0: | ||
1074 | /* length correct, nothing to do. */ | ||
1075 | memcpy(bins, vdata, SPECTRAL_HT20_NUM_BINS); | ||
1076 | break; | ||
1077 | case -1: | ||
1078 | /* first byte missing, duplicate it. */ | ||
1079 | memcpy(&bins[1], vdata, SPECTRAL_HT20_NUM_BINS - 1); | ||
1080 | bins[0] = vdata[0]; | ||
1081 | break; | ||
1082 | case 2: | ||
1083 | /* MAC added 2 extra bytes at bin 30 and 32, remove them. */ | ||
1084 | memcpy(bins, vdata, 30); | ||
1085 | bins[30] = vdata[31]; | ||
1086 | memcpy(&bins[31], &vdata[33], SPECTRAL_HT20_NUM_BINS - 31); | ||
1087 | break; | ||
1088 | case 1: | ||
1089 | /* MAC added 2 extra bytes AND first byte is missing. */ | ||
1090 | bins[0] = vdata[0]; | ||
1091 | memcpy(&bins[0], vdata, 30); | ||
1092 | bins[31] = vdata[31]; | ||
1093 | memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32); | ||
1094 | break; | ||
1095 | default: | ||
1096 | return; | ||
1097 | } | ||
1098 | |||
1099 | /* DC value (value in the middle) is the blind spot of the spectral | ||
1100 | * sample and invalid, interpolate it. | ||
1101 | */ | ||
1102 | dc_pos = SPECTRAL_HT20_NUM_BINS / 2; | ||
1103 | bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2; | ||
1104 | |||
1105 | /* mag data is at the end of the frame, in front of radar_info */ | ||
1106 | mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1; | ||
1107 | |||
1108 | /* Apply exponent and grab further auxiliary information. */ | ||
1109 | for (i = 0; i < SPECTRAL_HT20_NUM_BINS; i++) | ||
1110 | fft_sample.data[i] = bins[i] << mag_info->max_exp; | ||
1111 | |||
1112 | fft_sample.max_magnitude = spectral_max_magnitude(mag_info->all_bins); | ||
1113 | fft_sample.max_index = spectral_max_index(mag_info->all_bins); | ||
1114 | fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins); | ||
1115 | fft_sample.tsf = tsf; | ||
1116 | |||
1117 | ath_debug_send_fft_sample(sc, &fft_sample.tlv); | ||
1118 | #endif | ||
1119 | } | ||
1120 | |||
1037 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | 1121 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) |
1038 | { | 1122 | { |
1039 | struct ath_buf *bf; | 1123 | struct ath_buf *bf; |
@@ -1059,16 +1143,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1059 | dma_type = DMA_FROM_DEVICE; | 1143 | dma_type = DMA_FROM_DEVICE; |
1060 | 1144 | ||
1061 | qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; | 1145 | qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; |
1062 | spin_lock_bh(&sc->rx.rxbuflock); | ||
1063 | 1146 | ||
1064 | tsf = ath9k_hw_gettsf64(ah); | 1147 | tsf = ath9k_hw_gettsf64(ah); |
1065 | tsf_lower = tsf & 0xffffffff; | 1148 | tsf_lower = tsf & 0xffffffff; |
1066 | 1149 | ||
1067 | do { | 1150 | do { |
1068 | bool decrypt_error = false; | 1151 | bool decrypt_error = false; |
1069 | /* If handling rx interrupt and flush is in progress => exit */ | ||
1070 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) | ||
1071 | break; | ||
1072 | 1152 | ||
1073 | memset(&rs, 0, sizeof(rs)); | 1153 | memset(&rs, 0, sizeof(rs)); |
1074 | if (edma) | 1154 | if (edma) |
@@ -1111,15 +1191,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1111 | 1191 | ||
1112 | ath_debug_stat_rx(sc, &rs); | 1192 | ath_debug_stat_rx(sc, &rs); |
1113 | 1193 | ||
1114 | /* | ||
1115 | * If we're asked to flush receive queue, directly | ||
1116 | * chain it back at the queue without processing it. | ||
1117 | */ | ||
1118 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) { | ||
1119 | RX_STAT_INC(rx_drop_rxflush); | ||
1120 | goto requeue_drop_frag; | ||
1121 | } | ||
1122 | |||
1123 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); | 1194 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); |
1124 | 1195 | ||
1125 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; | 1196 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; |
@@ -1131,6 +1202,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1131 | unlikely(tsf_lower - rs.rs_tstamp > 0x10000000)) | 1202 | unlikely(tsf_lower - rs.rs_tstamp > 0x10000000)) |
1132 | rxs->mactime += 0x100000000ULL; | 1203 | rxs->mactime += 0x100000000ULL; |
1133 | 1204 | ||
1205 | if ((rs.rs_status & ATH9K_RXERR_PHY)) | ||
1206 | ath_process_fft(sc, hdr, &rs, rxs->mactime); | ||
1207 | |||
1134 | retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, | 1208 | retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, |
1135 | rxs, &decrypt_error); | 1209 | rxs, &decrypt_error); |
1136 | if (retval) | 1210 | if (retval) |
@@ -1254,19 +1328,18 @@ requeue_drop_frag: | |||
1254 | sc->rx.frag = NULL; | 1328 | sc->rx.frag = NULL; |
1255 | } | 1329 | } |
1256 | requeue: | 1330 | requeue: |
1331 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
1332 | if (flush) | ||
1333 | continue; | ||
1334 | |||
1257 | if (edma) { | 1335 | if (edma) { |
1258 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
1259 | ath_rx_edma_buf_link(sc, qtype); | 1336 | ath_rx_edma_buf_link(sc, qtype); |
1260 | } else { | 1337 | } else { |
1261 | list_move_tail(&bf->list, &sc->rx.rxbuf); | ||
1262 | ath_rx_buf_link(sc, bf); | 1338 | ath_rx_buf_link(sc, bf); |
1263 | if (!flush) | 1339 | ath9k_hw_rxena(ah); |
1264 | ath9k_hw_rxena(ah); | ||
1265 | } | 1340 | } |
1266 | } while (1); | 1341 | } while (1); |
1267 | 1342 | ||
1268 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
1269 | |||
1270 | if (!(ah->imask & ATH9K_INT_RXEOL)) { | 1343 | if (!(ah->imask & ATH9K_INT_RXEOL)) { |
1271 | ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | 1344 | ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); |
1272 | ath9k_hw_set_interrupts(ah); | 1345 | ath9k_hw_set_interrupts(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index ad3c82c09177..5929850649f0 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -789,6 +789,7 @@ | |||
789 | #define AR_SREV_REVISION_9271_11 1 | 789 | #define AR_SREV_REVISION_9271_11 1 |
790 | #define AR_SREV_VERSION_9300 0x1c0 | 790 | #define AR_SREV_VERSION_9300 0x1c0 |
791 | #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ | 791 | #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ |
792 | #define AR_SREV_REVISION_9300_22 3 | ||
792 | #define AR_SREV_VERSION_9330 0x200 | 793 | #define AR_SREV_VERSION_9330 0x200 |
793 | #define AR_SREV_REVISION_9330_10 0 | 794 | #define AR_SREV_REVISION_9330_10 0 |
794 | #define AR_SREV_REVISION_9330_11 1 | 795 | #define AR_SREV_REVISION_9330_11 1 |
@@ -869,6 +870,9 @@ | |||
869 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) | 870 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) |
870 | #define AR_SREV_9300_20_OR_LATER(_ah) \ | 871 | #define AR_SREV_9300_20_OR_LATER(_ah) \ |
871 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) | 872 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) |
873 | #define AR_SREV_9300_22(_ah) \ | ||
874 | (AR_SREV_9300(ah) && \ | ||
875 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_22)) | ||
872 | 876 | ||
873 | #define AR_SREV_9330(_ah) \ | 877 | #define AR_SREV_9330(_ah) \ |
874 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330)) | 878 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330)) |
@@ -884,9 +888,6 @@ | |||
884 | 888 | ||
885 | #define AR_SREV_9485(_ah) \ | 889 | #define AR_SREV_9485(_ah) \ |
886 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) | 890 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) |
887 | #define AR_SREV_9485_10(_ah) \ | ||
888 | (AR_SREV_9485(_ah) && \ | ||
889 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10)) | ||
890 | #define AR_SREV_9485_11(_ah) \ | 891 | #define AR_SREV_9485_11(_ah) \ |
891 | (AR_SREV_9485(_ah) && \ | 892 | (AR_SREV_9485(_ah) && \ |
892 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) | 893 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 90e48a0fafe5..feacaafee959 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -378,7 +378,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, | |||
378 | 378 | ||
379 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | 379 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, |
380 | struct ath_buf *bf, struct list_head *bf_q, | 380 | struct ath_buf *bf, struct list_head *bf_q, |
381 | struct ath_tx_status *ts, int txok, bool retry) | 381 | struct ath_tx_status *ts, int txok) |
382 | { | 382 | { |
383 | struct ath_node *an = NULL; | 383 | struct ath_node *an = NULL; |
384 | struct sk_buff *skb; | 384 | struct sk_buff *skb; |
@@ -490,7 +490,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
490 | } else if (!isaggr && txok) { | 490 | } else if (!isaggr && txok) { |
491 | /* transmit completion */ | 491 | /* transmit completion */ |
492 | acked_cnt++; | 492 | acked_cnt++; |
493 | } else if ((tid->state & AGGR_CLEANUP) || !retry) { | 493 | } else if (tid->state & AGGR_CLEANUP) { |
494 | /* | 494 | /* |
495 | * cleanup in progress, just fail | 495 | * cleanup in progress, just fail |
496 | * the un-acked sub-frames | 496 | * the un-acked sub-frames |
@@ -604,6 +604,37 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
604 | ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR); | 604 | ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR); |
605 | } | 605 | } |
606 | 606 | ||
607 | static bool bf_is_ampdu_not_probing(struct ath_buf *bf) | ||
608 | { | ||
609 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu); | ||
610 | return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); | ||
611 | } | ||
612 | |||
613 | static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | ||
614 | struct ath_tx_status *ts, struct ath_buf *bf, | ||
615 | struct list_head *bf_head) | ||
616 | { | ||
617 | bool txok, flush; | ||
618 | |||
619 | txok = !(ts->ts_status & ATH9K_TXERR_MASK); | ||
620 | flush = !!(ts->ts_status & ATH9K_TX_FLUSH); | ||
621 | txq->axq_tx_inprogress = false; | ||
622 | |||
623 | txq->axq_depth--; | ||
624 | if (bf_is_ampdu_not_probing(bf)) | ||
625 | txq->axq_ampdu_depth--; | ||
626 | |||
627 | if (!bf_isampdu(bf)) { | ||
628 | if (!flush) | ||
629 | ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); | ||
630 | ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); | ||
631 | } else | ||
632 | ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok); | ||
633 | |||
634 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !flush) | ||
635 | ath_txq_schedule(sc, txq); | ||
636 | } | ||
637 | |||
607 | static bool ath_lookup_legacy(struct ath_buf *bf) | 638 | static bool ath_lookup_legacy(struct ath_buf *bf) |
608 | { | 639 | { |
609 | struct sk_buff *skb; | 640 | struct sk_buff *skb; |
@@ -1331,23 +1362,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid | |||
1331 | /* Queue Management */ | 1362 | /* Queue Management */ |
1332 | /********************/ | 1363 | /********************/ |
1333 | 1364 | ||
1334 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | ||
1335 | struct ath_txq *txq) | ||
1336 | { | ||
1337 | struct ath_atx_ac *ac, *ac_tmp; | ||
1338 | struct ath_atx_tid *tid, *tid_tmp; | ||
1339 | |||
1340 | list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { | ||
1341 | list_del(&ac->list); | ||
1342 | ac->sched = false; | ||
1343 | list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { | ||
1344 | list_del(&tid->list); | ||
1345 | tid->sched = false; | ||
1346 | ath_tid_drain(sc, txq, tid); | ||
1347 | } | ||
1348 | } | ||
1349 | } | ||
1350 | |||
1351 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | 1365 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) |
1352 | { | 1366 | { |
1353 | struct ath_hw *ah = sc->sc_ah; | 1367 | struct ath_hw *ah = sc->sc_ah; |
@@ -1470,14 +1484,8 @@ int ath_cabq_update(struct ath_softc *sc) | |||
1470 | return 0; | 1484 | return 0; |
1471 | } | 1485 | } |
1472 | 1486 | ||
1473 | static bool bf_is_ampdu_not_probing(struct ath_buf *bf) | ||
1474 | { | ||
1475 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu); | ||
1476 | return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); | ||
1477 | } | ||
1478 | |||
1479 | static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, | 1487 | static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, |
1480 | struct list_head *list, bool retry_tx) | 1488 | struct list_head *list) |
1481 | { | 1489 | { |
1482 | struct ath_buf *bf, *lastbf; | 1490 | struct ath_buf *bf, *lastbf; |
1483 | struct list_head bf_head; | 1491 | struct list_head bf_head; |
@@ -1499,16 +1507,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, | |||
1499 | 1507 | ||
1500 | lastbf = bf->bf_lastbf; | 1508 | lastbf = bf->bf_lastbf; |
1501 | list_cut_position(&bf_head, list, &lastbf->list); | 1509 | list_cut_position(&bf_head, list, &lastbf->list); |
1502 | 1510 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); | |
1503 | txq->axq_depth--; | ||
1504 | if (bf_is_ampdu_not_probing(bf)) | ||
1505 | txq->axq_ampdu_depth--; | ||
1506 | |||
1507 | if (bf_isampdu(bf)) | ||
1508 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, | ||
1509 | retry_tx); | ||
1510 | else | ||
1511 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); | ||
1512 | } | 1511 | } |
1513 | } | 1512 | } |
1514 | 1513 | ||
@@ -1518,7 +1517,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, | |||
1518 | * This assumes output has been stopped and | 1517 | * This assumes output has been stopped and |
1519 | * we do not need to block ath_tx_tasklet. | 1518 | * we do not need to block ath_tx_tasklet. |
1520 | */ | 1519 | */ |
1521 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | 1520 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq) |
1522 | { | 1521 | { |
1523 | ath_txq_lock(sc, txq); | 1522 | ath_txq_lock(sc, txq); |
1524 | 1523 | ||
@@ -1526,8 +1525,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1526 | int idx = txq->txq_tailidx; | 1525 | int idx = txq->txq_tailidx; |
1527 | 1526 | ||
1528 | while (!list_empty(&txq->txq_fifo[idx])) { | 1527 | while (!list_empty(&txq->txq_fifo[idx])) { |
1529 | ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx], | 1528 | ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx]); |
1530 | retry_tx); | ||
1531 | 1529 | ||
1532 | INCR(idx, ATH_TXFIFO_DEPTH); | 1530 | INCR(idx, ATH_TXFIFO_DEPTH); |
1533 | } | 1531 | } |
@@ -1536,16 +1534,12 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1536 | 1534 | ||
1537 | txq->axq_link = NULL; | 1535 | txq->axq_link = NULL; |
1538 | txq->axq_tx_inprogress = false; | 1536 | txq->axq_tx_inprogress = false; |
1539 | ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); | 1537 | ath_drain_txq_list(sc, txq, &txq->axq_q); |
1540 | |||
1541 | /* flush any pending frames if aggregation is enabled */ | ||
1542 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx) | ||
1543 | ath_txq_drain_pending_buffers(sc, txq); | ||
1544 | 1538 | ||
1545 | ath_txq_unlock_complete(sc, txq); | 1539 | ath_txq_unlock_complete(sc, txq); |
1546 | } | 1540 | } |
1547 | 1541 | ||
1548 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1542 | bool ath_drain_all_txq(struct ath_softc *sc) |
1549 | { | 1543 | { |
1550 | struct ath_hw *ah = sc->sc_ah; | 1544 | struct ath_hw *ah = sc->sc_ah; |
1551 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1545 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -1581,7 +1575,7 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1581 | */ | 1575 | */ |
1582 | txq = &sc->tx.txq[i]; | 1576 | txq = &sc->tx.txq[i]; |
1583 | txq->stopped = false; | 1577 | txq->stopped = false; |
1584 | ath_draintxq(sc, txq, retry_tx); | 1578 | ath_draintxq(sc, txq); |
1585 | } | 1579 | } |
1586 | 1580 | ||
1587 | return !npend; | 1581 | return !npend; |
@@ -2175,28 +2169,6 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, | |||
2175 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; | 2169 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
2176 | } | 2170 | } |
2177 | 2171 | ||
2178 | static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | ||
2179 | struct ath_tx_status *ts, struct ath_buf *bf, | ||
2180 | struct list_head *bf_head) | ||
2181 | { | ||
2182 | int txok; | ||
2183 | |||
2184 | txq->axq_depth--; | ||
2185 | txok = !(ts->ts_status & ATH9K_TXERR_MASK); | ||
2186 | txq->axq_tx_inprogress = false; | ||
2187 | if (bf_is_ampdu_not_probing(bf)) | ||
2188 | txq->axq_ampdu_depth--; | ||
2189 | |||
2190 | if (!bf_isampdu(bf)) { | ||
2191 | ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); | ||
2192 | ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); | ||
2193 | } else | ||
2194 | ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); | ||
2195 | |||
2196 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | ||
2197 | ath_txq_schedule(sc, txq); | ||
2198 | } | ||
2199 | |||
2200 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | 2172 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) |
2201 | { | 2173 | { |
2202 | struct ath_hw *ah = sc->sc_ah; | 2174 | struct ath_hw *ah = sc->sc_ah; |
@@ -2361,8 +2333,8 @@ static int ath_txstatus_setup(struct ath_softc *sc, int size) | |||
2361 | u8 txs_len = sc->sc_ah->caps.txs_len; | 2333 | u8 txs_len = sc->sc_ah->caps.txs_len; |
2362 | 2334 | ||
2363 | dd->dd_desc_len = size * txs_len; | 2335 | dd->dd_desc_len = size * txs_len; |
2364 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | 2336 | dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len, |
2365 | &dd->dd_desc_paddr, GFP_KERNEL); | 2337 | &dd->dd_desc_paddr, GFP_KERNEL); |
2366 | if (!dd->dd_desc) | 2338 | if (!dd->dd_desc) |
2367 | return -ENOMEM; | 2339 | return -ENOMEM; |
2368 | 2340 | ||
@@ -2382,14 +2354,6 @@ static int ath_tx_edma_init(struct ath_softc *sc) | |||
2382 | return err; | 2354 | return err; |
2383 | } | 2355 | } |
2384 | 2356 | ||
2385 | static void ath_tx_edma_cleanup(struct ath_softc *sc) | ||
2386 | { | ||
2387 | struct ath_descdma *dd = &sc->txsdma; | ||
2388 | |||
2389 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
2390 | dd->dd_desc_paddr); | ||
2391 | } | ||
2392 | |||
2393 | int ath_tx_init(struct ath_softc *sc, int nbufs) | 2357 | int ath_tx_init(struct ath_softc *sc, int nbufs) |
2394 | { | 2358 | { |
2395 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2359 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -2402,7 +2366,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2402 | if (error != 0) { | 2366 | if (error != 0) { |
2403 | ath_err(common, | 2367 | ath_err(common, |
2404 | "Failed to allocate tx descriptors: %d\n", error); | 2368 | "Failed to allocate tx descriptors: %d\n", error); |
2405 | goto err; | 2369 | return error; |
2406 | } | 2370 | } |
2407 | 2371 | ||
2408 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, | 2372 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, |
@@ -2410,36 +2374,17 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2410 | if (error != 0) { | 2374 | if (error != 0) { |
2411 | ath_err(common, | 2375 | ath_err(common, |
2412 | "Failed to allocate beacon descriptors: %d\n", error); | 2376 | "Failed to allocate beacon descriptors: %d\n", error); |
2413 | goto err; | 2377 | return error; |
2414 | } | 2378 | } |
2415 | 2379 | ||
2416 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | 2380 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); |
2417 | 2381 | ||
2418 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 2382 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
2419 | error = ath_tx_edma_init(sc); | 2383 | error = ath_tx_edma_init(sc); |
2420 | if (error) | ||
2421 | goto err; | ||
2422 | } | ||
2423 | |||
2424 | err: | ||
2425 | if (error != 0) | ||
2426 | ath_tx_cleanup(sc); | ||
2427 | 2384 | ||
2428 | return error; | 2385 | return error; |
2429 | } | 2386 | } |
2430 | 2387 | ||
2431 | void ath_tx_cleanup(struct ath_softc *sc) | ||
2432 | { | ||
2433 | if (sc->beacon.bdma.dd_desc_len != 0) | ||
2434 | ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf); | ||
2435 | |||
2436 | if (sc->tx.txdma.dd_desc_len != 0) | ||
2437 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); | ||
2438 | |||
2439 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
2440 | ath_tx_edma_cleanup(sc); | ||
2441 | } | ||
2442 | |||
2443 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | 2388 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) |
2444 | { | 2389 | { |
2445 | struct ath_atx_tid *tid; | 2390 | struct ath_atx_tid *tid; |
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 2df17f1e49ef..25599741cd8a 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h | |||
@@ -85,20 +85,14 @@ enum carl9170_device_state { | |||
85 | CARL9170_STARTED, | 85 | CARL9170_STARTED, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | #define CARL9170_NUM_TID 16 | ||
89 | #define WME_BA_BMP_SIZE 64 | 88 | #define WME_BA_BMP_SIZE 64 |
90 | #define CARL9170_TX_USER_RATE_TRIES 3 | 89 | #define CARL9170_TX_USER_RATE_TRIES 3 |
91 | 90 | ||
92 | #define WME_AC_BE 2 | ||
93 | #define WME_AC_BK 3 | ||
94 | #define WME_AC_VI 1 | ||
95 | #define WME_AC_VO 0 | ||
96 | |||
97 | #define TID_TO_WME_AC(_tid) \ | 91 | #define TID_TO_WME_AC(_tid) \ |
98 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ | 92 | ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \ |
99 | (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ | 93 | (((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK : \ |
100 | (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ | 94 | (((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI : \ |
101 | WME_AC_VO) | 95 | IEEE80211_AC_VO) |
102 | 96 | ||
103 | #define SEQ_DIFF(_start, _seq) \ | 97 | #define SEQ_DIFF(_start, _seq) \ |
104 | (((_start) - (_seq)) & 0x0fff) | 98 | (((_start) - (_seq)) & 0x0fff) |
@@ -290,6 +284,7 @@ struct ar9170 { | |||
290 | unsigned int rx_size; | 284 | unsigned int rx_size; |
291 | unsigned int tx_seq_table; | 285 | unsigned int tx_seq_table; |
292 | bool ba_filter; | 286 | bool ba_filter; |
287 | bool disable_offload_fw; | ||
293 | } fw; | 288 | } fw; |
294 | 289 | ||
295 | /* interface configuration combinations */ | 290 | /* interface configuration combinations */ |
@@ -493,8 +488,8 @@ struct carl9170_sta_info { | |||
493 | bool sleeping; | 488 | bool sleeping; |
494 | atomic_t pending_frames; | 489 | atomic_t pending_frames; |
495 | unsigned int ampdu_max_len; | 490 | unsigned int ampdu_max_len; |
496 | struct carl9170_sta_tid __rcu *agg[CARL9170_NUM_TID]; | 491 | struct carl9170_sta_tid __rcu *agg[IEEE80211_NUM_TIDS]; |
497 | struct carl9170_ba_stats stats[CARL9170_NUM_TID]; | 492 | struct carl9170_ba_stats stats[IEEE80211_NUM_TIDS]; |
498 | }; | 493 | }; |
499 | 494 | ||
500 | struct carl9170_tx_info { | 495 | struct carl9170_tx_info { |
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 63fd9af3fd39..47d5c2e910ad 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
@@ -215,6 +215,24 @@ static int carl9170_fw_tx_sequence(struct ar9170 *ar) | |||
215 | return 0; | 215 | return 0; |
216 | } | 216 | } |
217 | 217 | ||
218 | static void carl9170_fw_set_if_combinations(struct ar9170 *ar, | ||
219 | u16 if_comb_types) | ||
220 | { | ||
221 | if (ar->fw.vif_num < 2) | ||
222 | return; | ||
223 | |||
224 | ar->if_comb_limits[0].max = ar->fw.vif_num; | ||
225 | ar->if_comb_limits[0].types = if_comb_types; | ||
226 | |||
227 | ar->if_combs[0].num_different_channels = 1; | ||
228 | ar->if_combs[0].max_interfaces = ar->fw.vif_num; | ||
229 | ar->if_combs[0].limits = ar->if_comb_limits; | ||
230 | ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); | ||
231 | |||
232 | ar->hw->wiphy->iface_combinations = ar->if_combs; | ||
233 | ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); | ||
234 | } | ||
235 | |||
218 | static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | 236 | static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) |
219 | { | 237 | { |
220 | const struct carl9170fw_otus_desc *otus_desc; | 238 | const struct carl9170fw_otus_desc *otus_desc; |
@@ -264,7 +282,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
264 | if (!SUPP(CARL9170FW_COMMAND_CAM)) { | 282 | if (!SUPP(CARL9170FW_COMMAND_CAM)) { |
265 | dev_info(&ar->udev->dev, "crypto offloading is disabled " | 283 | dev_info(&ar->udev->dev, "crypto offloading is disabled " |
266 | "by firmware.\n"); | 284 | "by firmware.\n"); |
267 | ar->disable_offload = true; | 285 | ar->fw.disable_offload_fw = true; |
268 | } | 286 | } |
269 | 287 | ||
270 | if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM)) | 288 | if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM)) |
@@ -345,20 +363,15 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
345 | } | 363 | } |
346 | } | 364 | } |
347 | 365 | ||
348 | ar->if_comb_limits[0].max = ar->fw.vif_num; | 366 | carl9170_fw_set_if_combinations(ar, if_comb_types); |
349 | ar->if_comb_limits[0].types = if_comb_types; | ||
350 | |||
351 | ar->if_combs[0].num_different_channels = 1; | ||
352 | ar->if_combs[0].max_interfaces = ar->fw.vif_num; | ||
353 | ar->if_combs[0].limits = ar->if_comb_limits; | ||
354 | ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); | ||
355 | |||
356 | ar->hw->wiphy->iface_combinations = ar->if_combs; | ||
357 | ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); | ||
358 | 367 | ||
359 | ar->hw->wiphy->interface_modes |= if_comb_types; | 368 | ar->hw->wiphy->interface_modes |= if_comb_types; |
360 | 369 | ||
361 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 370 | ar->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
371 | |||
372 | /* As IBSS Encryption is software-based, IBSS RSN is supported. */ | ||
373 | ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | | ||
374 | WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_SUPPORTS_TDLS; | ||
362 | 375 | ||
363 | #undef SUPPORTED | 376 | #undef SUPPORTED |
364 | return carl9170_fw_tx_sequence(ar); | 377 | return carl9170_fw_tx_sequence(ar); |
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h index 9443c802b25b..9111d4ffc1b3 100644 --- a/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h | |||
@@ -156,6 +156,14 @@ struct carl9170_psm { | |||
156 | } __packed; | 156 | } __packed; |
157 | #define CARL9170_PSM_SIZE 4 | 157 | #define CARL9170_PSM_SIZE 4 |
158 | 158 | ||
159 | /* | ||
160 | * Note: If a bit in rx_filter is set, then it | ||
161 | * means that the particular frames which matches | ||
162 | * the condition are FILTERED/REMOVED/DISCARDED! | ||
163 | * (This is can be a bit confusing, especially | ||
164 | * because someone people think it's the exact | ||
165 | * opposite way, so watch out!) | ||
166 | */ | ||
159 | struct carl9170_rx_filter_cmd { | 167 | struct carl9170_rx_filter_cmd { |
160 | __le32 rx_filter; | 168 | __le32 rx_filter; |
161 | } __packed; | 169 | } __packed; |
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h index fa834c1460f0..0db874abde50 100644 --- a/drivers/net/wireless/ath/carl9170/hw.h +++ b/drivers/net/wireless/ath/carl9170/hw.h | |||
@@ -384,7 +384,7 @@ | |||
384 | 384 | ||
385 | #define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84) | 385 | #define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84) |
386 | #define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88) | 386 | #define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88) |
387 | #define AR9170_MAC_BCN_LENGTH_MAX 256 | 387 | #define AR9170_MAC_BCN_LENGTH_MAX (512 - 32) |
388 | 388 | ||
389 | #define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c) | 389 | #define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c) |
390 | 390 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 25a1e2f4f738..ef82751722e0 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -358,8 +358,13 @@ static int carl9170_op_start(struct ieee80211_hw *hw) | |||
358 | ar->ps.last_action = jiffies; | 358 | ar->ps.last_action = jiffies; |
359 | ar->ps.last_slept = jiffies; | 359 | ar->ps.last_slept = jiffies; |
360 | ar->erp_mode = CARL9170_ERP_AUTO; | 360 | ar->erp_mode = CARL9170_ERP_AUTO; |
361 | ar->rx_software_decryption = false; | 361 | |
362 | ar->disable_offload = false; | 362 | /* Set "disable hw crypto offload" whenever the module parameter |
363 | * nohwcrypt is true or if the firmware does not support it. | ||
364 | */ | ||
365 | ar->disable_offload = modparam_nohwcrypt | | ||
366 | ar->fw.disable_offload_fw; | ||
367 | ar->rx_software_decryption = ar->disable_offload; | ||
363 | 368 | ||
364 | for (i = 0; i < ar->hw->queues; i++) { | 369 | for (i = 0; i < ar->hw->queues; i++) { |
365 | ar->queue_stop_timeout[i] = jiffies; | 370 | ar->queue_stop_timeout[i] = jiffies; |
@@ -565,12 +570,28 @@ static int carl9170_init_interface(struct ar9170 *ar, | |||
565 | 570 | ||
566 | memcpy(common->macaddr, vif->addr, ETH_ALEN); | 571 | memcpy(common->macaddr, vif->addr, ETH_ALEN); |
567 | 572 | ||
568 | if (modparam_nohwcrypt || | 573 | /* We have to fall back to software crypto, whenever |
569 | ((vif->type != NL80211_IFTYPE_STATION) && | 574 | * the user choose to participates in an IBSS. HW |
570 | (vif->type != NL80211_IFTYPE_AP))) { | 575 | * offload for IBSS RSN is not supported by this driver. |
571 | ar->rx_software_decryption = true; | 576 | * |
572 | ar->disable_offload = true; | 577 | * NOTE: If the previous main interface has already |
573 | } | 578 | * disabled hw crypto offload, we have to keep this |
579 | * previous disable_offload setting as it was. | ||
580 | * Altough ideally, we should notify mac80211 and tell | ||
581 | * it to forget about any HW crypto offload for now. | ||
582 | */ | ||
583 | ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) && | ||
584 | (vif->type != NL80211_IFTYPE_AP)); | ||
585 | |||
586 | /* While the driver supports HW offload in a single | ||
587 | * P2P client configuration, it doesn't support HW | ||
588 | * offload in the favourit, concurrent P2P GO+CLIENT | ||
589 | * configuration. Hence, HW offload will always be | ||
590 | * disabled for P2P. | ||
591 | */ | ||
592 | ar->disable_offload |= vif->p2p; | ||
593 | |||
594 | ar->rx_software_decryption = ar->disable_offload; | ||
574 | 595 | ||
575 | err = carl9170_set_operating_mode(ar); | 596 | err = carl9170_set_operating_mode(ar); |
576 | return err; | 597 | return err; |
@@ -580,7 +601,7 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
580 | struct ieee80211_vif *vif) | 601 | struct ieee80211_vif *vif) |
581 | { | 602 | { |
582 | struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; | 603 | struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; |
583 | struct ieee80211_vif *main_vif; | 604 | struct ieee80211_vif *main_vif, *old_main = NULL; |
584 | struct ar9170 *ar = hw->priv; | 605 | struct ar9170 *ar = hw->priv; |
585 | int vif_id = -1, err = 0; | 606 | int vif_id = -1, err = 0; |
586 | 607 | ||
@@ -602,6 +623,15 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
602 | goto init; | 623 | goto init; |
603 | } | 624 | } |
604 | 625 | ||
626 | /* Because the AR9170 HW's MAC doesn't provide full support for | ||
627 | * multiple, independent interfaces [of different operation modes]. | ||
628 | * We have to select ONE main interface [main mode of HW], but we | ||
629 | * can have multiple slaves [AKA: entry in the ACK-table]. | ||
630 | * | ||
631 | * The first (from HEAD/TOP) interface in the ar->vif_list is | ||
632 | * always the main intf. All following intfs in this list | ||
633 | * are considered to be slave intfs. | ||
634 | */ | ||
605 | main_vif = carl9170_get_main_vif(ar); | 635 | main_vif = carl9170_get_main_vif(ar); |
606 | 636 | ||
607 | if (main_vif) { | 637 | if (main_vif) { |
@@ -610,6 +640,18 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
610 | if (vif->type == NL80211_IFTYPE_STATION) | 640 | if (vif->type == NL80211_IFTYPE_STATION) |
611 | break; | 641 | break; |
612 | 642 | ||
643 | /* P2P GO [master] use-case | ||
644 | * Because the P2P GO station is selected dynamically | ||
645 | * by all participating peers of a WIFI Direct network, | ||
646 | * the driver has be able to change the main interface | ||
647 | * operating mode on the fly. | ||
648 | */ | ||
649 | if (main_vif->p2p && vif->p2p && | ||
650 | vif->type == NL80211_IFTYPE_AP) { | ||
651 | old_main = main_vif; | ||
652 | break; | ||
653 | } | ||
654 | |||
613 | err = -EBUSY; | 655 | err = -EBUSY; |
614 | rcu_read_unlock(); | 656 | rcu_read_unlock(); |
615 | 657 | ||
@@ -648,14 +690,41 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, | |||
648 | vif_priv->id = vif_id; | 690 | vif_priv->id = vif_id; |
649 | vif_priv->enable_beacon = false; | 691 | vif_priv->enable_beacon = false; |
650 | ar->vifs++; | 692 | ar->vifs++; |
651 | list_add_tail_rcu(&vif_priv->list, &ar->vif_list); | 693 | if (old_main) { |
694 | /* We end up in here, if the main interface is being replaced. | ||
695 | * Put the new main interface at the HEAD of the list and the | ||
696 | * previous inteface will automatically become second in line. | ||
697 | */ | ||
698 | list_add_rcu(&vif_priv->list, &ar->vif_list); | ||
699 | } else { | ||
700 | /* Add new inteface. If the list is empty, it will become the | ||
701 | * main inteface, otherwise it will be slave. | ||
702 | */ | ||
703 | list_add_tail_rcu(&vif_priv->list, &ar->vif_list); | ||
704 | } | ||
652 | rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); | 705 | rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); |
653 | 706 | ||
654 | init: | 707 | init: |
655 | if (carl9170_get_main_vif(ar) == vif) { | 708 | main_vif = carl9170_get_main_vif(ar); |
709 | |||
710 | if (main_vif == vif) { | ||
656 | rcu_assign_pointer(ar->beacon_iter, vif_priv); | 711 | rcu_assign_pointer(ar->beacon_iter, vif_priv); |
657 | rcu_read_unlock(); | 712 | rcu_read_unlock(); |
658 | 713 | ||
714 | if (old_main) { | ||
715 | struct carl9170_vif_info *old_main_priv = | ||
716 | (void *) old_main->drv_priv; | ||
717 | /* downgrade old main intf to slave intf. | ||
718 | * NOTE: We are no longer under rcu_read_lock. | ||
719 | * But we are still holding ar->mutex, so the | ||
720 | * vif data [id, addr] is safe. | ||
721 | */ | ||
722 | err = carl9170_mod_virtual_mac(ar, old_main_priv->id, | ||
723 | old_main->addr); | ||
724 | if (err) | ||
725 | goto unlock; | ||
726 | } | ||
727 | |||
659 | err = carl9170_init_interface(ar, vif); | 728 | err = carl9170_init_interface(ar, vif); |
660 | if (err) | 729 | if (err) |
661 | goto unlock; | 730 | goto unlock; |
@@ -1112,9 +1181,7 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1112 | if (ar->disable_offload || !vif) | 1181 | if (ar->disable_offload || !vif) |
1113 | return -EOPNOTSUPP; | 1182 | return -EOPNOTSUPP; |
1114 | 1183 | ||
1115 | /* | 1184 | /* Fall back to software encryption whenever the driver is connected |
1116 | * We have to fall back to software encryption, whenever | ||
1117 | * the user choose to participates in an IBSS or is connected | ||
1118 | * to more than one network. | 1185 | * to more than one network. |
1119 | * | 1186 | * |
1120 | * This is very unfortunate, because some machines cannot handle | 1187 | * This is very unfortunate, because some machines cannot handle |
@@ -1263,7 +1330,7 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, | |||
1263 | return 0; | 1330 | return 0; |
1264 | } | 1331 | } |
1265 | 1332 | ||
1266 | for (i = 0; i < CARL9170_NUM_TID; i++) | 1333 | for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) |
1267 | RCU_INIT_POINTER(sta_info->agg[i], NULL); | 1334 | RCU_INIT_POINTER(sta_info->agg[i], NULL); |
1268 | 1335 | ||
1269 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); | 1336 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); |
@@ -1287,7 +1354,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, | |||
1287 | sta_info->ht_sta = false; | 1354 | sta_info->ht_sta = false; |
1288 | 1355 | ||
1289 | rcu_read_lock(); | 1356 | rcu_read_lock(); |
1290 | for (i = 0; i < CARL9170_NUM_TID; i++) { | 1357 | for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) { |
1291 | struct carl9170_sta_tid *tid_info; | 1358 | struct carl9170_sta_tid *tid_info; |
1292 | 1359 | ||
1293 | tid_info = rcu_dereference(sta_info->agg[i]); | 1360 | tid_info = rcu_dereference(sta_info->agg[i]); |
@@ -1394,7 +1461,9 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, | |||
1394 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1461 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1395 | break; | 1462 | break; |
1396 | 1463 | ||
1397 | case IEEE80211_AMPDU_TX_STOP: | 1464 | case IEEE80211_AMPDU_TX_STOP_CONT: |
1465 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
1466 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
1398 | rcu_read_lock(); | 1467 | rcu_read_lock(); |
1399 | tid_info = rcu_dereference(sta_info->agg[tid]); | 1468 | tid_info = rcu_dereference(sta_info->agg[tid]); |
1400 | if (tid_info) { | 1469 | if (tid_info) { |
@@ -1805,10 +1874,6 @@ void *carl9170_alloc(size_t priv_size) | |||
1805 | for (i = 0; i < ARRAY_SIZE(ar->noise); i++) | 1874 | for (i = 0; i < ARRAY_SIZE(ar->noise); i++) |
1806 | ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ | 1875 | ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ |
1807 | 1876 | ||
1808 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1809 | |||
1810 | /* As IBSS Encryption is software-based, IBSS RSN is supported. */ | ||
1811 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | ||
1812 | return ar; | 1877 | return ar; |
1813 | 1878 | ||
1814 | err_nomem: | 1879 | err_nomem: |
@@ -1916,13 +1981,13 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) | |||
1916 | return 0; | 1981 | return 0; |
1917 | } | 1982 | } |
1918 | 1983 | ||
1919 | static int carl9170_reg_notifier(struct wiphy *wiphy, | 1984 | static void carl9170_reg_notifier(struct wiphy *wiphy, |
1920 | struct regulatory_request *request) | 1985 | struct regulatory_request *request) |
1921 | { | 1986 | { |
1922 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 1987 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
1923 | struct ar9170 *ar = hw->priv; | 1988 | struct ar9170 *ar = hw->priv; |
1924 | 1989 | ||
1925 | return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); | 1990 | ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); |
1926 | } | 1991 | } |
1927 | 1992 | ||
1928 | int carl9170_register(struct ar9170 *ar) | 1993 | int carl9170_register(struct ar9170 *ar) |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index ef4ec0da6e49..9c0b150d5b8e 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -1520,35 +1520,92 @@ void carl9170_tx_scheduler(struct ar9170 *ar) | |||
1520 | carl9170_tx(ar); | 1520 | carl9170_tx(ar); |
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | int carl9170_update_beacon(struct ar9170 *ar, const bool submit) | 1523 | /* caller has to take rcu_read_lock */ |
1524 | static struct carl9170_vif_info *carl9170_pick_beaconing_vif(struct ar9170 *ar) | ||
1524 | { | 1525 | { |
1525 | struct sk_buff *skb = NULL; | ||
1526 | struct carl9170_vif_info *cvif; | 1526 | struct carl9170_vif_info *cvif; |
1527 | int i = 1; | ||
1528 | |||
1529 | /* The AR9170 hardware has no fancy beacon queue or some | ||
1530 | * other scheduling mechanism. So, the driver has to make | ||
1531 | * due by setting the two beacon timers (pretbtt and tbtt) | ||
1532 | * once and then swapping the beacon address in the HW's | ||
1533 | * register file each time the pretbtt fires. | ||
1534 | */ | ||
1535 | |||
1536 | cvif = rcu_dereference(ar->beacon_iter); | ||
1537 | if (ar->vifs > 0 && cvif) { | ||
1538 | do { | ||
1539 | list_for_each_entry_continue_rcu(cvif, &ar->vif_list, | ||
1540 | list) { | ||
1541 | if (cvif->active && cvif->enable_beacon) | ||
1542 | goto out; | ||
1543 | } | ||
1544 | } while (ar->beacon_enabled && i--); | ||
1545 | } | ||
1546 | |||
1547 | out: | ||
1548 | rcu_assign_pointer(ar->beacon_iter, cvif); | ||
1549 | return cvif; | ||
1550 | } | ||
1551 | |||
1552 | static bool carl9170_tx_beacon_physet(struct ar9170 *ar, struct sk_buff *skb, | ||
1553 | u32 *ht1, u32 *plcp) | ||
1554 | { | ||
1527 | struct ieee80211_tx_info *txinfo; | 1555 | struct ieee80211_tx_info *txinfo; |
1528 | struct ieee80211_tx_rate *rate; | 1556 | struct ieee80211_tx_rate *rate; |
1529 | __le32 *data, *old = NULL; | 1557 | unsigned int power, chains; |
1530 | unsigned int plcp, power, chains; | 1558 | bool ht_rate; |
1531 | u32 word, ht1, off, addr, len; | ||
1532 | int i = 0, err = 0; | ||
1533 | 1559 | ||
1534 | rcu_read_lock(); | 1560 | txinfo = IEEE80211_SKB_CB(skb); |
1535 | cvif = rcu_dereference(ar->beacon_iter); | 1561 | rate = &txinfo->control.rates[0]; |
1536 | retry: | 1562 | ht_rate = !!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS); |
1537 | if (ar->vifs == 0 || !cvif) | 1563 | carl9170_tx_rate_tpc_chains(ar, txinfo, rate, plcp, &power, &chains); |
1538 | goto out_unlock; | ||
1539 | 1564 | ||
1540 | list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) { | 1565 | *ht1 = AR9170_MAC_BCN_HT1_TX_ANT0; |
1541 | if (cvif->active && cvif->enable_beacon) | 1566 | if (chains == AR9170_TX_PHY_TXCHAIN_2) |
1542 | goto found; | 1567 | *ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1; |
1568 | SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, *ht1, 7); | ||
1569 | SET_VAL(AR9170_MAC_BCN_HT1_TPC, *ht1, power); | ||
1570 | SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, *ht1, chains); | ||
1571 | |||
1572 | if (ht_rate) { | ||
1573 | *ht1 |= AR9170_MAC_BCN_HT1_HT_EN; | ||
1574 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
1575 | *plcp |= AR9170_MAC_BCN_HT2_SGI; | ||
1576 | |||
1577 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { | ||
1578 | *ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED; | ||
1579 | *plcp |= AR9170_MAC_BCN_HT2_BW40; | ||
1580 | } else if (rate->flags & IEEE80211_TX_RC_DUP_DATA) { | ||
1581 | *ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP; | ||
1582 | *plcp |= AR9170_MAC_BCN_HT2_BW40; | ||
1583 | } | ||
1584 | |||
1585 | SET_VAL(AR9170_MAC_BCN_HT2_LEN, *plcp, skb->len + FCS_LEN); | ||
1586 | } else { | ||
1587 | if (*plcp <= AR9170_TX_PHY_RATE_CCK_11M) | ||
1588 | *plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400; | ||
1589 | else | ||
1590 | *plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010; | ||
1543 | } | 1591 | } |
1544 | 1592 | ||
1545 | if (!ar->beacon_enabled || i++) | 1593 | return ht_rate; |
1546 | goto out_unlock; | 1594 | } |
1547 | 1595 | ||
1548 | goto retry; | 1596 | int carl9170_update_beacon(struct ar9170 *ar, const bool submit) |
1597 | { | ||
1598 | struct sk_buff *skb = NULL; | ||
1599 | struct carl9170_vif_info *cvif; | ||
1600 | __le32 *data, *old = NULL; | ||
1601 | u32 word, ht1, plcp, off, addr, len; | ||
1602 | int i = 0, err = 0; | ||
1603 | bool ht_rate; | ||
1549 | 1604 | ||
1550 | found: | 1605 | rcu_read_lock(); |
1551 | rcu_assign_pointer(ar->beacon_iter, cvif); | 1606 | cvif = carl9170_pick_beaconing_vif(ar); |
1607 | if (!cvif) | ||
1608 | goto out_unlock; | ||
1552 | 1609 | ||
1553 | skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif), | 1610 | skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif), |
1554 | NULL, NULL); | 1611 | NULL, NULL); |
@@ -1558,7 +1615,6 @@ found: | |||
1558 | goto err_free; | 1615 | goto err_free; |
1559 | } | 1616 | } |
1560 | 1617 | ||
1561 | txinfo = IEEE80211_SKB_CB(skb); | ||
1562 | spin_lock_bh(&ar->beacon_lock); | 1618 | spin_lock_bh(&ar->beacon_lock); |
1563 | data = (__le32 *)skb->data; | 1619 | data = (__le32 *)skb->data; |
1564 | if (cvif->beacon) | 1620 | if (cvif->beacon) |
@@ -1588,43 +1644,14 @@ found: | |||
1588 | goto err_unlock; | 1644 | goto err_unlock; |
1589 | } | 1645 | } |
1590 | 1646 | ||
1591 | ht1 = AR9170_MAC_BCN_HT1_TX_ANT0; | 1647 | ht_rate = carl9170_tx_beacon_physet(ar, skb, &ht1, &plcp); |
1592 | rate = &txinfo->control.rates[0]; | ||
1593 | carl9170_tx_rate_tpc_chains(ar, txinfo, rate, &plcp, &power, &chains); | ||
1594 | if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) { | ||
1595 | if (plcp <= AR9170_TX_PHY_RATE_CCK_11M) | ||
1596 | plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400; | ||
1597 | else | ||
1598 | plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010; | ||
1599 | } else { | ||
1600 | ht1 |= AR9170_MAC_BCN_HT1_HT_EN; | ||
1601 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
1602 | plcp |= AR9170_MAC_BCN_HT2_SGI; | ||
1603 | |||
1604 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { | ||
1605 | ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED; | ||
1606 | plcp |= AR9170_MAC_BCN_HT2_BW40; | ||
1607 | } | ||
1608 | if (rate->flags & IEEE80211_TX_RC_DUP_DATA) { | ||
1609 | ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP; | ||
1610 | plcp |= AR9170_MAC_BCN_HT2_BW40; | ||
1611 | } | ||
1612 | |||
1613 | SET_VAL(AR9170_MAC_BCN_HT2_LEN, plcp, skb->len + FCS_LEN); | ||
1614 | } | ||
1615 | |||
1616 | SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, ht1, 7); | ||
1617 | SET_VAL(AR9170_MAC_BCN_HT1_TPC, ht1, power); | ||
1618 | SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, ht1, chains); | ||
1619 | if (chains == AR9170_TX_PHY_TXCHAIN_2) | ||
1620 | ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1; | ||
1621 | 1648 | ||
1622 | carl9170_async_regwrite_begin(ar); | 1649 | carl9170_async_regwrite_begin(ar); |
1623 | carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1); | 1650 | carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1); |
1624 | if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) | 1651 | if (ht_rate) |
1625 | carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp); | ||
1626 | else | ||
1627 | carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp); | 1652 | carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp); |
1653 | else | ||
1654 | carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp); | ||
1628 | 1655 | ||
1629 | for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { | 1656 | for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { |
1630 | /* | 1657 | /* |
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h index 2ec3e9191e4d..2282847d4bb8 100644 --- a/drivers/net/wireless/ath/carl9170/version.h +++ b/drivers/net/wireless/ath/carl9170/version.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef __CARL9170_SHARED_VERSION_H | 1 | #ifndef __CARL9170_SHARED_VERSION_H |
2 | #define __CARL9170_SHARED_VERSION_H | 2 | #define __CARL9170_SHARED_VERSION_H |
3 | #define CARL9170FW_VERSION_YEAR 12 | 3 | #define CARL9170FW_VERSION_YEAR 12 |
4 | #define CARL9170FW_VERSION_MONTH 7 | 4 | #define CARL9170FW_VERSION_MONTH 12 |
5 | #define CARL9170FW_VERSION_DAY 7 | 5 | #define CARL9170FW_VERSION_DAY 15 |
6 | #define CARL9170FW_VERSION_GIT "1.9.6" | 6 | #define CARL9170FW_VERSION_GIT "1.9.7" |
7 | #endif /* __CARL9170_SHARED_VERSION_H */ | 7 | #endif /* __CARL9170_SHARED_VERSION_H */ |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index d81698015bf7..ccc4c718f124 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -195,8 +195,6 @@ ath_reg_apply_beaconing_flags(struct wiphy *wiphy, | |||
195 | const struct ieee80211_reg_rule *reg_rule; | 195 | const struct ieee80211_reg_rule *reg_rule; |
196 | struct ieee80211_channel *ch; | 196 | struct ieee80211_channel *ch; |
197 | unsigned int i; | 197 | unsigned int i; |
198 | u32 bandwidth = 0; | ||
199 | int r; | ||
200 | 198 | ||
201 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 199 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
202 | 200 | ||
@@ -214,11 +212,8 @@ ath_reg_apply_beaconing_flags(struct wiphy *wiphy, | |||
214 | continue; | 212 | continue; |
215 | 213 | ||
216 | if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { | 214 | if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { |
217 | r = freq_reg_info(wiphy, | 215 | reg_rule = freq_reg_info(wiphy, ch->center_freq); |
218 | ch->center_freq, | 216 | if (IS_ERR(reg_rule)) |
219 | bandwidth, | ||
220 | ®_rule); | ||
221 | if (r) | ||
222 | continue; | 217 | continue; |
223 | /* | 218 | /* |
224 | * If 11d had a rule for this channel ensure | 219 | * If 11d had a rule for this channel ensure |
@@ -254,8 +249,6 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy, | |||
254 | struct ieee80211_supported_band *sband; | 249 | struct ieee80211_supported_band *sband; |
255 | struct ieee80211_channel *ch; | 250 | struct ieee80211_channel *ch; |
256 | const struct ieee80211_reg_rule *reg_rule; | 251 | const struct ieee80211_reg_rule *reg_rule; |
257 | u32 bandwidth = 0; | ||
258 | int r; | ||
259 | 252 | ||
260 | sband = wiphy->bands[IEEE80211_BAND_2GHZ]; | 253 | sband = wiphy->bands[IEEE80211_BAND_2GHZ]; |
261 | if (!sband) | 254 | if (!sband) |
@@ -283,16 +276,16 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy, | |||
283 | */ | 276 | */ |
284 | 277 | ||
285 | ch = &sband->channels[11]; /* CH 12 */ | 278 | ch = &sband->channels[11]; /* CH 12 */ |
286 | r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); | 279 | reg_rule = freq_reg_info(wiphy, ch->center_freq); |
287 | if (!r) { | 280 | if (!IS_ERR(reg_rule)) { |
288 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) | 281 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) |
289 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 282 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
290 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | 283 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; |
291 | } | 284 | } |
292 | 285 | ||
293 | ch = &sband->channels[12]; /* CH 13 */ | 286 | ch = &sband->channels[12]; /* CH 13 */ |
294 | r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); | 287 | reg_rule = freq_reg_info(wiphy, ch->center_freq); |
295 | if (!r) { | 288 | if (!IS_ERR(reg_rule)) { |
296 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) | 289 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) |
297 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 290 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
298 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | 291 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; |
@@ -363,9 +356,9 @@ static u16 ath_regd_find_country_by_name(char *alpha2) | |||
363 | return -1; | 356 | return -1; |
364 | } | 357 | } |
365 | 358 | ||
366 | int ath_reg_notifier_apply(struct wiphy *wiphy, | 359 | void ath_reg_notifier_apply(struct wiphy *wiphy, |
367 | struct regulatory_request *request, | 360 | struct regulatory_request *request, |
368 | struct ath_regulatory *reg) | 361 | struct ath_regulatory *reg) |
369 | { | 362 | { |
370 | struct ath_common *common = container_of(reg, struct ath_common, | 363 | struct ath_common *common = container_of(reg, struct ath_common, |
371 | regulatory); | 364 | regulatory); |
@@ -380,7 +373,7 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, | |||
380 | * any pending requests in the queue. | 373 | * any pending requests in the queue. |
381 | */ | 374 | */ |
382 | if (!request) | 375 | if (!request) |
383 | return 0; | 376 | return; |
384 | 377 | ||
385 | switch (request->initiator) { | 378 | switch (request->initiator) { |
386 | case NL80211_REGDOM_SET_BY_CORE: | 379 | case NL80211_REGDOM_SET_BY_CORE: |
@@ -416,8 +409,6 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, | |||
416 | 409 | ||
417 | break; | 410 | break; |
418 | } | 411 | } |
419 | |||
420 | return 0; | ||
421 | } | 412 | } |
422 | EXPORT_SYMBOL(ath_reg_notifier_apply); | 413 | EXPORT_SYMBOL(ath_reg_notifier_apply); |
423 | 414 | ||
@@ -507,8 +498,8 @@ ath_get_regpair(int regdmn) | |||
507 | static int | 498 | static int |
508 | ath_regd_init_wiphy(struct ath_regulatory *reg, | 499 | ath_regd_init_wiphy(struct ath_regulatory *reg, |
509 | struct wiphy *wiphy, | 500 | struct wiphy *wiphy, |
510 | int (*reg_notifier)(struct wiphy *wiphy, | 501 | void (*reg_notifier)(struct wiphy *wiphy, |
511 | struct regulatory_request *request)) | 502 | struct regulatory_request *request)) |
512 | { | 503 | { |
513 | const struct ieee80211_regdomain *regd; | 504 | const struct ieee80211_regdomain *regd; |
514 | 505 | ||
@@ -628,8 +619,8 @@ static int __ath_regd_init(struct ath_regulatory *reg) | |||
628 | int | 619 | int |
629 | ath_regd_init(struct ath_regulatory *reg, | 620 | ath_regd_init(struct ath_regulatory *reg, |
630 | struct wiphy *wiphy, | 621 | struct wiphy *wiphy, |
631 | int (*reg_notifier)(struct wiphy *wiphy, | 622 | void (*reg_notifier)(struct wiphy *wiphy, |
632 | struct regulatory_request *request)) | 623 | struct regulatory_request *request)) |
633 | { | 624 | { |
634 | struct ath_common *common = container_of(reg, struct ath_common, | 625 | struct ath_common *common = container_of(reg, struct ath_common, |
635 | regulatory); | 626 | regulatory); |
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index 03a8268ccf21..37f53bd8fcb1 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h | |||
@@ -252,12 +252,12 @@ enum CountryCode { | |||
252 | bool ath_is_world_regd(struct ath_regulatory *reg); | 252 | bool ath_is_world_regd(struct ath_regulatory *reg); |
253 | bool ath_is_49ghz_allowed(u16 redomain); | 253 | bool ath_is_49ghz_allowed(u16 redomain); |
254 | int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, | 254 | int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, |
255 | int (*reg_notifier)(struct wiphy *wiphy, | 255 | void (*reg_notifier)(struct wiphy *wiphy, |
256 | struct regulatory_request *request)); | 256 | struct regulatory_request *request)); |
257 | u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, | 257 | u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, |
258 | enum ieee80211_band band); | 258 | enum ieee80211_band band); |
259 | int ath_reg_notifier_apply(struct wiphy *wiphy, | 259 | void ath_reg_notifier_apply(struct wiphy *wiphy, |
260 | struct regulatory_request *request, | 260 | struct regulatory_request *request, |
261 | struct ath_regulatory *reg); | 261 | struct ath_regulatory *reg); |
262 | 262 | ||
263 | #endif | 263 | #endif |
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 97d4e27bf36f..aaca60c6f575 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c | |||
@@ -3226,8 +3226,6 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | |||
3226 | { | 3226 | { |
3227 | struct nphy_gain_ctl_workaround_entry *e; | 3227 | struct nphy_gain_ctl_workaround_entry *e; |
3228 | u8 phy_idx; | 3228 | u8 phy_idx; |
3229 | u8 tr_iso = ghz5 ? dev->dev->bus_sprom->fem.ghz5.tr_iso : | ||
3230 | dev->dev->bus_sprom->fem.ghz2.tr_iso; | ||
3231 | 3229 | ||
3232 | if (!ghz5 && dev->phy.rev >= 6 && dev->phy.radio_rev == 11) | 3230 | if (!ghz5 && dev->phy.rev >= 6 && dev->phy.radio_rev == 11) |
3233 | return &nphy_gain_ctl_wa_phy6_radio11_ghz2; | 3231 | return &nphy_gain_ctl_wa_phy6_radio11_ghz2; |
@@ -3249,6 +3247,10 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | |||
3249 | !b43_channel_type_is_40mhz(dev->phy.channel_type)) | 3247 | !b43_channel_type_is_40mhz(dev->phy.channel_type)) |
3250 | e->cliplo_gain = 0x2d; | 3248 | e->cliplo_gain = 0x2d; |
3251 | } else if (!ghz5 && dev->phy.rev >= 5) { | 3249 | } else if (!ghz5 && dev->phy.rev >= 5) { |
3250 | static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a, | ||
3251 | 0x106c, 0x1074, 0x107c, 0x207c}; | ||
3252 | u8 tr_iso = dev->dev->bus_sprom->fem.ghz2.tr_iso; | ||
3253 | |||
3252 | if (ext_lna) { | 3254 | if (ext_lna) { |
3253 | e->rfseq_init[0] &= ~0x4000; | 3255 | e->rfseq_init[0] &= ~0x4000; |
3254 | e->rfseq_init[1] &= ~0x4000; | 3256 | e->rfseq_init[1] &= ~0x4000; |
@@ -3256,26 +3258,10 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | |||
3256 | e->rfseq_init[3] &= ~0x4000; | 3258 | e->rfseq_init[3] &= ~0x4000; |
3257 | e->init_gain &= ~0x4000; | 3259 | e->init_gain &= ~0x4000; |
3258 | } | 3260 | } |
3259 | switch (tr_iso) { | 3261 | if (tr_iso > 7) |
3260 | case 0: | 3262 | tr_iso = 3; |
3261 | e->cliplo_gain = 0x0062; | 3263 | e->cliplo_gain = gain_data[tr_iso]; |
3262 | case 1: | 3264 | |
3263 | e->cliplo_gain = 0x0064; | ||
3264 | case 2: | ||
3265 | e->cliplo_gain = 0x006a; | ||
3266 | case 3: | ||
3267 | e->cliplo_gain = 0x106a; | ||
3268 | case 4: | ||
3269 | e->cliplo_gain = 0x106c; | ||
3270 | case 5: | ||
3271 | e->cliplo_gain = 0x1074; | ||
3272 | case 6: | ||
3273 | e->cliplo_gain = 0x107c; | ||
3274 | case 7: | ||
3275 | e->cliplo_gain = 0x207c; | ||
3276 | default: | ||
3277 | e->cliplo_gain = 0x106a; | ||
3278 | } | ||
3279 | } else if (ghz5 && dev->phy.rev == 4 && ext_lna) { | 3265 | } else if (ghz5 && dev->phy.rev == 4 && ext_lna) { |
3280 | e->rfseq_init[0] &= ~0x4000; | 3266 | e->rfseq_init[0] &= ~0x4000; |
3281 | e->rfseq_init[1] &= ~0x4000; | 3267 | e->rfseq_init[1] &= ~0x4000; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index be35a2f99b1c..11fd1c735589 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -15,8 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | /* ****************** SDIO CARD Interface Functions **************************/ | 16 | /* ****************** SDIO CARD Interface Functions **************************/ |
17 | 17 | ||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
19 | |||
20 | #include <linux/types.h> | 18 | #include <linux/types.h> |
21 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
22 | #include <linux/export.h> | 20 | #include <linux/export.h> |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index d33e5598611b..d92d373733d7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -14,8 +14,6 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
19 | #include <linux/types.h> | 17 | #include <linux/types.h> |
20 | #include <linux/netdevice.h> | 18 | #include <linux/netdevice.h> |
21 | #include <linux/mmc/sdio.h> | 19 | #include <linux/mmc/sdio.h> |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index fd672bf53867..a2f32fb990fa 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define BRCMF_C_GET_BSSID 23 | 39 | #define BRCMF_C_GET_BSSID 23 |
40 | #define BRCMF_C_GET_SSID 25 | 40 | #define BRCMF_C_GET_SSID 25 |
41 | #define BRCMF_C_SET_SSID 26 | 41 | #define BRCMF_C_SET_SSID 26 |
42 | #define BRCMF_C_TERMINATED 28 | ||
42 | #define BRCMF_C_GET_CHANNEL 29 | 43 | #define BRCMF_C_GET_CHANNEL 29 |
43 | #define BRCMF_C_SET_CHANNEL 30 | 44 | #define BRCMF_C_SET_CHANNEL 30 |
44 | #define BRCMF_C_GET_SRL 31 | 45 | #define BRCMF_C_GET_SRL 31 |
@@ -480,36 +481,14 @@ struct brcmf_pub { | |||
480 | unsigned long drv_version; /* Version of dongle-resident driver */ | 481 | unsigned long drv_version; /* Version of dongle-resident driver */ |
481 | u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ | 482 | u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ |
482 | 483 | ||
483 | /* Additional stats for the bus level */ | ||
484 | |||
485 | /* Multicast data packets sent to dongle */ | 484 | /* Multicast data packets sent to dongle */ |
486 | unsigned long tx_multicast; | 485 | unsigned long tx_multicast; |
487 | /* Packets flushed due to unscheduled sendup thread */ | ||
488 | unsigned long rx_flushed; | ||
489 | /* Number of times dpc scheduled by watchdog timer */ | ||
490 | unsigned long wd_dpc_sched; | ||
491 | |||
492 | /* Number of flow control pkts recvd */ | ||
493 | unsigned long fc_packets; | ||
494 | |||
495 | /* Last error return */ | ||
496 | int bcmerror; | ||
497 | |||
498 | /* Last error from dongle */ | ||
499 | int dongle_error; | ||
500 | |||
501 | /* Suspend disable flag flag */ | ||
502 | int suspend_disable_flag; /* "1" to disable all extra powersaving | ||
503 | during suspend */ | ||
504 | int in_suspend; /* flag set to 1 when early suspend called */ | ||
505 | int dtim_skip; /* dtim skip , default 0 means wake each dtim */ | ||
506 | 486 | ||
507 | struct brcmf_if *iflist[BRCMF_MAX_IFS]; | 487 | struct brcmf_if *iflist[BRCMF_MAX_IFS]; |
508 | 488 | ||
509 | struct mutex proto_block; | 489 | struct mutex proto_block; |
510 | unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; | 490 | unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; |
511 | 491 | ||
512 | u8 macvalue[ETH_ALEN]; | ||
513 | atomic_t pend_8021x_cnt; | 492 | atomic_t pend_8021x_cnt; |
514 | wait_queue_head_t pend_8021x_wait; | 493 | wait_queue_head_t pend_8021x_wait; |
515 | 494 | ||
@@ -519,11 +498,6 @@ struct brcmf_pub { | |||
519 | #endif | 498 | #endif |
520 | }; | 499 | }; |
521 | 500 | ||
522 | struct bcmevent_name { | ||
523 | uint event; | ||
524 | const char *name; | ||
525 | }; | ||
526 | |||
527 | struct brcmf_if_event { | 501 | struct brcmf_if_event { |
528 | u8 ifidx; | 502 | u8 ifidx; |
529 | u8 action; | 503 | u8 action; |
@@ -557,13 +531,6 @@ struct brcmf_if { | |||
557 | u8 mac_addr[ETH_ALEN]; | 531 | u8 mac_addr[ETH_ALEN]; |
558 | }; | 532 | }; |
559 | 533 | ||
560 | static inline s32 brcmf_ndev_bssidx(struct net_device *ndev) | ||
561 | { | ||
562 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
563 | return ifp->bssidx; | ||
564 | } | ||
565 | |||
566 | extern const struct bcmevent_name bcmevent_names[]; | ||
567 | 534 | ||
568 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); | 535 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); |
569 | 536 | ||
@@ -576,6 +543,10 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, | |||
576 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, | 543 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, |
577 | void *buf, uint len); | 544 | void *buf, uint len); |
578 | 545 | ||
546 | /* Remove any protocol-specific data header. */ | ||
547 | extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, | ||
548 | struct sk_buff *rxp); | ||
549 | |||
579 | extern int brcmf_net_attach(struct brcmf_if *ifp); | 550 | extern int brcmf_net_attach(struct brcmf_if *ifp); |
580 | extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, | 551 | extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, |
581 | s32 bssidx, char *name, u8 *mac_addr); | 552 | s32 bssidx, char *name, u8 *mac_addr); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index dd38b78a9726..64c38f4226a3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -130,31 +130,18 @@ int brcmf_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint len) | |||
130 | * interface functions from common layer | 130 | * interface functions from common layer |
131 | */ | 131 | */ |
132 | 132 | ||
133 | /* Remove any protocol-specific data header. */ | ||
134 | extern int brcmf_proto_hdrpull(struct device *dev, int *ifidx, | ||
135 | struct sk_buff *rxp); | ||
136 | |||
137 | extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | 133 | extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
138 | struct sk_buff *pkt, int prec); | 134 | struct sk_buff *pkt, int prec); |
139 | 135 | ||
140 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ | 136 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ |
141 | extern void brcmf_rx_frame(struct device *dev, u8 ifidx, | 137 | extern void brcmf_rx_frames(struct device *dev, struct sk_buff_head *rxlist); |
142 | struct sk_buff_head *rxlist); | ||
143 | static inline void brcmf_rx_packet(struct device *dev, int ifidx, | ||
144 | struct sk_buff *pkt) | ||
145 | { | ||
146 | struct sk_buff_head q; | ||
147 | |||
148 | skb_queue_head_init(&q); | ||
149 | skb_queue_tail(&q, pkt); | ||
150 | brcmf_rx_frame(dev, ifidx, &q); | ||
151 | } | ||
152 | 138 | ||
153 | /* Indication from bus module regarding presence/insertion of dongle. */ | 139 | /* Indication from bus module regarding presence/insertion of dongle. */ |
154 | extern int brcmf_attach(uint bus_hdrlen, struct device *dev); | 140 | extern int brcmf_attach(uint bus_hdrlen, struct device *dev); |
155 | /* Indication from bus module regarding removal/absence of dongle */ | 141 | /* Indication from bus module regarding removal/absence of dongle */ |
156 | extern void brcmf_detach(struct device *dev); | 142 | extern void brcmf_detach(struct device *dev); |
157 | 143 | /* Indication from bus module that dongle should be reset */ | |
144 | extern void brcmf_dev_reset(struct device *dev); | ||
158 | /* Indication from bus module to change flow-control state */ | 145 | /* Indication from bus module to change flow-control state */ |
159 | extern void brcmf_txflowblock(struct device *dev, bool state); | 146 | extern void brcmf_txflowblock(struct device *dev, bool state); |
160 | 147 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index 83923553f1ac..bb454cdab29d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * For certain dcmd codes, the dongle interprets string data from the host. | 19 | * For certain dcmd codes, the dongle interprets string data from the host. |
20 | ******************************************************************************/ | 20 | ******************************************************************************/ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <linux/types.h> | 22 | #include <linux/types.h> |
25 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
26 | 24 | ||
@@ -94,8 +92,6 @@ struct brcmf_proto_bdc_header { | |||
94 | 92 | ||
95 | struct brcmf_proto { | 93 | struct brcmf_proto { |
96 | u16 reqid; | 94 | u16 reqid; |
97 | u8 pending; | ||
98 | u32 lastcmd; | ||
99 | u8 bus_header[BUS_HEADER_LEN]; | 95 | u8 bus_header[BUS_HEADER_LEN]; |
100 | struct brcmf_proto_cdc_dcmd msg; | 96 | struct brcmf_proto_cdc_dcmd msg; |
101 | unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; | 97 | unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; |
@@ -107,7 +103,7 @@ static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) | |||
107 | int len = le32_to_cpu(prot->msg.len) + | 103 | int len = le32_to_cpu(prot->msg.len) + |
108 | sizeof(struct brcmf_proto_cdc_dcmd); | 104 | sizeof(struct brcmf_proto_cdc_dcmd); |
109 | 105 | ||
110 | brcmf_dbg(TRACE, "Enter\n"); | 106 | brcmf_dbg(CDC, "Enter\n"); |
111 | 107 | ||
112 | /* NOTE : cdc->msg.len holds the desired length of the buffer to be | 108 | /* NOTE : cdc->msg.len holds the desired length of the buffer to be |
113 | * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area | 109 | * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area |
@@ -125,7 +121,7 @@ static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) | |||
125 | int ret; | 121 | int ret; |
126 | struct brcmf_proto *prot = drvr->prot; | 122 | struct brcmf_proto *prot = drvr->prot; |
127 | 123 | ||
128 | brcmf_dbg(TRACE, "Enter\n"); | 124 | brcmf_dbg(CDC, "Enter\n"); |
129 | len += sizeof(struct brcmf_proto_cdc_dcmd); | 125 | len += sizeof(struct brcmf_proto_cdc_dcmd); |
130 | do { | 126 | do { |
131 | ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg, | 127 | ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg, |
@@ -147,20 +143,7 @@ brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, | |||
147 | int ret = 0, retries = 0; | 143 | int ret = 0, retries = 0; |
148 | u32 id, flags; | 144 | u32 id, flags; |
149 | 145 | ||
150 | brcmf_dbg(TRACE, "Enter\n"); | 146 | brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); |
151 | brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len); | ||
152 | |||
153 | /* Respond "bcmerror" and "bcmerrorstr" with local cache */ | ||
154 | if (cmd == BRCMF_C_GET_VAR && buf) { | ||
155 | if (!strcmp((char *)buf, "bcmerrorstr")) { | ||
156 | strncpy((char *)buf, "bcm_error", | ||
157 | BCME_STRLEN); | ||
158 | goto done; | ||
159 | } else if (!strcmp((char *)buf, "bcmerror")) { | ||
160 | *(int *)buf = drvr->dongle_error; | ||
161 | goto done; | ||
162 | } | ||
163 | } | ||
164 | 147 | ||
165 | memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); | 148 | memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); |
166 | 149 | ||
@@ -210,11 +193,8 @@ retry: | |||
210 | } | 193 | } |
211 | 194 | ||
212 | /* Check the ERROR flag */ | 195 | /* Check the ERROR flag */ |
213 | if (flags & CDC_DCMD_ERROR) { | 196 | if (flags & CDC_DCMD_ERROR) |
214 | ret = le32_to_cpu(msg->status); | 197 | ret = le32_to_cpu(msg->status); |
215 | /* Cache error from dongle */ | ||
216 | drvr->dongle_error = ret; | ||
217 | } | ||
218 | 198 | ||
219 | done: | 199 | done: |
220 | return ret; | 200 | return ret; |
@@ -228,8 +208,7 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, | |||
228 | int ret = 0; | 208 | int ret = 0; |
229 | u32 flags, id; | 209 | u32 flags, id; |
230 | 210 | ||
231 | brcmf_dbg(TRACE, "Enter\n"); | 211 | brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); |
232 | brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len); | ||
233 | 212 | ||
234 | memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); | 213 | memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); |
235 | 214 | ||
@@ -262,11 +241,8 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, | |||
262 | } | 241 | } |
263 | 242 | ||
264 | /* Check the ERROR flag */ | 243 | /* Check the ERROR flag */ |
265 | if (flags & CDC_DCMD_ERROR) { | 244 | if (flags & CDC_DCMD_ERROR) |
266 | ret = le32_to_cpu(msg->status); | 245 | ret = le32_to_cpu(msg->status); |
267 | /* Cache error from dongle */ | ||
268 | drvr->dongle_error = ret; | ||
269 | } | ||
270 | 246 | ||
271 | done: | 247 | done: |
272 | return ret; | 248 | return ret; |
@@ -287,7 +263,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, | |||
287 | { | 263 | { |
288 | struct brcmf_proto_bdc_header *h; | 264 | struct brcmf_proto_bdc_header *h; |
289 | 265 | ||
290 | brcmf_dbg(TRACE, "Enter\n"); | 266 | brcmf_dbg(CDC, "Enter\n"); |
291 | 267 | ||
292 | /* Push BDC header used to convey priority for buses that don't */ | 268 | /* Push BDC header used to convey priority for buses that don't */ |
293 | 269 | ||
@@ -305,14 +281,12 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, | |||
305 | BDC_SET_IF_IDX(h, ifidx); | 281 | BDC_SET_IF_IDX(h, ifidx); |
306 | } | 282 | } |
307 | 283 | ||
308 | int brcmf_proto_hdrpull(struct device *dev, int *ifidx, | 284 | int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, |
309 | struct sk_buff *pktbuf) | 285 | struct sk_buff *pktbuf) |
310 | { | 286 | { |
311 | struct brcmf_proto_bdc_header *h; | 287 | struct brcmf_proto_bdc_header *h; |
312 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
313 | struct brcmf_pub *drvr = bus_if->drvr; | ||
314 | 288 | ||
315 | brcmf_dbg(TRACE, "Enter\n"); | 289 | brcmf_dbg(CDC, "Enter\n"); |
316 | 290 | ||
317 | /* Pop BDC header used to convey priority for buses that don't */ | 291 | /* Pop BDC header used to convey priority for buses that don't */ |
318 | 292 | ||
@@ -338,7 +312,7 @@ int brcmf_proto_hdrpull(struct device *dev, int *ifidx, | |||
338 | } | 312 | } |
339 | 313 | ||
340 | if (h->flags & BDC_FLAG_SUM_GOOD) { | 314 | if (h->flags & BDC_FLAG_SUM_GOOD) { |
341 | brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n", | 315 | brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n", |
342 | brcmf_ifname(drvr, *ifidx), h->flags); | 316 | brcmf_ifname(drvr, *ifidx), h->flags); |
343 | pkt_set_sum_good(pktbuf, true); | 317 | pkt_set_sum_good(pktbuf, true); |
344 | } | 318 | } |
@@ -348,6 +322,8 @@ int brcmf_proto_hdrpull(struct device *dev, int *ifidx, | |||
348 | skb_pull(pktbuf, BDC_HEADER_LEN); | 322 | skb_pull(pktbuf, BDC_HEADER_LEN); |
349 | skb_pull(pktbuf, h->data_offset << 2); | 323 | skb_pull(pktbuf, h->data_offset << 2); |
350 | 324 | ||
325 | if (pktbuf->len == 0) | ||
326 | return -ENODATA; | ||
351 | return 0; | 327 | return 0; |
352 | } | 328 | } |
353 | 329 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index f8b52e5b941a..4544342a0428 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -14,8 +14,6 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
19 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
20 | #include <linux/string.h> | 18 | #include <linux/string.h> |
21 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index f2ab01cd7966..bc013cbe06f6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | |||
@@ -18,21 +18,26 @@ | |||
18 | #define _BRCMF_DBG_H_ | 18 | #define _BRCMF_DBG_H_ |
19 | 19 | ||
20 | /* message levels */ | 20 | /* message levels */ |
21 | #define BRCMF_TRACE_VAL 0x0002 | 21 | #define BRCMF_TRACE_VAL 0x00000002 |
22 | #define BRCMF_INFO_VAL 0x0004 | 22 | #define BRCMF_INFO_VAL 0x00000004 |
23 | #define BRCMF_DATA_VAL 0x0008 | 23 | #define BRCMF_DATA_VAL 0x00000008 |
24 | #define BRCMF_CTL_VAL 0x0010 | 24 | #define BRCMF_CTL_VAL 0x00000010 |
25 | #define BRCMF_TIMER_VAL 0x0020 | 25 | #define BRCMF_TIMER_VAL 0x00000020 |
26 | #define BRCMF_HDRS_VAL 0x0040 | 26 | #define BRCMF_HDRS_VAL 0x00000040 |
27 | #define BRCMF_BYTES_VAL 0x0080 | 27 | #define BRCMF_BYTES_VAL 0x00000080 |
28 | #define BRCMF_INTR_VAL 0x0100 | 28 | #define BRCMF_INTR_VAL 0x00000100 |
29 | #define BRCMF_GLOM_VAL 0x0200 | 29 | #define BRCMF_GLOM_VAL 0x00000200 |
30 | #define BRCMF_EVENT_VAL 0x0400 | 30 | #define BRCMF_EVENT_VAL 0x00000400 |
31 | #define BRCMF_BTA_VAL 0x0800 | 31 | #define BRCMF_BTA_VAL 0x00000800 |
32 | #define BRCMF_FIL_VAL 0x1000 | 32 | #define BRCMF_FIL_VAL 0x00001000 |
33 | #define BRCMF_USB_VAL 0x2000 | 33 | #define BRCMF_USB_VAL 0x00002000 |
34 | #define BRCMF_SCAN_VAL 0x4000 | 34 | #define BRCMF_SCAN_VAL 0x00004000 |
35 | #define BRCMF_CONN_VAL 0x8000 | 35 | #define BRCMF_CONN_VAL 0x00008000 |
36 | #define BRCMF_CDC_VAL 0x00010000 | ||
37 | |||
38 | /* set default print format */ | ||
39 | #undef pr_fmt | ||
40 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
36 | 41 | ||
37 | /* Macro for error messages. net_ratelimit() is used when driver | 42 | /* Macro for error messages. net_ratelimit() is used when driver |
38 | * debugging is not selected. When debugging the driver error | 43 | * debugging is not selected. When debugging the driver error |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 8c28a1518409..14b8fdde6954 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -14,8 +14,6 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
19 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
20 | #include <linux/etherdevice.h> | 18 | #include <linux/etherdevice.h> |
21 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -162,28 +160,31 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev) | |||
162 | schedule_work(&ifp->multicast_work); | 160 | schedule_work(&ifp->multicast_work); |
163 | } | 161 | } |
164 | 162 | ||
165 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 163 | static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, |
164 | struct net_device *ndev) | ||
166 | { | 165 | { |
167 | int ret; | 166 | int ret; |
168 | struct brcmf_if *ifp = netdev_priv(ndev); | 167 | struct brcmf_if *ifp = netdev_priv(ndev); |
169 | struct brcmf_pub *drvr = ifp->drvr; | 168 | struct brcmf_pub *drvr = ifp->drvr; |
169 | struct ethhdr *eh; | ||
170 | 170 | ||
171 | brcmf_dbg(TRACE, "Enter\n"); | 171 | brcmf_dbg(TRACE, "Enter\n"); |
172 | 172 | ||
173 | /* Reject if down */ | 173 | /* Can the device send data? */ |
174 | if (!drvr->bus_if->drvr_up || | 174 | if (drvr->bus_if->state != BRCMF_BUS_DATA) { |
175 | (drvr->bus_if->state != BRCMF_BUS_DATA)) { | 175 | brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state); |
176 | brcmf_err("xmit rejected drvup=%d state=%d\n", | ||
177 | drvr->bus_if->drvr_up, | ||
178 | drvr->bus_if->state); | ||
179 | netif_stop_queue(ndev); | 176 | netif_stop_queue(ndev); |
180 | return -ENODEV; | 177 | dev_kfree_skb(skb); |
178 | ret = -ENODEV; | ||
179 | goto done; | ||
181 | } | 180 | } |
182 | 181 | ||
183 | if (!drvr->iflist[ifp->idx]) { | 182 | if (!drvr->iflist[ifp->idx]) { |
184 | brcmf_err("bad ifidx %d\n", ifp->idx); | 183 | brcmf_err("bad ifidx %d\n", ifp->idx); |
185 | netif_stop_queue(ndev); | 184 | netif_stop_queue(ndev); |
186 | return -ENODEV; | 185 | dev_kfree_skb(skb); |
186 | ret = -ENODEV; | ||
187 | goto done; | ||
187 | } | 188 | } |
188 | 189 | ||
189 | /* Make sure there's enough room for any header */ | 190 | /* Make sure there's enough room for any header */ |
@@ -204,17 +205,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
204 | } | 205 | } |
205 | } | 206 | } |
206 | 207 | ||
207 | /* Update multicast statistic */ | 208 | /* validate length for ether packet */ |
208 | if (skb->len >= ETH_ALEN) { | 209 | if (skb->len < sizeof(*eh)) { |
209 | u8 *pktdata = (u8 *)(skb->data); | 210 | ret = -EINVAL; |
210 | struct ethhdr *eh = (struct ethhdr *)pktdata; | 211 | dev_kfree_skb(skb); |
211 | 212 | goto done; | |
212 | if (is_multicast_ether_addr(eh->h_dest)) | ||
213 | drvr->tx_multicast++; | ||
214 | if (ntohs(eh->h_proto) == ETH_P_PAE) | ||
215 | atomic_inc(&drvr->pend_8021x_cnt); | ||
216 | } | 213 | } |
217 | 214 | ||
215 | /* handle ethernet header */ | ||
216 | eh = (struct ethhdr *)(skb->data); | ||
217 | if (is_multicast_ether_addr(eh->h_dest)) | ||
218 | drvr->tx_multicast++; | ||
219 | if (ntohs(eh->h_proto) == ETH_P_PAE) | ||
220 | atomic_inc(&drvr->pend_8021x_cnt); | ||
221 | |||
218 | /* If the protocol uses a data header, apply it */ | 222 | /* If the protocol uses a data header, apply it */ |
219 | brcmf_proto_hdrpush(drvr, ifp->idx, skb); | 223 | brcmf_proto_hdrpush(drvr, ifp->idx, skb); |
220 | 224 | ||
@@ -228,7 +232,7 @@ done: | |||
228 | drvr->bus_if->dstats.tx_packets++; | 232 | drvr->bus_if->dstats.tx_packets++; |
229 | 233 | ||
230 | /* Return ok: we always eat the packet */ | 234 | /* Return ok: we always eat the packet */ |
231 | return 0; | 235 | return NETDEV_TX_OK; |
232 | } | 236 | } |
233 | 237 | ||
234 | void brcmf_txflowblock(struct device *dev, bool state) | 238 | void brcmf_txflowblock(struct device *dev, bool state) |
@@ -250,8 +254,7 @@ void brcmf_txflowblock(struct device *dev, bool state) | |||
250 | } | 254 | } |
251 | } | 255 | } |
252 | 256 | ||
253 | void brcmf_rx_frame(struct device *dev, u8 ifidx, | 257 | void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) |
254 | struct sk_buff_head *skb_list) | ||
255 | { | 258 | { |
256 | unsigned char *eth; | 259 | unsigned char *eth; |
257 | uint len; | 260 | uint len; |
@@ -259,12 +262,24 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx, | |||
259 | struct brcmf_if *ifp; | 262 | struct brcmf_if *ifp; |
260 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 263 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
261 | struct brcmf_pub *drvr = bus_if->drvr; | 264 | struct brcmf_pub *drvr = bus_if->drvr; |
265 | u8 ifidx; | ||
266 | int ret; | ||
262 | 267 | ||
263 | brcmf_dbg(TRACE, "Enter\n"); | 268 | brcmf_dbg(TRACE, "Enter\n"); |
264 | 269 | ||
265 | skb_queue_walk_safe(skb_list, skb, pnext) { | 270 | skb_queue_walk_safe(skb_list, skb, pnext) { |
266 | skb_unlink(skb, skb_list); | 271 | skb_unlink(skb, skb_list); |
267 | 272 | ||
273 | /* process and remove protocol-specific header | ||
274 | */ | ||
275 | ret = brcmf_proto_hdrpull(drvr, &ifidx, skb); | ||
276 | if (ret < 0) { | ||
277 | if (ret != -ENODATA) | ||
278 | bus_if->dstats.rx_errors++; | ||
279 | brcmu_pkt_buf_free_skb(skb); | ||
280 | continue; | ||
281 | } | ||
282 | |||
268 | /* Get the protocol, maintain skb around eth_type_trans() | 283 | /* Get the protocol, maintain skb around eth_type_trans() |
269 | * The main reason for this hack is for the limitation of | 284 | * The main reason for this hack is for the limitation of |
270 | * Linux 2.4 where 'eth_type_trans' uses the | 285 | * Linux 2.4 where 'eth_type_trans' uses the |
@@ -328,13 +343,13 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx, | |||
328 | 343 | ||
329 | void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) | 344 | void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) |
330 | { | 345 | { |
331 | uint ifidx; | 346 | u8 ifidx; |
332 | struct ethhdr *eh; | 347 | struct ethhdr *eh; |
333 | u16 type; | 348 | u16 type; |
334 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 349 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
335 | struct brcmf_pub *drvr = bus_if->drvr; | 350 | struct brcmf_pub *drvr = bus_if->drvr; |
336 | 351 | ||
337 | brcmf_proto_hdrpull(dev, &ifidx, txp); | 352 | brcmf_proto_hdrpull(drvr, &ifidx, txp); |
338 | 353 | ||
339 | eh = (struct ethhdr *)(txp->data); | 354 | eh = (struct ethhdr *)(txp->data); |
340 | type = ntohs(eh->h_proto); | 355 | type = ntohs(eh->h_proto); |
@@ -452,7 +467,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) | |||
452 | sprintf(info.version, "%lu", drvr->drv_version); | 467 | sprintf(info.version, "%lu", drvr->drv_version); |
453 | if (copy_to_user(uaddr, &info, sizeof(info))) | 468 | if (copy_to_user(uaddr, &info, sizeof(info))) |
454 | return -EFAULT; | 469 | return -EFAULT; |
455 | brcmf_dbg(CTL, "given %*s, returning %s\n", | 470 | brcmf_dbg(TRACE, "given %*s, returning %s\n", |
456 | (int)sizeof(drvname), drvname, info.driver); | 471 | (int)sizeof(drvname), drvname, info.driver); |
457 | break; | 472 | break; |
458 | 473 | ||
@@ -572,14 +587,9 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
572 | /* Get current TOE mode from dongle */ | 587 | /* Get current TOE mode from dongle */ |
573 | if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 | 588 | if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 |
574 | && (toe_ol & TOE_TX_CSUM_OL) != 0) | 589 | && (toe_ol & TOE_TX_CSUM_OL) != 0) |
575 | drvr->iflist[ifp->idx]->ndev->features |= | 590 | ndev->features |= NETIF_F_IP_CSUM; |
576 | NETIF_F_IP_CSUM; | ||
577 | else | 591 | else |
578 | drvr->iflist[ifp->idx]->ndev->features &= | 592 | ndev->features &= ~NETIF_F_IP_CSUM; |
579 | ~NETIF_F_IP_CSUM; | ||
580 | |||
581 | /* make sure RF is ready for work */ | ||
582 | brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); | ||
583 | 593 | ||
584 | /* Allow transmit calls */ | 594 | /* Allow transmit calls */ |
585 | netif_start_queue(ndev); | 595 | netif_start_queue(ndev); |
@@ -847,6 +857,17 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr) | |||
847 | } | 857 | } |
848 | } | 858 | } |
849 | 859 | ||
860 | void brcmf_dev_reset(struct device *dev) | ||
861 | { | ||
862 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
863 | struct brcmf_pub *drvr = bus_if->drvr; | ||
864 | |||
865 | if (drvr == NULL) | ||
866 | return; | ||
867 | |||
868 | brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1); | ||
869 | } | ||
870 | |||
850 | void brcmf_detach(struct device *dev) | 871 | void brcmf_detach(struct device *dev) |
851 | { | 872 | { |
852 | int i; | 873 | int i; |
@@ -868,9 +889,8 @@ void brcmf_detach(struct device *dev) | |||
868 | 889 | ||
869 | brcmf_bus_detach(drvr); | 890 | brcmf_bus_detach(drvr); |
870 | 891 | ||
871 | if (drvr->prot) { | 892 | if (drvr->prot) |
872 | brcmf_proto_detach(drvr); | 893 | brcmf_proto_detach(drvr); |
873 | } | ||
874 | 894 | ||
875 | brcmf_debugfs_detach(drvr); | 895 | brcmf_debugfs_detach(drvr); |
876 | bus_if->drvr = NULL; | 896 | bus_if->drvr = NULL; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index cf857f1edf8c..7fef9b5ba003 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -14,8 +14,6 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
19 | #include <linux/types.h> | 17 | #include <linux/types.h> |
20 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
21 | #include <linux/kthread.h> | 19 | #include <linux/kthread.h> |
@@ -1169,7 +1167,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1169 | int errcode; | 1167 | int errcode; |
1170 | u8 doff, sfdoff; | 1168 | u8 doff, sfdoff; |
1171 | 1169 | ||
1172 | int ifidx = 0; | ||
1173 | bool usechain = bus->use_rxchain; | 1170 | bool usechain = bus->use_rxchain; |
1174 | 1171 | ||
1175 | struct brcmf_sdio_read rd_new; | 1172 | struct brcmf_sdio_read rd_new; |
@@ -1388,13 +1385,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1388 | skb_unlink(pfirst, &bus->glom); | 1385 | skb_unlink(pfirst, &bus->glom); |
1389 | brcmu_pkt_buf_free_skb(pfirst); | 1386 | brcmu_pkt_buf_free_skb(pfirst); |
1390 | continue; | 1387 | continue; |
1391 | } else if (brcmf_proto_hdrpull(bus->sdiodev->dev, | ||
1392 | &ifidx, pfirst) != 0) { | ||
1393 | brcmf_err("rx protocol error\n"); | ||
1394 | bus->sdiodev->bus_if->dstats.rx_errors++; | ||
1395 | skb_unlink(pfirst, &bus->glom); | ||
1396 | brcmu_pkt_buf_free_skb(pfirst); | ||
1397 | continue; | ||
1398 | } | 1388 | } |
1399 | 1389 | ||
1400 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), | 1390 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), |
@@ -1407,7 +1397,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1407 | } | 1397 | } |
1408 | /* sent any remaining packets up */ | 1398 | /* sent any remaining packets up */ |
1409 | if (bus->glom.qlen) | 1399 | if (bus->glom.qlen) |
1410 | brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); | 1400 | brcmf_rx_frames(bus->sdiodev->dev, &bus->glom); |
1411 | 1401 | ||
1412 | bus->sdcnt.rxglomframes++; | 1402 | bus->sdcnt.rxglomframes++; |
1413 | bus->sdcnt.rxglompkts += bus->glom.qlen; | 1403 | bus->sdcnt.rxglompkts += bus->glom.qlen; |
@@ -1558,10 +1548,10 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) | |||
1558 | static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | 1548 | static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) |
1559 | { | 1549 | { |
1560 | struct sk_buff *pkt; /* Packet for event or data frames */ | 1550 | struct sk_buff *pkt; /* Packet for event or data frames */ |
1551 | struct sk_buff_head pktlist; /* needed for bus interface */ | ||
1561 | u16 pad; /* Number of pad bytes to read */ | 1552 | u16 pad; /* Number of pad bytes to read */ |
1562 | uint rxleft = 0; /* Remaining number of frames allowed */ | 1553 | uint rxleft = 0; /* Remaining number of frames allowed */ |
1563 | int sdret; /* Return code from calls */ | 1554 | int sdret; /* Return code from calls */ |
1564 | int ifidx = 0; | ||
1565 | uint rxcount = 0; /* Total frames read */ | 1555 | uint rxcount = 0; /* Total frames read */ |
1566 | struct brcmf_sdio_read *rd = &bus->cur_read, rd_new; | 1556 | struct brcmf_sdio_read *rd = &bus->cur_read, rd_new; |
1567 | u8 head_read = 0; | 1557 | u8 head_read = 0; |
@@ -1760,15 +1750,11 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1760 | if (pkt->len == 0) { | 1750 | if (pkt->len == 0) { |
1761 | brcmu_pkt_buf_free_skb(pkt); | 1751 | brcmu_pkt_buf_free_skb(pkt); |
1762 | continue; | 1752 | continue; |
1763 | } else if (brcmf_proto_hdrpull(bus->sdiodev->dev, &ifidx, | ||
1764 | pkt) != 0) { | ||
1765 | brcmf_err("rx protocol error\n"); | ||
1766 | brcmu_pkt_buf_free_skb(pkt); | ||
1767 | bus->sdiodev->bus_if->dstats.rx_errors++; | ||
1768 | continue; | ||
1769 | } | 1753 | } |
1770 | 1754 | ||
1771 | brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); | 1755 | skb_queue_head_init(&pktlist); |
1756 | skb_queue_tail(&pktlist, pkt); | ||
1757 | brcmf_rx_frames(bus->sdiodev->dev, &pktlist); | ||
1772 | } | 1758 | } |
1773 | 1759 | ||
1774 | rxcount = maxframes - rxleft; | 1760 | rxcount = maxframes - rxleft; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index b1bb46c49799..14be2d5530ce 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
@@ -15,8 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | /* ***** SDIO interface chip backplane handle functions ***** */ | 16 | /* ***** SDIO interface chip backplane handle functions ***** */ |
17 | 17 | ||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
19 | |||
20 | #include <linux/types.h> | 18 | #include <linux/types.h> |
21 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
22 | #include <linux/mmc/card.h> | 20 | #include <linux/mmc/card.h> |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 914c56fe6c5f..e15630cc3889 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -443,14 +443,15 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
443 | struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; | 443 | struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; |
444 | struct brcmf_usbdev_info *devinfo = req->devinfo; | 444 | struct brcmf_usbdev_info *devinfo = req->devinfo; |
445 | struct sk_buff *skb; | 445 | struct sk_buff *skb; |
446 | int ifidx = 0; | 446 | struct sk_buff_head skbq; |
447 | 447 | ||
448 | brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); | 448 | brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); |
449 | brcmf_usb_del_fromq(devinfo, req); | 449 | brcmf_usb_del_fromq(devinfo, req); |
450 | skb = req->skb; | 450 | skb = req->skb; |
451 | req->skb = NULL; | 451 | req->skb = NULL; |
452 | 452 | ||
453 | if (urb->status == 0) { | 453 | /* zero lenght packets indicate usb "failure". Do not refill */ |
454 | if (urb->status == 0 && urb->actual_length) { | ||
454 | devinfo->bus_pub.bus->dstats.rx_packets++; | 455 | devinfo->bus_pub.bus->dstats.rx_packets++; |
455 | } else { | 456 | } else { |
456 | devinfo->bus_pub.bus->dstats.rx_errors++; | 457 | devinfo->bus_pub.bus->dstats.rx_errors++; |
@@ -460,13 +461,10 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
460 | } | 461 | } |
461 | 462 | ||
462 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { | 463 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { |
464 | skb_queue_head_init(&skbq); | ||
465 | skb_queue_tail(&skbq, skb); | ||
463 | skb_put(skb, urb->actual_length); | 466 | skb_put(skb, urb->actual_length); |
464 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { | 467 | brcmf_rx_frames(devinfo->dev, &skbq); |
465 | brcmf_err("rx protocol error\n"); | ||
466 | brcmu_pkt_buf_free_skb(skb); | ||
467 | devinfo->bus_pub.bus->dstats.rx_errors++; | ||
468 | } else | ||
469 | brcmf_rx_packet(devinfo->dev, ifidx, skb); | ||
470 | brcmf_usb_rx_refill(devinfo, req); | 468 | brcmf_usb_rx_refill(devinfo, req); |
471 | } else { | 469 | } else { |
472 | brcmu_pkt_buf_free_skb(skb); | 470 | brcmu_pkt_buf_free_skb(skb); |
@@ -1520,10 +1518,23 @@ static void brcmf_release_fw(struct list_head *q) | |||
1520 | } | 1518 | } |
1521 | } | 1519 | } |
1522 | 1520 | ||
1521 | static int brcmf_usb_reset_device(struct device *dev, void *notused) | ||
1522 | { | ||
1523 | /* device past is the usb interface so we | ||
1524 | * need to use parent here. | ||
1525 | */ | ||
1526 | brcmf_dev_reset(dev->parent); | ||
1527 | return 0; | ||
1528 | } | ||
1523 | 1529 | ||
1524 | void brcmf_usb_exit(void) | 1530 | void brcmf_usb_exit(void) |
1525 | { | 1531 | { |
1532 | struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver; | ||
1533 | int ret; | ||
1534 | |||
1526 | brcmf_dbg(USB, "Enter\n"); | 1535 | brcmf_dbg(USB, "Enter\n"); |
1536 | ret = driver_for_each_device(drv, NULL, NULL, | ||
1537 | brcmf_usb_reset_device); | ||
1527 | usb_deregister(&brcmf_usbdrvr); | 1538 | usb_deregister(&brcmf_usbdrvr); |
1528 | brcmf_release_fw(&fw_image_list); | 1539 | brcmf_release_fw(&fw_image_list); |
1529 | } | 1540 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 75464ad4fbd1..62a528e8b958 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -16,8 +16,6 @@ | |||
16 | 16 | ||
17 | /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */ | 17 | /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */ |
18 | 18 | ||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
21 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
22 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
23 | #include <net/cfg80211.h> | 21 | #include <net/cfg80211.h> |
@@ -2011,67 +2009,6 @@ done: | |||
2011 | return err; | 2009 | return err; |
2012 | } | 2010 | } |
2013 | 2011 | ||
2014 | static s32 | ||
2015 | brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, | ||
2016 | const u8 *addr, | ||
2017 | const struct cfg80211_bitrate_mask *mask) | ||
2018 | { | ||
2019 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
2020 | struct brcm_rateset_le rateset_le; | ||
2021 | s32 rate; | ||
2022 | s32 val; | ||
2023 | s32 err_bg; | ||
2024 | s32 err_a; | ||
2025 | u32 legacy; | ||
2026 | s32 err = 0; | ||
2027 | |||
2028 | brcmf_dbg(TRACE, "Enter\n"); | ||
2029 | if (!check_vif_up(ifp->vif)) | ||
2030 | return -EIO; | ||
2031 | |||
2032 | /* addr param is always NULL. ignore it */ | ||
2033 | /* Get current rateset */ | ||
2034 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET, | ||
2035 | &rateset_le, sizeof(rateset_le)); | ||
2036 | if (err) { | ||
2037 | brcmf_err("could not get current rateset (%d)\n", err); | ||
2038 | goto done; | ||
2039 | } | ||
2040 | |||
2041 | legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF); | ||
2042 | if (!legacy) | ||
2043 | legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy & | ||
2044 | 0xFFFF); | ||
2045 | |||
2046 | val = wl_g_rates[legacy - 1].bitrate * 100000; | ||
2047 | |||
2048 | if (val < le32_to_cpu(rateset_le.count)) | ||
2049 | /* Select rate by rateset index */ | ||
2050 | rate = rateset_le.rates[val] & 0x7f; | ||
2051 | else | ||
2052 | /* Specified rate in bps */ | ||
2053 | rate = val / 500000; | ||
2054 | |||
2055 | brcmf_dbg(CONN, "rate %d mbps\n", rate / 2); | ||
2056 | |||
2057 | /* | ||
2058 | * | ||
2059 | * Set rate override, | ||
2060 | * Since the is a/b/g-blind, both a/bg_rate are enforced. | ||
2061 | */ | ||
2062 | err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate); | ||
2063 | err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate); | ||
2064 | if (err_bg && err_a) { | ||
2065 | brcmf_err("could not set fixed rate (%d) (%d)\n", err_bg, | ||
2066 | err_a); | ||
2067 | err = err_bg | err_a; | ||
2068 | } | ||
2069 | |||
2070 | done: | ||
2071 | brcmf_dbg(TRACE, "Exit\n"); | ||
2072 | return err; | ||
2073 | } | ||
2074 | |||
2075 | static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, | 2012 | static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, |
2076 | struct brcmf_bss_info_le *bi) | 2013 | struct brcmf_bss_info_le *bi) |
2077 | { | 2014 | { |
@@ -3704,7 +3641,6 @@ static struct cfg80211_ops wl_cfg80211_ops = { | |||
3704 | .set_default_key = brcmf_cfg80211_config_default_key, | 3641 | .set_default_key = brcmf_cfg80211_config_default_key, |
3705 | .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key, | 3642 | .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key, |
3706 | .set_power_mgmt = brcmf_cfg80211_set_power_mgmt, | 3643 | .set_power_mgmt = brcmf_cfg80211_set_power_mgmt, |
3707 | .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask, | ||
3708 | .connect = brcmf_cfg80211_connect, | 3644 | .connect = brcmf_cfg80211_connect, |
3709 | .disconnect = brcmf_cfg80211_disconnect, | 3645 | .disconnect = brcmf_cfg80211_disconnect, |
3710 | .suspend = brcmf_cfg80211_suspend, | 3646 | .suspend = brcmf_cfg80211_suspend, |
@@ -4330,9 +4266,8 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) | |||
4330 | } | 4266 | } |
4331 | 4267 | ||
4332 | static s32 | 4268 | static s32 |
4333 | brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) | 4269 | brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout) |
4334 | { | 4270 | { |
4335 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4336 | s32 err = 0; | 4271 | s32 err = 0; |
4337 | __le32 roamtrigger[2]; | 4272 | __le32 roamtrigger[2]; |
4338 | __le32 roam_delta[2]; | 4273 | __le32 roam_delta[2]; |
@@ -4383,10 +4318,9 @@ dongle_rom_out: | |||
4383 | } | 4318 | } |
4384 | 4319 | ||
4385 | static s32 | 4320 | static s32 |
4386 | brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, | 4321 | brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time, |
4387 | s32 scan_unassoc_time, s32 scan_passive_time) | 4322 | s32 scan_unassoc_time, s32 scan_passive_time) |
4388 | { | 4323 | { |
4389 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4390 | s32 err = 0; | 4324 | s32 err = 0; |
4391 | 4325 | ||
4392 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, | 4326 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, |
@@ -4456,6 +4390,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) | |||
4456 | { | 4390 | { |
4457 | struct net_device *ndev; | 4391 | struct net_device *ndev; |
4458 | struct wireless_dev *wdev; | 4392 | struct wireless_dev *wdev; |
4393 | struct brcmf_if *ifp; | ||
4459 | s32 power_mode; | 4394 | s32 power_mode; |
4460 | s32 err = 0; | 4395 | s32 err = 0; |
4461 | 4396 | ||
@@ -4464,35 +4399,34 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) | |||
4464 | 4399 | ||
4465 | ndev = cfg_to_ndev(cfg); | 4400 | ndev = cfg_to_ndev(cfg); |
4466 | wdev = ndev->ieee80211_ptr; | 4401 | wdev = ndev->ieee80211_ptr; |
4402 | ifp = netdev_priv(ndev); | ||
4467 | 4403 | ||
4468 | brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, | 4404 | /* make sure RF is ready for work */ |
4469 | WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); | 4405 | brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); |
4406 | |||
4407 | brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME, | ||
4408 | WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); | ||
4470 | 4409 | ||
4471 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; | 4410 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; |
4472 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, | 4411 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode); |
4473 | power_mode); | ||
4474 | if (err) | 4412 | if (err) |
4475 | goto default_conf_out; | 4413 | goto default_conf_out; |
4476 | brcmf_dbg(INFO, "power save set to %s\n", | 4414 | brcmf_dbg(INFO, "power save set to %s\n", |
4477 | (power_mode ? "enabled" : "disabled")); | 4415 | (power_mode ? "enabled" : "disabled")); |
4478 | 4416 | ||
4479 | err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1), | 4417 | err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); |
4480 | WL_BEACON_TIMEOUT); | ||
4481 | if (err) | 4418 | if (err) |
4482 | goto default_conf_out; | 4419 | goto default_conf_out; |
4483 | err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, | 4420 | err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, |
4484 | NULL, NULL); | 4421 | NULL, NULL); |
4485 | if (err && err != -EINPROGRESS) | 4422 | if (err) |
4486 | goto default_conf_out; | 4423 | goto default_conf_out; |
4487 | err = brcmf_dongle_probecap(cfg); | 4424 | err = brcmf_dongle_probecap(cfg); |
4488 | if (err) | 4425 | if (err) |
4489 | goto default_conf_out; | 4426 | goto default_conf_out; |
4490 | 4427 | ||
4491 | /* -EINPROGRESS: Call commit handler */ | ||
4492 | |||
4493 | default_conf_out: | ||
4494 | |||
4495 | cfg->dongle_up = true; | 4428 | cfg->dongle_up = true; |
4429 | default_conf_out: | ||
4496 | 4430 | ||
4497 | return err; | 4431 | return err; |
4498 | 4432 | ||
@@ -4501,8 +4435,6 @@ default_conf_out: | |||
4501 | static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp) | 4435 | static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp) |
4502 | { | 4436 | { |
4503 | set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); | 4437 | set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); |
4504 | if (ifp->idx) | ||
4505 | return 0; | ||
4506 | 4438 | ||
4507 | return brcmf_config_dongle(ifp->drvr->config); | 4439 | return brcmf_config_dongle(ifp->drvr->config); |
4508 | } | 4440 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 1de94f30564f..1585cc5bf866 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -961,7 +961,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
961 | /* if acked then clear bit and free packet */ | 961 | /* if acked then clear bit and free packet */ |
962 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) | 962 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) |
963 | && isset(bitmap, bindex)) { | 963 | && isset(bitmap, bindex)) { |
964 | ini->tx_in_transit--; | ||
965 | ini->txretry[index] = 0; | 964 | ini->txretry[index] = 0; |
966 | 965 | ||
967 | /* | 966 | /* |
@@ -990,7 +989,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
990 | if (retry && (ini->txretry[index] < (int)retry_limit)) { | 989 | if (retry && (ini->txretry[index] < (int)retry_limit)) { |
991 | int ret; | 990 | int ret; |
992 | ini->txretry[index]++; | 991 | ini->txretry[index]++; |
993 | ini->tx_in_transit--; | ||
994 | ret = brcms_c_txfifo(wlc, queue, p); | 992 | ret = brcms_c_txfifo(wlc, queue, p); |
995 | /* | 993 | /* |
996 | * We shouldn't be out of space in the DMA | 994 | * We shouldn't be out of space in the DMA |
@@ -1000,7 +998,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1000 | WARN_ONCE(ret, "queue %d out of txds\n", queue); | 998 | WARN_ONCE(ret, "queue %d out of txds\n", queue); |
1001 | } else { | 999 | } else { |
1002 | /* Retry timeout */ | 1000 | /* Retry timeout */ |
1003 | ini->tx_in_transit--; | ||
1004 | ieee80211_tx_info_clear_status(tx_info); | 1001 | ieee80211_tx_info_clear_status(tx_info); |
1005 | tx_info->status.ampdu_ack_len = 0; | 1002 | tx_info->status.ampdu_ack_len = 0; |
1006 | tx_info->status.ampdu_len = 1; | 1003 | tx_info->status.ampdu_len = 1; |
@@ -1009,8 +1006,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1009 | skb_pull(p, D11_PHY_HDR_LEN); | 1006 | skb_pull(p, D11_PHY_HDR_LEN); |
1010 | skb_pull(p, D11_TXH_LEN); | 1007 | skb_pull(p, D11_TXH_LEN); |
1011 | brcms_dbg_ht(wlc->hw->d11core, | 1008 | brcms_dbg_ht(wlc->hw->d11core, |
1012 | "BA Timeout, seq %d, in_transit %d\n", | 1009 | "BA Timeout, seq %d\n", |
1013 | seq, ini->tx_in_transit); | 1010 | seq); |
1014 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, | 1011 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, |
1015 | p); | 1012 | p); |
1016 | } | 1013 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index a90b72202ec5..cdb62b8ccc79 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
@@ -670,7 +670,7 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy, | |||
670 | struct ieee80211_supported_band *sband; | 670 | struct ieee80211_supported_band *sband; |
671 | struct ieee80211_channel *ch; | 671 | struct ieee80211_channel *ch; |
672 | const struct ieee80211_reg_rule *rule; | 672 | const struct ieee80211_reg_rule *rule; |
673 | int band, i, ret; | 673 | int band, i; |
674 | 674 | ||
675 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 675 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
676 | sband = wiphy->bands[band]; | 676 | sband = wiphy->bands[band]; |
@@ -685,9 +685,8 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy, | |||
685 | continue; | 685 | continue; |
686 | 686 | ||
687 | if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { | 687 | if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { |
688 | ret = freq_reg_info(wiphy, ch->center_freq, | 688 | rule = freq_reg_info(wiphy, ch->center_freq); |
689 | 0, &rule); | 689 | if (IS_ERR(rule)) |
690 | if (ret) | ||
691 | continue; | 690 | continue; |
692 | 691 | ||
693 | if (!(rule->flags & NL80211_RRF_NO_IBSS)) | 692 | if (!(rule->flags & NL80211_RRF_NO_IBSS)) |
@@ -703,8 +702,8 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy, | |||
703 | } | 702 | } |
704 | } | 703 | } |
705 | 704 | ||
706 | static int brcms_reg_notifier(struct wiphy *wiphy, | 705 | static void brcms_reg_notifier(struct wiphy *wiphy, |
707 | struct regulatory_request *request) | 706 | struct regulatory_request *request) |
708 | { | 707 | { |
709 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 708 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
710 | struct brcms_info *wl = hw->priv; | 709 | struct brcms_info *wl = hw->priv; |
@@ -745,8 +744,6 @@ static int brcms_reg_notifier(struct wiphy *wiphy, | |||
745 | if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) | 744 | if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) |
746 | wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, | 745 | wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, |
747 | brcms_c_japan_ccode(request->alpha2)); | 746 | brcms_c_japan_ccode(request->alpha2)); |
748 | |||
749 | return 0; | ||
750 | } | 747 | } |
751 | 748 | ||
752 | void brcms_c_regd_init(struct brcms_c_info *wlc) | 749 | void brcms_c_regd_init(struct brcms_c_info *wlc) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 1fbd8ecbe2ea..7fc49ca3f597 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -362,8 +362,11 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
362 | return -EOPNOTSUPP; | 362 | return -EOPNOTSUPP; |
363 | } | 363 | } |
364 | 364 | ||
365 | spin_lock_bh(&wl->lock); | ||
366 | memcpy(wl->pub->cur_etheraddr, vif->addr, sizeof(vif->addr)); | ||
365 | wl->mute_tx = false; | 367 | wl->mute_tx = false; |
366 | brcms_c_mute(wl->wlc, false); | 368 | brcms_c_mute(wl->wlc, false); |
369 | spin_unlock_bh(&wl->lock); | ||
367 | 370 | ||
368 | return 0; | 371 | return 0; |
369 | } | 372 | } |
@@ -668,7 +671,9 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, | |||
668 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 671 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
669 | break; | 672 | break; |
670 | 673 | ||
671 | case IEEE80211_AMPDU_TX_STOP: | 674 | case IEEE80211_AMPDU_TX_STOP_CONT: |
675 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
676 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
672 | spin_lock_bh(&wl->lock); | 677 | spin_lock_bh(&wl->lock); |
673 | brcms_c_ampdu_flush(wl->wlc, sta, tid); | 678 | brcms_c_ampdu_flush(wl->wlc, sta, tid); |
674 | spin_unlock_bh(&wl->lock); | 679 | spin_unlock_bh(&wl->lock); |
@@ -1407,9 +1412,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) | |||
1407 | #endif | 1412 | #endif |
1408 | t->ms = ms; | 1413 | t->ms = ms; |
1409 | t->periodic = (bool) periodic; | 1414 | t->periodic = (bool) periodic; |
1410 | t->set = true; | 1415 | if (!t->set) { |
1411 | 1416 | t->set = true; | |
1412 | atomic_inc(&t->wl->callbacks); | 1417 | atomic_inc(&t->wl->callbacks); |
1418 | } | ||
1413 | 1419 | ||
1414 | ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms)); | 1420 | ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms)); |
1415 | } | 1421 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 17594de4199e..c26992a60e6c 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -2473,6 +2473,7 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, | |||
2473 | static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) | 2473 | static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) |
2474 | { | 2474 | { |
2475 | static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; | 2475 | static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; |
2476 | u8 *ethaddr = wlc_hw->wlc->pub->cur_etheraddr; | ||
2476 | 2477 | ||
2477 | if (mute_tx) { | 2478 | if (mute_tx) { |
2478 | /* suspend tx fifos */ | 2479 | /* suspend tx fifos */ |
@@ -2482,8 +2483,7 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) | |||
2482 | brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); | 2483 | brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); |
2483 | 2484 | ||
2484 | /* zero the address match register so we do not send ACKs */ | 2485 | /* zero the address match register so we do not send ACKs */ |
2485 | brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, | 2486 | brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, null_ether_addr); |
2486 | null_ether_addr); | ||
2487 | } else { | 2487 | } else { |
2488 | /* resume tx fifos */ | 2488 | /* resume tx fifos */ |
2489 | brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); | 2489 | brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); |
@@ -2492,8 +2492,7 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) | |||
2492 | brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); | 2492 | brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); |
2493 | 2493 | ||
2494 | /* Restore address */ | 2494 | /* Restore address */ |
2495 | brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, | 2495 | brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, ethaddr); |
2496 | wlc_hw->etheraddr); | ||
2497 | } | 2496 | } |
2498 | 2497 | ||
2499 | wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0); | 2498 | wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0); |
@@ -7633,7 +7632,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) | |||
7633 | 7632 | ||
7634 | uint n = 0; | 7633 | uint n = 0; |
7635 | uint bound_limit = bound ? RXBND : -1; | 7634 | uint bound_limit = bound ? RXBND : -1; |
7636 | bool morepending; | 7635 | bool morepending = false; |
7637 | 7636 | ||
7638 | skb_queue_head_init(&recv_frames); | 7637 | skb_queue_head_init(&recv_frames); |
7639 | 7638 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/scb.h b/drivers/net/wireless/brcm80211/brcmsmac/scb.h index 51c79c7239b7..3a3d73699f83 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/scb.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/scb.h | |||
@@ -36,7 +36,6 @@ | |||
36 | 36 | ||
37 | /* structure to store per-tid state for the ampdu initiator */ | 37 | /* structure to store per-tid state for the ampdu initiator */ |
38 | struct scb_ampdu_tid_ini { | 38 | struct scb_ampdu_tid_ini { |
39 | u8 tx_in_transit; /* number of pending mpdus in transit in driver */ | ||
40 | u8 tid; /* initiator tid for easy lookup */ | 39 | u8 tid; /* initiator tid for easy lookup */ |
41 | /* tx retry count; indexed by seq modulo */ | 40 | /* tx retry count; indexed by seq modulo */ |
42 | u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; | 41 | u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; |
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 3726cd6fcd75..050ce7c70d74 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c | |||
@@ -3474,6 +3474,7 @@ struct ieee80211_ops il3945_mac_ops = { | |||
3474 | .sta_add = il3945_mac_sta_add, | 3474 | .sta_add = il3945_mac_sta_add, |
3475 | .sta_remove = il_mac_sta_remove, | 3475 | .sta_remove = il_mac_sta_remove, |
3476 | .tx_last_beacon = il_mac_tx_last_beacon, | 3476 | .tx_last_beacon = il_mac_tx_last_beacon, |
3477 | .flush = il_mac_flush, | ||
3477 | }; | 3478 | }; |
3478 | 3479 | ||
3479 | static int | 3480 | static int |
@@ -3548,7 +3549,8 @@ il3945_setup_mac(struct il_priv *il) | |||
3548 | hw->vif_data_size = sizeof(struct il_vif_priv); | 3549 | hw->vif_data_size = sizeof(struct il_vif_priv); |
3549 | 3550 | ||
3550 | /* Tell mac80211 our characteristics */ | 3551 | /* Tell mac80211 our characteristics */ |
3551 | hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT; | 3552 | hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT | |
3553 | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
3552 | 3554 | ||
3553 | hw->wiphy->interface_modes = | 3555 | hw->wiphy->interface_modes = |
3554 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); | 3556 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); |
@@ -3557,6 +3559,8 @@ il3945_setup_mac(struct il_priv *il) | |||
3557 | WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | | 3559 | WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
3558 | WIPHY_FLAG_IBSS_RSN; | 3560 | WIPHY_FLAG_IBSS_RSN; |
3559 | 3561 | ||
3562 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
3563 | |||
3560 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; | 3564 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; |
3561 | /* we create the 802.11 header and a zero-length SSID element */ | 3565 | /* we create the 802.11 header and a zero-length SSID element */ |
3562 | hw->wiphy->max_scan_ie_len = IL3945_MAX_PROBE_REQUEST - 24 - 2; | 3566 | hw->wiphy->max_scan_ie_len = IL3945_MAX_PROBE_REQUEST - 24 - 2; |
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index c3fbf6717564..f1dc04006564 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -5712,8 +5712,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) | |||
5712 | hw->flags = | 5712 | hw->flags = |
5713 | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | | 5713 | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | |
5714 | IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT | | 5714 | IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT | |
5715 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | 5715 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | |
5716 | 5716 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | |
5717 | if (il->cfg->sku & IL_SKU_N) | 5717 | if (il->cfg->sku & IL_SKU_N) |
5718 | hw->flags |= | 5718 | hw->flags |= |
5719 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 5719 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
@@ -5968,7 +5968,9 @@ il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5968 | D_HT("start Tx\n"); | 5968 | D_HT("start Tx\n"); |
5969 | ret = il4965_tx_agg_start(il, vif, sta, tid, ssn); | 5969 | ret = il4965_tx_agg_start(il, vif, sta, tid, ssn); |
5970 | break; | 5970 | break; |
5971 | case IEEE80211_AMPDU_TX_STOP: | 5971 | case IEEE80211_AMPDU_TX_STOP_CONT: |
5972 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
5973 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
5972 | D_HT("stop Tx\n"); | 5974 | D_HT("stop Tx\n"); |
5973 | ret = il4965_tx_agg_stop(il, vif, sta, tid); | 5975 | ret = il4965_tx_agg_stop(il, vif, sta, tid); |
5974 | if (test_bit(S_EXIT_PENDING, &il->status)) | 5976 | if (test_bit(S_EXIT_PENDING, &il->status)) |
@@ -6306,6 +6308,7 @@ const struct ieee80211_ops il4965_mac_ops = { | |||
6306 | .sta_remove = il_mac_sta_remove, | 6308 | .sta_remove = il_mac_sta_remove, |
6307 | .channel_switch = il4965_mac_channel_switch, | 6309 | .channel_switch = il4965_mac_channel_switch, |
6308 | .tx_last_beacon = il_mac_tx_last_beacon, | 6310 | .tx_last_beacon = il_mac_tx_last_beacon, |
6311 | .flush = il_mac_flush, | ||
6309 | }; | 6312 | }; |
6310 | 6313 | ||
6311 | static int | 6314 | static int |
@@ -6553,6 +6556,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6553 | il4965_prepare_card_hw(il); | 6556 | il4965_prepare_card_hw(il); |
6554 | if (!il->hw_ready) { | 6557 | if (!il->hw_ready) { |
6555 | IL_WARN("Failed, HW not ready\n"); | 6558 | IL_WARN("Failed, HW not ready\n"); |
6559 | err = -EIO; | ||
6556 | goto out_iounmap; | 6560 | goto out_iounmap; |
6557 | } | 6561 | } |
6558 | 6562 | ||
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 7e16d10a7f14..1f598604a79c 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il) | |||
3958 | 3958 | ||
3959 | memset(&il->staging, 0, sizeof(il->staging)); | 3959 | memset(&il->staging, 0, sizeof(il->staging)); |
3960 | 3960 | ||
3961 | if (!il->vif) { | 3961 | switch (il->iw_mode) { |
3962 | case NL80211_IFTYPE_UNSPECIFIED: | ||
3962 | il->staging.dev_type = RXON_DEV_TYPE_ESS; | 3963 | il->staging.dev_type = RXON_DEV_TYPE_ESS; |
3963 | } else if (il->vif->type == NL80211_IFTYPE_STATION) { | 3964 | break; |
3965 | case NL80211_IFTYPE_STATION: | ||
3964 | il->staging.dev_type = RXON_DEV_TYPE_ESS; | 3966 | il->staging.dev_type = RXON_DEV_TYPE_ESS; |
3965 | il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; | 3967 | il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; |
3966 | } else if (il->vif->type == NL80211_IFTYPE_ADHOC) { | 3968 | break; |
3969 | case NL80211_IFTYPE_ADHOC: | ||
3967 | il->staging.dev_type = RXON_DEV_TYPE_IBSS; | 3970 | il->staging.dev_type = RXON_DEV_TYPE_IBSS; |
3968 | il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; | 3971 | il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; |
3969 | il->staging.filter_flags = | 3972 | il->staging.filter_flags = |
3970 | RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; | 3973 | RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; |
3971 | } else { | 3974 | break; |
3975 | default: | ||
3972 | IL_ERR("Unsupported interface type %d\n", il->vif->type); | 3976 | IL_ERR("Unsupported interface type %d\n", il->vif->type); |
3973 | return; | 3977 | return; |
3974 | } | 3978 | } |
@@ -4550,8 +4554,7 @@ out: | |||
4550 | EXPORT_SYMBOL(il_mac_add_interface); | 4554 | EXPORT_SYMBOL(il_mac_add_interface); |
4551 | 4555 | ||
4552 | static void | 4556 | static void |
4553 | il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, | 4557 | il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif) |
4554 | bool mode_change) | ||
4555 | { | 4558 | { |
4556 | lockdep_assert_held(&il->mutex); | 4559 | lockdep_assert_held(&il->mutex); |
4557 | 4560 | ||
@@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, | |||
4560 | il_force_scan_end(il); | 4563 | il_force_scan_end(il); |
4561 | } | 4564 | } |
4562 | 4565 | ||
4563 | if (!mode_change) | 4566 | il_set_mode(il); |
4564 | il_set_mode(il); | ||
4565 | |||
4566 | } | 4567 | } |
4567 | 4568 | ||
4568 | void | 4569 | void |
@@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
4575 | 4576 | ||
4576 | WARN_ON(il->vif != vif); | 4577 | WARN_ON(il->vif != vif); |
4577 | il->vif = NULL; | 4578 | il->vif = NULL; |
4578 | 4579 | il->iw_mode = NL80211_IFTYPE_UNSPECIFIED; | |
4579 | il_teardown_interface(il, vif, false); | 4580 | il_teardown_interface(il, vif); |
4580 | memset(il->bssid, 0, ETH_ALEN); | 4581 | memset(il->bssid, 0, ETH_ALEN); |
4581 | 4582 | ||
4582 | D_MAC80211("leave\n"); | 4583 | D_MAC80211("leave\n"); |
@@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
4685 | } | 4686 | } |
4686 | 4687 | ||
4687 | /* success */ | 4688 | /* success */ |
4688 | il_teardown_interface(il, vif, true); | ||
4689 | vif->type = newtype; | 4689 | vif->type = newtype; |
4690 | vif->p2p = false; | 4690 | vif->p2p = false; |
4691 | err = il_set_mode(il); | 4691 | il->iw_mode = newtype; |
4692 | WARN_ON(err); | 4692 | il_teardown_interface(il, vif); |
4693 | /* | ||
4694 | * We've switched internally, but submitting to the | ||
4695 | * device may have failed for some reason. Mask this | ||
4696 | * error, because otherwise mac80211 will not switch | ||
4697 | * (and set the interface type back) and we'll be | ||
4698 | * out of sync with it. | ||
4699 | */ | ||
4700 | err = 0; | 4693 | err = 0; |
4701 | 4694 | ||
4702 | out: | 4695 | out: |
@@ -4707,6 +4700,42 @@ out: | |||
4707 | } | 4700 | } |
4708 | EXPORT_SYMBOL(il_mac_change_interface); | 4701 | EXPORT_SYMBOL(il_mac_change_interface); |
4709 | 4702 | ||
4703 | void | ||
4704 | il_mac_flush(struct ieee80211_hw *hw, bool drop) | ||
4705 | { | ||
4706 | struct il_priv *il = hw->priv; | ||
4707 | unsigned long timeout = jiffies + msecs_to_jiffies(500); | ||
4708 | int i; | ||
4709 | |||
4710 | mutex_lock(&il->mutex); | ||
4711 | D_MAC80211("enter\n"); | ||
4712 | |||
4713 | if (il->txq == NULL) | ||
4714 | goto out; | ||
4715 | |||
4716 | for (i = 0; i < il->hw_params.max_txq_num; i++) { | ||
4717 | struct il_queue *q; | ||
4718 | |||
4719 | if (i == il->cmd_queue) | ||
4720 | continue; | ||
4721 | |||
4722 | q = &il->txq[i].q; | ||
4723 | if (q->read_ptr == q->write_ptr) | ||
4724 | continue; | ||
4725 | |||
4726 | if (time_after(jiffies, timeout)) { | ||
4727 | IL_ERR("Failed to flush queue %d\n", q->id); | ||
4728 | break; | ||
4729 | } | ||
4730 | |||
4731 | msleep(20); | ||
4732 | } | ||
4733 | out: | ||
4734 | D_MAC80211("leave\n"); | ||
4735 | mutex_unlock(&il->mutex); | ||
4736 | } | ||
4737 | EXPORT_SYMBOL(il_mac_flush); | ||
4738 | |||
4710 | /* | 4739 | /* |
4711 | * On every watchdog tick we check (latest) time stamp. If it does not | 4740 | * On every watchdog tick we check (latest) time stamp. If it does not |
4712 | * change during timeout period and queue is not empty we reset firmware. | 4741 | * change during timeout period and queue is not empty we reset firmware. |
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index a9a569f432fb..37fe553b25e0 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h | |||
@@ -1723,6 +1723,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, | |||
1723 | struct ieee80211_vif *vif); | 1723 | struct ieee80211_vif *vif); |
1724 | int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1724 | int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1725 | enum nl80211_iftype newtype, bool newp2p); | 1725 | enum nl80211_iftype newtype, bool newp2p); |
1726 | void il_mac_flush(struct ieee80211_hw *hw, bool drop); | ||
1726 | int il_alloc_txq_mem(struct il_priv *il); | 1727 | int il_alloc_txq_mem(struct il_priv *il); |
1727 | void il_free_txq_mem(struct il_priv *il); | 1728 | void il_free_txq_mem(struct il_priv *il); |
1728 | 1729 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 71ab76b2b39d..0ca99c13f7f2 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
@@ -3695,7 +3695,7 @@ struct iwl_bt_uart_msg { | |||
3695 | u8 frame5; | 3695 | u8 frame5; |
3696 | u8 frame6; | 3696 | u8 frame6; |
3697 | u8 frame7; | 3697 | u8 frame7; |
3698 | } __attribute__((packed)); | 3698 | } __packed; |
3699 | 3699 | ||
3700 | struct iwl_bt_coex_profile_notif { | 3700 | struct iwl_bt_coex_profile_notif { |
3701 | struct iwl_bt_uart_msg last_bt_uart_msg; | 3701 | struct iwl_bt_uart_msg last_bt_uart_msg; |
@@ -3703,7 +3703,7 @@ struct iwl_bt_coex_profile_notif { | |||
3703 | u8 bt_traffic_load; /* 0 .. 3? */ | 3703 | u8 bt_traffic_load; /* 0 .. 3? */ |
3704 | u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ | 3704 | u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ |
3705 | u8 reserved; | 3705 | u8 reserved; |
3706 | } __attribute__((packed)); | 3706 | } __packed; |
3707 | 3707 | ||
3708 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 | 3708 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 |
3709 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 | 3709 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 |
@@ -3752,7 +3752,7 @@ enum bt_coex_prio_table_priorities { | |||
3752 | 3752 | ||
3753 | struct iwl_bt_coex_prio_table_cmd { | 3753 | struct iwl_bt_coex_prio_table_cmd { |
3754 | u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; | 3754 | u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; |
3755 | } __attribute__((packed)); | 3755 | } __packed; |
3756 | 3756 | ||
3757 | #define IWL_BT_COEX_ENV_CLOSE 0 | 3757 | #define IWL_BT_COEX_ENV_CLOSE 0 |
3758 | #define IWL_BT_COEX_ENV_OPEN 1 | 3758 | #define IWL_BT_COEX_ENV_OPEN 1 |
@@ -3764,7 +3764,7 @@ struct iwl_bt_coex_prot_env_cmd { | |||
3764 | u8 action; /* 0 = closed, 1 = open */ | 3764 | u8 action; /* 0 = closed, 1 = open */ |
3765 | u8 type; /* 0 .. 15 */ | 3765 | u8 type; /* 0 .. 15 */ |
3766 | u8 reserved[2]; | 3766 | u8 reserved[2]; |
3767 | } __attribute__((packed)); | 3767 | } __packed; |
3768 | 3768 | ||
3769 | /* | 3769 | /* |
3770 | * REPLY_D3_CONFIG | 3770 | * REPLY_D3_CONFIG |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 5b9533eef54d..72c74af38138 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -157,7 +157,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
157 | sram = priv->dbgfs_sram_offset & ~0x3; | 157 | sram = priv->dbgfs_sram_offset & ~0x3; |
158 | 158 | ||
159 | /* read the first u32 from sram */ | 159 | /* read the first u32 from sram */ |
160 | val = iwl_read_targ_mem(priv->trans, sram); | 160 | val = iwl_trans_read_mem32(priv->trans, sram); |
161 | 161 | ||
162 | for (; len; len--) { | 162 | for (; len; len--) { |
163 | /* put the address at the start of every line */ | 163 | /* put the address at the start of every line */ |
@@ -176,7 +176,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
176 | if (++offset == 4) { | 176 | if (++offset == 4) { |
177 | sram += 4; | 177 | sram += 4; |
178 | offset = 0; | 178 | offset = 0; |
179 | val = iwl_read_targ_mem(priv->trans, sram); | 179 | val = iwl_trans_read_mem32(priv->trans, sram); |
180 | } | 180 | } |
181 | 181 | ||
182 | /* put in extra spaces and split lines for human readability */ | 182 | /* put in extra spaces and split lines for human readability */ |
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.c b/drivers/net/wireless/iwlwifi/dvm/led.c index bf479f709091..844a17f99a18 100644 --- a/drivers/net/wireless/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/iwlwifi/dvm/led.c | |||
@@ -69,7 +69,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { | |||
69 | /* Set led register off */ | 69 | /* Set led register off */ |
70 | void iwlagn_led_enable(struct iwl_priv *priv) | 70 | void iwlagn_led_enable(struct iwl_priv *priv) |
71 | { | 71 | { |
72 | iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TRUN_ON); | 72 | iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON); |
73 | } | 73 | } |
74 | 74 | ||
75 | /* | 75 | /* |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 3163e0f38c25..0353e1c0670d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -206,7 +206,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
206 | 206 | ||
207 | #ifdef CONFIG_PM_SLEEP | 207 | #ifdef CONFIG_PM_SLEEP |
208 | if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && | 208 | if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && |
209 | priv->trans->ops->wowlan_suspend && | 209 | priv->trans->ops->d3_suspend && |
210 | priv->trans->ops->d3_resume && | ||
210 | device_can_wakeup(priv->trans->dev)) { | 211 | device_can_wakeup(priv->trans->dev)) { |
211 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | 212 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | |
212 | WIPHY_WOWLAN_DISCONNECT | | 213 | WIPHY_WOWLAN_DISCONNECT | |
@@ -426,7 +427,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
426 | if (ret) | 427 | if (ret) |
427 | goto error; | 428 | goto error; |
428 | 429 | ||
429 | iwl_trans_wowlan_suspend(priv->trans); | 430 | iwl_trans_d3_suspend(priv->trans); |
430 | 431 | ||
431 | goto out; | 432 | goto out; |
432 | 433 | ||
@@ -459,11 +460,11 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
459 | base = priv->device_pointers.error_event_table; | 460 | base = priv->device_pointers.error_event_table; |
460 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 461 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
461 | spin_lock_irqsave(&priv->trans->reg_lock, flags); | 462 | spin_lock_irqsave(&priv->trans->reg_lock, flags); |
462 | ret = iwl_grab_nic_access_silent(priv->trans); | 463 | if (iwl_trans_grab_nic_access(priv->trans, true)) { |
463 | if (likely(ret == 0)) { | ||
464 | iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); | 464 | iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); |
465 | status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); | 465 | status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); |
466 | iwl_release_nic_access(priv->trans); | 466 | iwl_trans_release_nic_access(priv->trans); |
467 | ret = 0; | ||
467 | } | 468 | } |
468 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); | 469 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); |
469 | 470 | ||
@@ -479,7 +480,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
479 | } | 480 | } |
480 | 481 | ||
481 | if (priv->wowlan_sram) | 482 | if (priv->wowlan_sram) |
482 | _iwl_read_targ_mem_dwords( | 483 | iwl_trans_read_mem( |
483 | priv->trans, 0x800000, | 484 | priv->trans, 0x800000, |
484 | priv->wowlan_sram, | 485 | priv->wowlan_sram, |
485 | img->sec[IWL_UCODE_SECTION_DATA].len / 4); | 486 | img->sec[IWL_UCODE_SECTION_DATA].len / 4); |
@@ -520,9 +521,6 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, | |||
520 | { | 521 | { |
521 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 522 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
522 | 523 | ||
523 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | ||
524 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | ||
525 | |||
526 | if (iwlagn_tx_skb(priv, control->sta, skb)) | 524 | if (iwlagn_tx_skb(priv, control->sta, skb)) |
527 | ieee80211_free_txskb(hw, skb); | 525 | ieee80211_free_txskb(hw, skb); |
528 | } | 526 | } |
@@ -679,7 +677,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
679 | IWL_DEBUG_HT(priv, "start Tx\n"); | 677 | IWL_DEBUG_HT(priv, "start Tx\n"); |
680 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 678 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
681 | break; | 679 | break; |
682 | case IEEE80211_AMPDU_TX_STOP: | 680 | case IEEE80211_AMPDU_TX_STOP_CONT: |
681 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
682 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
683 | IWL_DEBUG_HT(priv, "stop Tx\n"); | 683 | IWL_DEBUG_HT(priv, "stop Tx\n"); |
684 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | 684 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); |
685 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | 685 | if ((ret == 0) && (priv->agg_tids_count > 0)) { |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index faa05932efae..a64f361e341c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -354,7 +354,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
354 | 354 | ||
355 | /* Make sure device is powered up for SRAM reads */ | 355 | /* Make sure device is powered up for SRAM reads */ |
356 | spin_lock_irqsave(&priv->trans->reg_lock, reg_flags); | 356 | spin_lock_irqsave(&priv->trans->reg_lock, reg_flags); |
357 | if (unlikely(!iwl_grab_nic_access(priv->trans))) { | 357 | if (!iwl_trans_grab_nic_access(priv->trans, false)) { |
358 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); | 358 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); |
359 | return; | 359 | return; |
360 | } | 360 | } |
@@ -388,7 +388,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
388 | } | 388 | } |
389 | } | 389 | } |
390 | /* Allow device to power down */ | 390 | /* Allow device to power down */ |
391 | iwl_release_nic_access(priv->trans); | 391 | iwl_trans_release_nic_access(priv->trans); |
392 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); | 392 | spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); |
393 | } | 393 | } |
394 | 394 | ||
@@ -408,7 +408,8 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) | |||
408 | 408 | ||
409 | base = priv->device_pointers.log_event_table; | 409 | base = priv->device_pointers.log_event_table; |
410 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 410 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
411 | iwl_read_targ_mem_bytes(priv->trans, base, &read, sizeof(read)); | 411 | iwl_trans_read_mem_bytes(priv->trans, base, |
412 | &read, sizeof(read)); | ||
412 | capacity = read.capacity; | 413 | capacity = read.capacity; |
413 | mode = read.mode; | 414 | mode = read.mode; |
414 | num_wraps = read.wrap_counter; | 415 | num_wraps = read.wrap_counter; |
@@ -1627,7 +1628,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1627 | } | 1628 | } |
1628 | 1629 | ||
1629 | /*TODO: Update dbgfs with ISR error stats obtained below */ | 1630 | /*TODO: Update dbgfs with ISR error stats obtained below */ |
1630 | iwl_read_targ_mem_bytes(trans, base, &table, sizeof(table)); | 1631 | iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); |
1631 | 1632 | ||
1632 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { | 1633 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { |
1633 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); | 1634 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); |
@@ -1717,7 +1718,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1717 | 1718 | ||
1718 | /* Make sure device is powered up for SRAM reads */ | 1719 | /* Make sure device is powered up for SRAM reads */ |
1719 | spin_lock_irqsave(&trans->reg_lock, reg_flags); | 1720 | spin_lock_irqsave(&trans->reg_lock, reg_flags); |
1720 | if (unlikely(!iwl_grab_nic_access(trans))) | 1721 | if (!iwl_trans_grab_nic_access(trans, false)) |
1721 | goto out_unlock; | 1722 | goto out_unlock; |
1722 | 1723 | ||
1723 | /* Set starting address; reads will auto-increment */ | 1724 | /* Set starting address; reads will auto-increment */ |
@@ -1756,7 +1757,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1756 | } | 1757 | } |
1757 | 1758 | ||
1758 | /* Allow device to power down */ | 1759 | /* Allow device to power down */ |
1759 | iwl_release_nic_access(trans); | 1760 | iwl_trans_release_nic_access(trans); |
1760 | out_unlock: | 1761 | out_unlock: |
1761 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); | 1762 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); |
1762 | return pos; | 1763 | return pos; |
@@ -1835,10 +1836,10 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
1835 | } | 1836 | } |
1836 | 1837 | ||
1837 | /* event log header */ | 1838 | /* event log header */ |
1838 | capacity = iwl_read_targ_mem(trans, base); | 1839 | capacity = iwl_trans_read_mem32(trans, base); |
1839 | mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); | 1840 | mode = iwl_trans_read_mem32(trans, base + (1 * sizeof(u32))); |
1840 | num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); | 1841 | num_wraps = iwl_trans_read_mem32(trans, base + (2 * sizeof(u32))); |
1841 | next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); | 1842 | next_entry = iwl_trans_read_mem32(trans, base + (3 * sizeof(u32))); |
1842 | 1843 | ||
1843 | if (capacity > logsize) { | 1844 | if (capacity > logsize) { |
1844 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d " | 1845 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d " |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c index eb864433e59d..b28cfc8553d7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c | |||
@@ -186,8 +186,8 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
186 | } | 186 | } |
187 | iwl_read32(priv->trans, CSR_UCODE_DRV_GP1); | 187 | iwl_read32(priv->trans, CSR_UCODE_DRV_GP1); |
188 | spin_lock_irqsave(&priv->trans->reg_lock, flags); | 188 | spin_lock_irqsave(&priv->trans->reg_lock, flags); |
189 | if (likely(iwl_grab_nic_access(priv->trans))) | 189 | if (iwl_trans_grab_nic_access(priv->trans, false)) |
190 | iwl_release_nic_access(priv->trans); | 190 | iwl_trans_release_nic_access(priv->trans); |
191 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); | 191 | spin_unlock_irqrestore(&priv->trans->reg_lock, flags); |
192 | 192 | ||
193 | /* Reschedule the ct_kill timer to occur in | 193 | /* Reschedule the ct_kill timer to occur in |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a790599fe2c2..6b01fc195940 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -231,13 +231,11 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
231 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); | 231 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); |
232 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 232 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
233 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; | 233 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; |
234 | IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); | ||
235 | break; | 234 | break; |
236 | 235 | ||
237 | case WLAN_CIPHER_SUITE_TKIP: | 236 | case WLAN_CIPHER_SUITE_TKIP: |
238 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; | 237 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; |
239 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); | 238 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); |
240 | IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); | ||
241 | break; | 239 | break; |
242 | 240 | ||
243 | case WLAN_CIPHER_SUITE_WEP104: | 241 | case WLAN_CIPHER_SUITE_WEP104: |
@@ -355,8 +353,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, | |||
355 | } | 353 | } |
356 | } | 354 | } |
357 | 355 | ||
358 | IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); | ||
359 | |||
360 | if (sta) | 356 | if (sta) |
361 | sta_priv = (void *)sta->drv_priv; | 357 | sta_priv = (void *)sta->drv_priv; |
362 | 358 | ||
@@ -472,6 +468,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, | |||
472 | WARN_ON_ONCE(is_agg && | 468 | WARN_ON_ONCE(is_agg && |
473 | priv->queue_to_mac80211[txq_id] != info->hw_queue); | 469 | priv->queue_to_mac80211[txq_id] != info->hw_queue); |
474 | 470 | ||
471 | IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid, | ||
472 | txq_id, seq_number); | ||
473 | |||
475 | if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id)) | 474 | if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id)) |
476 | goto drop_unlock_sta; | 475 | goto drop_unlock_sta; |
477 | 476 | ||
@@ -541,9 +540,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
541 | spin_lock_bh(&priv->sta_lock); | 540 | spin_lock_bh(&priv->sta_lock); |
542 | 541 | ||
543 | tid_data = &priv->tid_data[sta_id][tid]; | 542 | tid_data = &priv->tid_data[sta_id][tid]; |
544 | txq_id = priv->tid_data[sta_id][tid].agg.txq_id; | 543 | txq_id = tid_data->agg.txq_id; |
545 | 544 | ||
546 | switch (priv->tid_data[sta_id][tid].agg.state) { | 545 | switch (tid_data->agg.state) { |
547 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 546 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
548 | /* | 547 | /* |
549 | * This can happen if the peer stops aggregation | 548 | * This can happen if the peer stops aggregation |
@@ -563,9 +562,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
563 | case IWL_AGG_ON: | 562 | case IWL_AGG_ON: |
564 | break; | 563 | break; |
565 | default: | 564 | default: |
566 | IWL_WARN(priv, "Stopping AGG while state not ON " | 565 | IWL_WARN(priv, |
567 | "or starting for %d on %d (%d)\n", sta_id, tid, | 566 | "Stopping AGG while state not ON or starting for %d on %d (%d)\n", |
568 | priv->tid_data[sta_id][tid].agg.state); | 567 | sta_id, tid, tid_data->agg.state); |
569 | spin_unlock_bh(&priv->sta_lock); | 568 | spin_unlock_bh(&priv->sta_lock); |
570 | return 0; | 569 | return 0; |
571 | } | 570 | } |
@@ -578,12 +577,11 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
578 | "stopping AGG on STA/TID %d/%d but hwq %d not used\n", | 577 | "stopping AGG on STA/TID %d/%d but hwq %d not used\n", |
579 | sta_id, tid, txq_id); | 578 | sta_id, tid, txq_id); |
580 | } else if (tid_data->agg.ssn != tid_data->next_reclaimed) { | 579 | } else if (tid_data->agg.ssn != tid_data->next_reclaimed) { |
581 | IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " | 580 | IWL_DEBUG_TX_QUEUES(priv, |
582 | "next_recl = %d\n", | 581 | "Can't proceed: ssn %d, next_recl = %d\n", |
583 | tid_data->agg.ssn, | 582 | tid_data->agg.ssn, |
584 | tid_data->next_reclaimed); | 583 | tid_data->next_reclaimed); |
585 | priv->tid_data[sta_id][tid].agg.state = | 584 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_DELBA; |
586 | IWL_EMPTYING_HW_QUEUE_DELBA; | ||
587 | spin_unlock_bh(&priv->sta_lock); | 585 | spin_unlock_bh(&priv->sta_lock); |
588 | return 0; | 586 | return 0; |
589 | } | 587 | } |
@@ -591,8 +589,8 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
591 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", | 589 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", |
592 | tid_data->agg.ssn); | 590 | tid_data->agg.ssn); |
593 | turn_off: | 591 | turn_off: |
594 | agg_state = priv->tid_data[sta_id][tid].agg.state; | 592 | agg_state = tid_data->agg.state; |
595 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | 593 | tid_data->agg.state = IWL_AGG_OFF; |
596 | 594 | ||
597 | spin_unlock_bh(&priv->sta_lock); | 595 | spin_unlock_bh(&priv->sta_lock); |
598 | 596 | ||
@@ -954,12 +952,6 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, | |||
954 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | | 952 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | |
955 | AGG_TX_STATE_ABORT_MSK)) | 953 | AGG_TX_STATE_ABORT_MSK)) |
956 | continue; | 954 | continue; |
957 | |||
958 | IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), " | ||
959 | "try-count (0x%08x)\n", | ||
960 | iwl_get_agg_tx_fail_reason(fstatus), | ||
961 | fstatus & AGG_TX_STATUS_MSK, | ||
962 | fstatus & AGG_TX_TRY_MSK); | ||
963 | } | 955 | } |
964 | } | 956 | } |
965 | 957 | ||
@@ -1079,6 +1071,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, | |||
1079 | { | 1071 | { |
1080 | u16 status = le16_to_cpu(tx_resp->status.status); | 1072 | u16 status = le16_to_cpu(tx_resp->status.status); |
1081 | 1073 | ||
1074 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
1075 | |||
1082 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1076 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1083 | info->flags |= iwl_tx_status_to_mac80211(status); | 1077 | info->flags |= iwl_tx_status_to_mac80211(status); |
1084 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | 1078 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), |
@@ -1223,16 +1217,27 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1223 | next_reclaimed); | 1217 | next_reclaimed); |
1224 | } | 1218 | } |
1225 | 1219 | ||
1226 | WARN_ON(!is_agg && freed != 1); | 1220 | if (!is_agg && freed != 1) |
1221 | IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed); | ||
1227 | 1222 | ||
1228 | /* | 1223 | /* |
1229 | * An offchannel frame can be send only on the AUX queue, where | 1224 | * An offchannel frame can be send only on the AUX queue, where |
1230 | * there is no aggregation (and reordering) so it only is single | 1225 | * there is no aggregation (and reordering) so it only is single |
1231 | * skb is expected to be processed. | 1226 | * skb is expected to be processed. |
1232 | */ | 1227 | */ |
1233 | WARN_ON(is_offchannel_skb && freed != 1); | 1228 | if (is_offchannel_skb && freed != 1) |
1229 | IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed); | ||
1234 | } | 1230 | } |
1235 | 1231 | ||
1232 | IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id, | ||
1233 | iwl_get_tx_fail_reason(status), status); | ||
1234 | |||
1235 | IWL_DEBUG_TX_REPLY(priv, | ||
1236 | "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n", | ||
1237 | le32_to_cpu(tx_resp->rate_n_flags), | ||
1238 | tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn, | ||
1239 | le16_to_cpu(tx_resp->seq_ctl)); | ||
1240 | |||
1236 | iwl_check_abort_status(priv, tx_resp->frame_count, status); | 1241 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
1237 | spin_unlock(&priv->sta_lock); | 1242 | spin_unlock(&priv->sta_lock); |
1238 | 1243 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index c6467e5554f5..ebec13a3329f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c | |||
@@ -286,89 +286,6 @@ static int iwl_alive_notify(struct iwl_priv *priv) | |||
286 | return iwl_send_calib_results(priv); | 286 | return iwl_send_calib_results(priv); |
287 | } | 287 | } |
288 | 288 | ||
289 | |||
290 | /** | ||
291 | * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, | ||
292 | * using sample data 100 bytes apart. If these sample points are good, | ||
293 | * it's a pretty good bet that everything between them is good, too. | ||
294 | */ | ||
295 | static int iwl_verify_sec_sparse(struct iwl_priv *priv, | ||
296 | const struct fw_desc *fw_desc) | ||
297 | { | ||
298 | __le32 *image = (__le32 *)fw_desc->data; | ||
299 | u32 len = fw_desc->len; | ||
300 | u32 val; | ||
301 | u32 i; | ||
302 | |||
303 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | ||
304 | |||
305 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | ||
306 | /* read data comes through single port, auto-incr addr */ | ||
307 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
308 | * if IWL_DL_IO is set */ | ||
309 | iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR, | ||
310 | i + fw_desc->offset); | ||
311 | val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); | ||
312 | if (val != le32_to_cpu(*image)) | ||
313 | return -EIO; | ||
314 | } | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static void iwl_print_mismatch_sec(struct iwl_priv *priv, | ||
320 | const struct fw_desc *fw_desc) | ||
321 | { | ||
322 | __le32 *image = (__le32 *)fw_desc->data; | ||
323 | u32 len = fw_desc->len; | ||
324 | u32 val; | ||
325 | u32 offs; | ||
326 | int errors = 0; | ||
327 | |||
328 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | ||
329 | |||
330 | iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR, | ||
331 | fw_desc->offset); | ||
332 | |||
333 | for (offs = 0; | ||
334 | offs < len && errors < 20; | ||
335 | offs += sizeof(u32), image++) { | ||
336 | /* read data comes through single port, auto-incr addr */ | ||
337 | val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); | ||
338 | if (val != le32_to_cpu(*image)) { | ||
339 | IWL_ERR(priv, "uCode INST section at " | ||
340 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | ||
341 | offs, val, le32_to_cpu(*image)); | ||
342 | errors++; | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * iwl_verify_ucode - determine which instruction image is in SRAM, | ||
349 | * and verify its contents | ||
350 | */ | ||
351 | static int iwl_verify_ucode(struct iwl_priv *priv, | ||
352 | enum iwl_ucode_type ucode_type) | ||
353 | { | ||
354 | const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); | ||
355 | |||
356 | if (!img) { | ||
357 | IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | |||
361 | if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { | ||
362 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | ||
367 | |||
368 | iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); | ||
369 | return -EIO; | ||
370 | } | ||
371 | |||
372 | struct iwl_alive_data { | 289 | struct iwl_alive_data { |
373 | bool valid; | 290 | bool valid; |
374 | u8 subtype; | 291 | u8 subtype; |
@@ -426,7 +343,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | |||
426 | alive_cmd, ARRAY_SIZE(alive_cmd), | 343 | alive_cmd, ARRAY_SIZE(alive_cmd), |
427 | iwl_alive_fn, &alive_data); | 344 | iwl_alive_fn, &alive_data); |
428 | 345 | ||
429 | ret = iwl_trans_start_fw(priv->trans, fw); | 346 | ret = iwl_trans_start_fw(priv->trans, fw, false); |
430 | if (ret) { | 347 | if (ret) { |
431 | priv->cur_ucode = old_type; | 348 | priv->cur_ucode = old_type; |
432 | iwl_remove_notification(&priv->notif_wait, &alive_wait); | 349 | iwl_remove_notification(&priv->notif_wait, &alive_wait); |
@@ -450,18 +367,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | |||
450 | return -EIO; | 367 | return -EIO; |
451 | } | 368 | } |
452 | 369 | ||
453 | /* | ||
454 | * This step takes a long time (60-80ms!!) and | ||
455 | * WoWLAN image should be loaded quickly, so | ||
456 | * skip it for WoWLAN. | ||
457 | */ | ||
458 | if (ucode_type != IWL_UCODE_WOWLAN) { | 370 | if (ucode_type != IWL_UCODE_WOWLAN) { |
459 | ret = iwl_verify_ucode(priv, ucode_type); | ||
460 | if (ret) { | ||
461 | priv->cur_ucode = old_type; | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /* delay a bit to give rfkill time to run */ | 371 | /* delay a bit to give rfkill time to run */ |
466 | msleep(5); | 372 | msleep(5); |
467 | } | 373 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 34a5287dfc2f..b419a1efac0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -381,8 +381,8 @@ | |||
381 | 381 | ||
382 | /* LED */ | 382 | /* LED */ |
383 | #define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) | 383 | #define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) |
384 | #define CSR_LED_REG_TRUN_ON (0x78) | 384 | #define CSR_LED_REG_TURN_ON (0x60) |
385 | #define CSR_LED_REG_TRUN_OFF (0x38) | 385 | #define CSR_LED_REG_TURN_OFF (0x20) |
386 | 386 | ||
387 | /* ANA_PLL */ | 387 | /* ANA_PLL */ |
388 | #define CSR50_ANA_PLL_CFG_VAL (0x00880300) | 388 | #define CSR50_ANA_PLL_CFG_VAL (0x00880300) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index ec48563d3c6a..c646a90b725e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -225,6 +225,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
225 | #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008) | 225 | #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008) |
226 | #define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG) | 226 | #define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG) |
227 | 227 | ||
228 | #define FW_RSCSR_CHNL0_RXDCB_RDPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x00c) | ||
229 | #define FH_RSCSR_CHNL0_RDPTR FW_RSCSR_CHNL0_RXDCB_RDPTR_REG | ||
228 | 230 | ||
229 | /** | 231 | /** |
230 | * Rx Config/Status Registers (RCSR) | 232 | * Rx Config/Status Registers (RCSR) |
@@ -257,6 +259,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
257 | #define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND) | 259 | #define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND) |
258 | 260 | ||
259 | #define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0) | 261 | #define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0) |
262 | #define FH_MEM_RCSR_CHNL0_RBDCB_WPTR (FH_MEM_RCSR_CHNL0 + 0x8) | ||
263 | #define FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ (FH_MEM_RCSR_CHNL0 + 0x10) | ||
260 | 264 | ||
261 | #define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */ | 265 | #define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */ |
262 | #define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */ | 266 | #define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index cdaff9572059..bff3ac96c00b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -35,12 +35,12 @@ | |||
35 | 35 | ||
36 | #define IWL_POLL_INTERVAL 10 /* microseconds */ | 36 | #define IWL_POLL_INTERVAL 10 /* microseconds */ |
37 | 37 | ||
38 | static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) | 38 | void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
39 | { | 39 | { |
40 | iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); | 40 | iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); |
41 | } | 41 | } |
42 | 42 | ||
43 | static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) | 43 | void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
44 | { | 44 | { |
45 | iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); | 45 | iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); |
46 | } | 46 | } |
@@ -99,86 +99,16 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | |||
99 | } | 99 | } |
100 | EXPORT_SYMBOL_GPL(iwl_poll_bit); | 100 | EXPORT_SYMBOL_GPL(iwl_poll_bit); |
101 | 101 | ||
102 | int iwl_grab_nic_access_silent(struct iwl_trans *trans) | ||
103 | { | ||
104 | int ret; | ||
105 | |||
106 | lockdep_assert_held(&trans->reg_lock); | ||
107 | |||
108 | /* this bit wakes up the NIC */ | ||
109 | __iwl_set_bit(trans, CSR_GP_CNTRL, | ||
110 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
111 | |||
112 | /* | ||
113 | * These bits say the device is running, and should keep running for | ||
114 | * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), | ||
115 | * but they do not indicate that embedded SRAM is restored yet; | ||
116 | * 3945 and 4965 have volatile SRAM, and must save/restore contents | ||
117 | * to/from host DRAM when sleeping/waking for power-saving. | ||
118 | * Each direction takes approximately 1/4 millisecond; with this | ||
119 | * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a | ||
120 | * series of register accesses are expected (e.g. reading Event Log), | ||
121 | * to keep device from sleeping. | ||
122 | * | ||
123 | * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that | ||
124 | * SRAM is okay/restored. We don't check that here because this call | ||
125 | * is just for hardware register access; but GP1 MAC_SLEEP check is a | ||
126 | * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). | ||
127 | * | ||
128 | * 5000 series and later (including 1000 series) have non-volatile SRAM, | ||
129 | * and do not save/restore SRAM when power cycling. | ||
130 | */ | ||
131 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
132 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | ||
133 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | ||
134 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); | ||
135 | if (ret < 0) { | ||
136 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); | ||
137 | return -EIO; | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | EXPORT_SYMBOL_GPL(iwl_grab_nic_access_silent); | ||
143 | |||
144 | bool iwl_grab_nic_access(struct iwl_trans *trans) | ||
145 | { | ||
146 | int ret = iwl_grab_nic_access_silent(trans); | ||
147 | if (unlikely(ret)) { | ||
148 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); | ||
149 | WARN_ONCE(1, "Timeout waiting for hardware access " | ||
150 | "(CSR_GP_CNTRL 0x%08x)\n", val); | ||
151 | return false; | ||
152 | } | ||
153 | |||
154 | return true; | ||
155 | } | ||
156 | EXPORT_SYMBOL_GPL(iwl_grab_nic_access); | ||
157 | |||
158 | void iwl_release_nic_access(struct iwl_trans *trans) | ||
159 | { | ||
160 | lockdep_assert_held(&trans->reg_lock); | ||
161 | __iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
162 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
163 | /* | ||
164 | * Above we read the CSR_GP_CNTRL register, which will flush | ||
165 | * any previous writes, but we need the write that clears the | ||
166 | * MAC_ACCESS_REQ bit to be performed before any other writes | ||
167 | * scheduled on different CPUs (after we drop reg_lock). | ||
168 | */ | ||
169 | mmiowb(); | ||
170 | } | ||
171 | EXPORT_SYMBOL_GPL(iwl_release_nic_access); | ||
172 | |||
173 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | 102 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
174 | { | 103 | { |
175 | u32 value; | 104 | u32 value = 0x5a5a5a5a; |
176 | unsigned long flags; | 105 | unsigned long flags; |
177 | 106 | ||
178 | spin_lock_irqsave(&trans->reg_lock, flags); | 107 | spin_lock_irqsave(&trans->reg_lock, flags); |
179 | iwl_grab_nic_access(trans); | 108 | if (iwl_trans_grab_nic_access(trans, false)) { |
180 | value = iwl_read32(trans, reg); | 109 | value = iwl_read32(trans, reg); |
181 | iwl_release_nic_access(trans); | 110 | iwl_trans_release_nic_access(trans); |
111 | } | ||
182 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 112 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
183 | 113 | ||
184 | return value; | 114 | return value; |
@@ -190,9 +120,9 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | |||
190 | unsigned long flags; | 120 | unsigned long flags; |
191 | 121 | ||
192 | spin_lock_irqsave(&trans->reg_lock, flags); | 122 | spin_lock_irqsave(&trans->reg_lock, flags); |
193 | if (likely(iwl_grab_nic_access(trans))) { | 123 | if (iwl_trans_grab_nic_access(trans, false)) { |
194 | iwl_write32(trans, reg, value); | 124 | iwl_write32(trans, reg, value); |
195 | iwl_release_nic_access(trans); | 125 | iwl_trans_release_nic_access(trans); |
196 | } | 126 | } |
197 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 127 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
198 | } | 128 | } |
@@ -230,12 +160,13 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | |||
230 | u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) | 160 | u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) |
231 | { | 161 | { |
232 | unsigned long flags; | 162 | unsigned long flags; |
233 | u32 val; | 163 | u32 val = 0x5a5a5a5a; |
234 | 164 | ||
235 | spin_lock_irqsave(&trans->reg_lock, flags); | 165 | spin_lock_irqsave(&trans->reg_lock, flags); |
236 | iwl_grab_nic_access(trans); | 166 | if (iwl_trans_grab_nic_access(trans, false)) { |
237 | val = __iwl_read_prph(trans, ofs); | 167 | val = __iwl_read_prph(trans, ofs); |
238 | iwl_release_nic_access(trans); | 168 | iwl_trans_release_nic_access(trans); |
169 | } | ||
239 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 170 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
240 | return val; | 171 | return val; |
241 | } | 172 | } |
@@ -246,9 +177,9 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | |||
246 | unsigned long flags; | 177 | unsigned long flags; |
247 | 178 | ||
248 | spin_lock_irqsave(&trans->reg_lock, flags); | 179 | spin_lock_irqsave(&trans->reg_lock, flags); |
249 | if (likely(iwl_grab_nic_access(trans))) { | 180 | if (iwl_trans_grab_nic_access(trans, false)) { |
250 | __iwl_write_prph(trans, ofs, val); | 181 | __iwl_write_prph(trans, ofs, val); |
251 | iwl_release_nic_access(trans); | 182 | iwl_trans_release_nic_access(trans); |
252 | } | 183 | } |
253 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 184 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
254 | } | 185 | } |
@@ -259,10 +190,10 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | |||
259 | unsigned long flags; | 190 | unsigned long flags; |
260 | 191 | ||
261 | spin_lock_irqsave(&trans->reg_lock, flags); | 192 | spin_lock_irqsave(&trans->reg_lock, flags); |
262 | if (likely(iwl_grab_nic_access(trans))) { | 193 | if (iwl_trans_grab_nic_access(trans, false)) { |
263 | __iwl_write_prph(trans, ofs, | 194 | __iwl_write_prph(trans, ofs, |
264 | __iwl_read_prph(trans, ofs) | mask); | 195 | __iwl_read_prph(trans, ofs) | mask); |
265 | iwl_release_nic_access(trans); | 196 | iwl_trans_release_nic_access(trans); |
266 | } | 197 | } |
267 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 198 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
268 | } | 199 | } |
@@ -274,10 +205,10 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, | |||
274 | unsigned long flags; | 205 | unsigned long flags; |
275 | 206 | ||
276 | spin_lock_irqsave(&trans->reg_lock, flags); | 207 | spin_lock_irqsave(&trans->reg_lock, flags); |
277 | if (likely(iwl_grab_nic_access(trans))) { | 208 | if (iwl_trans_grab_nic_access(trans, false)) { |
278 | __iwl_write_prph(trans, ofs, | 209 | __iwl_write_prph(trans, ofs, |
279 | (__iwl_read_prph(trans, ofs) & mask) | bits); | 210 | (__iwl_read_prph(trans, ofs) & mask) | bits); |
280 | iwl_release_nic_access(trans); | 211 | iwl_trans_release_nic_access(trans); |
281 | } | 212 | } |
282 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 213 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
283 | } | 214 | } |
@@ -289,66 +220,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | |||
289 | u32 val; | 220 | u32 val; |
290 | 221 | ||
291 | spin_lock_irqsave(&trans->reg_lock, flags); | 222 | spin_lock_irqsave(&trans->reg_lock, flags); |
292 | if (likely(iwl_grab_nic_access(trans))) { | 223 | if (iwl_trans_grab_nic_access(trans, false)) { |
293 | val = __iwl_read_prph(trans, ofs); | 224 | val = __iwl_read_prph(trans, ofs); |
294 | __iwl_write_prph(trans, ofs, (val & ~mask)); | 225 | __iwl_write_prph(trans, ofs, (val & ~mask)); |
295 | iwl_release_nic_access(trans); | 226 | iwl_trans_release_nic_access(trans); |
296 | } | 227 | } |
297 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 228 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
298 | } | 229 | } |
299 | EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); | 230 | EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); |
300 | |||
301 | void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
302 | void *buf, int dwords) | ||
303 | { | ||
304 | unsigned long flags; | ||
305 | int offs; | ||
306 | u32 *vals = buf; | ||
307 | |||
308 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
309 | if (likely(iwl_grab_nic_access(trans))) { | ||
310 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | ||
311 | for (offs = 0; offs < dwords; offs++) | ||
312 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | ||
313 | iwl_release_nic_access(trans); | ||
314 | } | ||
315 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
316 | } | ||
317 | EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_dwords); | ||
318 | |||
319 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) | ||
320 | { | ||
321 | u32 value; | ||
322 | |||
323 | _iwl_read_targ_mem_dwords(trans, addr, &value, 1); | ||
324 | |||
325 | return value; | ||
326 | } | ||
327 | EXPORT_SYMBOL_GPL(iwl_read_targ_mem); | ||
328 | |||
329 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
330 | const void *buf, int dwords) | ||
331 | { | ||
332 | unsigned long flags; | ||
333 | int offs, result = 0; | ||
334 | const u32 *vals = buf; | ||
335 | |||
336 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
337 | if (likely(iwl_grab_nic_access(trans))) { | ||
338 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); | ||
339 | for (offs = 0; offs < dwords; offs++) | ||
340 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); | ||
341 | iwl_release_nic_access(trans); | ||
342 | } else | ||
343 | result = -EBUSY; | ||
344 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
345 | |||
346 | return result; | ||
347 | } | ||
348 | EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_dwords); | ||
349 | |||
350 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) | ||
351 | { | ||
352 | return _iwl_write_targ_mem_dwords(trans, addr, &val, 1); | ||
353 | } | ||
354 | EXPORT_SYMBOL_GPL(iwl_write_targ_mem); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 48dc753e3742..dc478068596b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -53,6 +53,8 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) | |||
53 | 53 | ||
54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
56 | void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); | ||
57 | void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); | ||
56 | 58 | ||
57 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); | 59 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); |
58 | 60 | ||
@@ -61,10 +63,6 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | |||
61 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | 63 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
62 | int timeout); | 64 | int timeout); |
63 | 65 | ||
64 | int iwl_grab_nic_access_silent(struct iwl_trans *trans); | ||
65 | bool iwl_grab_nic_access(struct iwl_trans *trans); | ||
66 | void iwl_release_nic_access(struct iwl_trans *trans); | ||
67 | |||
68 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); | 66 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); |
69 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); | 67 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); |
70 | 68 | ||
@@ -76,19 +74,4 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, | |||
76 | u32 bits, u32 mask); | 74 | u32 bits, u32 mask); |
77 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); | 75 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); |
78 | 76 | ||
79 | void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
80 | void *buf, int dwords); | ||
81 | |||
82 | #define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \ | ||
83 | do { \ | ||
84 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ | ||
85 | _iwl_read_targ_mem_dwords(trans, addr, buf, \ | ||
86 | (bufsize) / sizeof(u32));\ | ||
87 | } while (0) | ||
88 | |||
89 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | ||
90 | const void *buf, int dwords); | ||
91 | |||
92 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); | ||
93 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); | ||
94 | #endif | 77 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index 81e8c7126d72..1a226114fe73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c | |||
@@ -467,18 +467,20 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) | |||
467 | if (IWL_ABS_PRPH_START <= addr && | 467 | if (IWL_ABS_PRPH_START <= addr && |
468 | addr < IWL_ABS_PRPH_START + PRPH_END) { | 468 | addr < IWL_ABS_PRPH_START + PRPH_END) { |
469 | spin_lock_irqsave(&trans->reg_lock, flags); | 469 | spin_lock_irqsave(&trans->reg_lock, flags); |
470 | iwl_grab_nic_access(trans); | 470 | if (!iwl_trans_grab_nic_access(trans, false)) { |
471 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
472 | return -EIO; | ||
473 | } | ||
471 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, | 474 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, |
472 | addr | (3 << 24)); | 475 | addr | (3 << 24)); |
473 | for (i = 0; i < size; i += 4) | 476 | for (i = 0; i < size; i += 4) |
474 | *(u32 *)(tst->mem.addr + i) = | 477 | *(u32 *)(tst->mem.addr + i) = |
475 | iwl_read32(trans, HBUS_TARG_PRPH_RDAT); | 478 | iwl_read32(trans, HBUS_TARG_PRPH_RDAT); |
476 | iwl_release_nic_access(trans); | 479 | iwl_trans_release_nic_access(trans); |
477 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 480 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
478 | } else { /* target memory (SRAM) */ | 481 | } else { /* target memory (SRAM) */ |
479 | _iwl_read_targ_mem_dwords(trans, addr, | 482 | iwl_trans_read_mem(trans, addr, tst->mem.addr, |
480 | tst->mem.addr, | 483 | tst->mem.size / 4); |
481 | tst->mem.size / 4); | ||
482 | } | 484 | } |
483 | 485 | ||
484 | tst->mem.nchunks = | 486 | tst->mem.nchunks = |
@@ -501,28 +503,31 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, | |||
501 | 503 | ||
502 | if (IWL_ABS_PRPH_START <= addr && | 504 | if (IWL_ABS_PRPH_START <= addr && |
503 | addr < IWL_ABS_PRPH_START + PRPH_END) { | 505 | addr < IWL_ABS_PRPH_START + PRPH_END) { |
504 | /* Periphery writes can be 1-3 bytes long, or DWORDs */ | 506 | /* Periphery writes can be 1-3 bytes long, or DWORDs */ |
505 | if (size < 4) { | 507 | if (size < 4) { |
506 | memcpy(&val, buf, size); | 508 | memcpy(&val, buf, size); |
507 | spin_lock_irqsave(&trans->reg_lock, flags); | 509 | spin_lock_irqsave(&trans->reg_lock, flags); |
508 | iwl_grab_nic_access(trans); | 510 | if (!iwl_trans_grab_nic_access(trans, false)) { |
509 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, | ||
510 | (addr & 0x0000FFFF) | | ||
511 | ((size - 1) << 24)); | ||
512 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); | ||
513 | iwl_release_nic_access(trans); | ||
514 | /* needed after consecutive writes w/o read */ | ||
515 | mmiowb(); | ||
516 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 511 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
517 | } else { | 512 | return -EIO; |
518 | if (size % 4) | ||
519 | return -EINVAL; | ||
520 | for (i = 0; i < size; i += 4) | ||
521 | iwl_write_prph(trans, addr+i, | ||
522 | *(u32 *)(buf+i)); | ||
523 | } | 513 | } |
514 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, | ||
515 | (addr & 0x0000FFFF) | | ||
516 | ((size - 1) << 24)); | ||
517 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); | ||
518 | iwl_trans_release_nic_access(trans); | ||
519 | /* needed after consecutive writes w/o read */ | ||
520 | mmiowb(); | ||
521 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
522 | } else { | ||
523 | if (size % 4) | ||
524 | return -EINVAL; | ||
525 | for (i = 0; i < size; i += 4) | ||
526 | iwl_write_prph(trans, addr+i, | ||
527 | *(u32 *)(buf+i)); | ||
528 | } | ||
524 | } else if (iwl_test_valid_hw_addr(tst, addr)) { | 529 | } else if (iwl_test_valid_hw_addr(tst, addr)) { |
525 | _iwl_write_targ_mem_dwords(trans, addr, buf, size / 4); | 530 | iwl_trans_write_mem(trans, addr, buf, size / 4); |
526 | } else { | 531 | } else { |
527 | return -EINVAL; | 532 | return -EINVAL; |
528 | } | 533 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b76532e238c1..0f85eb305878 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -308,6 +308,16 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
308 | #define IWL_FRAME_LIMIT 64 | 308 | #define IWL_FRAME_LIMIT 64 |
309 | 309 | ||
310 | /** | 310 | /** |
311 | * enum iwl_wowlan_status - WoWLAN image/device status | ||
312 | * @IWL_D3_STATUS_ALIVE: firmware is still running after resume | ||
313 | * @IWL_D3_STATUS_RESET: device was reset while suspended | ||
314 | */ | ||
315 | enum iwl_d3_status { | ||
316 | IWL_D3_STATUS_ALIVE, | ||
317 | IWL_D3_STATUS_RESET, | ||
318 | }; | ||
319 | |||
320 | /** | ||
311 | * struct iwl_trans_config - transport configuration | 321 | * struct iwl_trans_config - transport configuration |
312 | * | 322 | * |
313 | * @op_mode: pointer to the upper layer. | 323 | * @op_mode: pointer to the upper layer. |
@@ -321,6 +331,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
321 | * @n_no_reclaim_cmds: # of commands in list | 331 | * @n_no_reclaim_cmds: # of commands in list |
322 | * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, | 332 | * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, |
323 | * if unset 4k will be the RX buffer size | 333 | * if unset 4k will be the RX buffer size |
334 | * @bc_table_dword: set to true if the BC table expects the byte count to be | ||
335 | * in DWORD (as opposed to bytes) | ||
324 | * @queue_watchdog_timeout: time (in ms) after which queues | 336 | * @queue_watchdog_timeout: time (in ms) after which queues |
325 | * are considered stuck and will trigger device restart | 337 | * are considered stuck and will trigger device restart |
326 | * @command_names: array of command names, must be 256 entries | 338 | * @command_names: array of command names, must be 256 entries |
@@ -335,6 +347,7 @@ struct iwl_trans_config { | |||
335 | int n_no_reclaim_cmds; | 347 | int n_no_reclaim_cmds; |
336 | 348 | ||
337 | bool rx_buf_size_8k; | 349 | bool rx_buf_size_8k; |
350 | bool bc_table_dword; | ||
338 | unsigned int queue_watchdog_timeout; | 351 | unsigned int queue_watchdog_timeout; |
339 | const char **command_names; | 352 | const char **command_names; |
340 | }; | 353 | }; |
@@ -360,9 +373,12 @@ struct iwl_trans; | |||
360 | * May sleep | 373 | * May sleep |
361 | * @stop_device:stops the whole device (embedded CPU put to reset) | 374 | * @stop_device:stops the whole device (embedded CPU put to reset) |
362 | * May sleep | 375 | * May sleep |
363 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | 376 | * @d3_suspend: put the device into the correct mode for WoWLAN during |
364 | * suspend. This is optional, if not implemented WoWLAN will not be | 377 | * suspend. This is optional, if not implemented WoWLAN will not be |
365 | * supported. This callback may sleep. | 378 | * supported. This callback may sleep. |
379 | * @d3_resume: resume the device after WoWLAN, enabling the opmode to | ||
380 | * talk to the WoWLAN image to get its status. This is optional, if not | ||
381 | * implemented WoWLAN will not be supported. This callback may sleep. | ||
366 | * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. | 382 | * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. |
367 | * If RFkill is asserted in the middle of a SYNC host command, it must | 383 | * If RFkill is asserted in the middle of a SYNC host command, it must |
368 | * return -ERFKILL straight away. | 384 | * return -ERFKILL straight away. |
@@ -387,20 +403,27 @@ struct iwl_trans; | |||
387 | * @read32: read a u32 register at offset ofs from the BAR | 403 | * @read32: read a u32 register at offset ofs from the BAR |
388 | * @read_prph: read a DWORD from a periphery register | 404 | * @read_prph: read a DWORD from a periphery register |
389 | * @write_prph: write a DWORD to a periphery register | 405 | * @write_prph: write a DWORD to a periphery register |
406 | * @read_mem: read device's SRAM in DWORD | ||
407 | * @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory | ||
408 | * will be zeroed. | ||
390 | * @configure: configure parameters required by the transport layer from | 409 | * @configure: configure parameters required by the transport layer from |
391 | * the op_mode. May be called several times before start_fw, can't be | 410 | * the op_mode. May be called several times before start_fw, can't be |
392 | * called after that. | 411 | * called after that. |
393 | * @set_pmi: set the power pmi state | 412 | * @set_pmi: set the power pmi state |
413 | * @grab_nic_access: wake the NIC to be able to access non-HBUS regs | ||
414 | * @release_nic_access: let the NIC go to sleep | ||
394 | */ | 415 | */ |
395 | struct iwl_trans_ops { | 416 | struct iwl_trans_ops { |
396 | 417 | ||
397 | int (*start_hw)(struct iwl_trans *iwl_trans); | 418 | int (*start_hw)(struct iwl_trans *iwl_trans); |
398 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); | 419 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); |
399 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); | 420 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, |
421 | bool run_in_rfkill); | ||
400 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); | 422 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); |
401 | void (*stop_device)(struct iwl_trans *trans); | 423 | void (*stop_device)(struct iwl_trans *trans); |
402 | 424 | ||
403 | void (*wowlan_suspend)(struct iwl_trans *trans); | 425 | void (*d3_suspend)(struct iwl_trans *trans); |
426 | int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status); | ||
404 | 427 | ||
405 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 428 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
406 | 429 | ||
@@ -424,9 +447,15 @@ struct iwl_trans_ops { | |||
424 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); | 447 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); |
425 | u32 (*read_prph)(struct iwl_trans *trans, u32 ofs); | 448 | u32 (*read_prph)(struct iwl_trans *trans, u32 ofs); |
426 | void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val); | 449 | void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val); |
450 | int (*read_mem)(struct iwl_trans *trans, u32 addr, | ||
451 | void *buf, int dwords); | ||
452 | int (*write_mem)(struct iwl_trans *trans, u32 addr, | ||
453 | void *buf, int dwords); | ||
427 | void (*configure)(struct iwl_trans *trans, | 454 | void (*configure)(struct iwl_trans *trans, |
428 | const struct iwl_trans_config *trans_cfg); | 455 | const struct iwl_trans_config *trans_cfg); |
429 | void (*set_pmi)(struct iwl_trans *trans, bool state); | 456 | void (*set_pmi)(struct iwl_trans *trans, bool state); |
457 | bool (*grab_nic_access)(struct iwl_trans *trans, bool silent); | ||
458 | void (*release_nic_access)(struct iwl_trans *trans); | ||
430 | }; | 459 | }; |
431 | 460 | ||
432 | /** | 461 | /** |
@@ -528,13 +557,14 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) | |||
528 | } | 557 | } |
529 | 558 | ||
530 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, | 559 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, |
531 | const struct fw_img *fw) | 560 | const struct fw_img *fw, |
561 | bool run_in_rfkill) | ||
532 | { | 562 | { |
533 | might_sleep(); | 563 | might_sleep(); |
534 | 564 | ||
535 | WARN_ON_ONCE(!trans->rx_mpdu_cmd); | 565 | WARN_ON_ONCE(!trans->rx_mpdu_cmd); |
536 | 566 | ||
537 | return trans->ops->start_fw(trans, fw); | 567 | return trans->ops->start_fw(trans, fw, run_in_rfkill); |
538 | } | 568 | } |
539 | 569 | ||
540 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) | 570 | static inline void iwl_trans_stop_device(struct iwl_trans *trans) |
@@ -546,10 +576,17 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) | |||
546 | trans->state = IWL_TRANS_NO_FW; | 576 | trans->state = IWL_TRANS_NO_FW; |
547 | } | 577 | } |
548 | 578 | ||
549 | static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) | 579 | static inline void iwl_trans_d3_suspend(struct iwl_trans *trans) |
580 | { | ||
581 | might_sleep(); | ||
582 | trans->ops->d3_suspend(trans); | ||
583 | } | ||
584 | |||
585 | static inline int iwl_trans_d3_resume(struct iwl_trans *trans, | ||
586 | enum iwl_d3_status *status) | ||
550 | { | 587 | { |
551 | might_sleep(); | 588 | might_sleep(); |
552 | trans->ops->wowlan_suspend(trans); | 589 | return trans->ops->d3_resume(trans, status); |
553 | } | 590 | } |
554 | 591 | ||
555 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | 592 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, |
@@ -636,7 +673,7 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | |||
636 | } | 673 | } |
637 | 674 | ||
638 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, | 675 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, |
639 | struct dentry *dir) | 676 | struct dentry *dir) |
640 | { | 677 | { |
641 | return trans->ops->dbgfs_register(trans, dir); | 678 | return trans->ops->dbgfs_register(trans, dir); |
642 | } | 679 | } |
@@ -679,11 +716,57 @@ static inline void iwl_trans_write_prph(struct iwl_trans *trans, u32 ofs, | |||
679 | return trans->ops->write_prph(trans, ofs, val); | 716 | return trans->ops->write_prph(trans, ofs, val); |
680 | } | 717 | } |
681 | 718 | ||
719 | static inline int iwl_trans_read_mem(struct iwl_trans *trans, u32 addr, | ||
720 | void *buf, int dwords) | ||
721 | { | ||
722 | return trans->ops->read_mem(trans, addr, buf, dwords); | ||
723 | } | ||
724 | |||
725 | #define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \ | ||
726 | do { \ | ||
727 | if (__builtin_constant_p(bufsize)) \ | ||
728 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ | ||
729 | iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\ | ||
730 | } while (0) | ||
731 | |||
732 | static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr) | ||
733 | { | ||
734 | u32 value; | ||
735 | |||
736 | if (WARN_ON(iwl_trans_read_mem(trans, addr, &value, 1))) | ||
737 | return 0xa5a5a5a5; | ||
738 | |||
739 | return value; | ||
740 | } | ||
741 | |||
742 | static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, | ||
743 | void *buf, int dwords) | ||
744 | { | ||
745 | return trans->ops->write_mem(trans, addr, buf, dwords); | ||
746 | } | ||
747 | |||
748 | static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr, | ||
749 | u32 val) | ||
750 | { | ||
751 | return iwl_trans_write_mem(trans, addr, &val, 1); | ||
752 | } | ||
753 | |||
682 | static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) | 754 | static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) |
683 | { | 755 | { |
684 | trans->ops->set_pmi(trans, state); | 756 | trans->ops->set_pmi(trans, state); |
685 | } | 757 | } |
686 | 758 | ||
759 | #define iwl_trans_grab_nic_access(trans, silent) \ | ||
760 | __cond_lock(nic_access, \ | ||
761 | likely((trans)->ops->grab_nic_access(trans, silent))) | ||
762 | |||
763 | static inline void __releases(nic_access) | ||
764 | iwl_trans_release_nic_access(struct iwl_trans *trans) | ||
765 | { | ||
766 | trans->ops->release_nic_access(trans); | ||
767 | __release(nic_access); | ||
768 | } | ||
769 | |||
687 | /***************************************************** | 770 | /***************************************************** |
688 | * driver (transport) register/unregister functions | 771 | * driver (transport) register/unregister functions |
689 | ******************************************************/ | 772 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index d91d2e8c62f5..20735a008cab 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -222,8 +222,6 @@ struct iwl_txq { | |||
222 | * @rx_replenish: work that will be called when buffers need to be allocated | 222 | * @rx_replenish: work that will be called when buffers need to be allocated |
223 | * @drv - pointer to iwl_drv | 223 | * @drv - pointer to iwl_drv |
224 | * @trans: pointer to the generic transport area | 224 | * @trans: pointer to the generic transport area |
225 | * @irq - the irq number for the device | ||
226 | * @irq_requested: true when the irq has been requested | ||
227 | * @scd_base_addr: scheduler sram base address in SRAM | 225 | * @scd_base_addr: scheduler sram base address in SRAM |
228 | * @scd_bc_tbls: pointer to the byte count table of the scheduler | 226 | * @scd_bc_tbls: pointer to the byte count table of the scheduler |
229 | * @kw: keep warm address | 227 | * @kw: keep warm address |
@@ -234,6 +232,7 @@ struct iwl_txq { | |||
234 | * @status - transport specific status flags | 232 | * @status - transport specific status flags |
235 | * @cmd_queue - command queue number | 233 | * @cmd_queue - command queue number |
236 | * @rx_buf_size_8k: 8 kB RX buffer size | 234 | * @rx_buf_size_8k: 8 kB RX buffer size |
235 | * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) | ||
237 | * @rx_page_order: page order for receive buffer size | 236 | * @rx_page_order: page order for receive buffer size |
238 | * @wd_timeout: queue watchdog timeout (jiffies) | 237 | * @wd_timeout: queue watchdog timeout (jiffies) |
239 | */ | 238 | */ |
@@ -249,11 +248,9 @@ struct iwl_trans_pcie { | |||
249 | int ict_index; | 248 | int ict_index; |
250 | u32 inta; | 249 | u32 inta; |
251 | bool use_ict; | 250 | bool use_ict; |
252 | bool irq_requested; | ||
253 | struct tasklet_struct irq_tasklet; | 251 | struct tasklet_struct irq_tasklet; |
254 | struct isr_statistics isr_stats; | 252 | struct isr_statistics isr_stats; |
255 | 253 | ||
256 | unsigned int irq; | ||
257 | spinlock_t irq_lock; | 254 | spinlock_t irq_lock; |
258 | u32 inta_mask; | 255 | u32 inta_mask; |
259 | u32 scd_base_addr; | 256 | u32 scd_base_addr; |
@@ -279,6 +276,7 @@ struct iwl_trans_pcie { | |||
279 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; | 276 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; |
280 | 277 | ||
281 | bool rx_buf_size_8k; | 278 | bool rx_buf_size_8k; |
279 | bool bc_table_dword; | ||
282 | u32 rx_page_order; | 280 | u32 rx_page_order; |
283 | 281 | ||
284 | const char **command_names; | 282 | const char **command_names; |
@@ -359,6 +357,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, | |||
359 | struct iwl_rx_cmd_buffer *rxb, int handler_status); | 357 | struct iwl_rx_cmd_buffer *rxb, int handler_status); |
360 | void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | 358 | void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, |
361 | struct sk_buff_head *skbs); | 359 | struct sk_buff_head *skbs); |
360 | void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); | ||
361 | |||
362 | /***************************************************** | 362 | /***************************************************** |
363 | * Error handling | 363 | * Error handling |
364 | ******************************************************/ | 364 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 8389cd38338b..4e6591d24e61 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -436,7 +436,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) | |||
436 | err_rb_stts: | 436 | err_rb_stts: |
437 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | 437 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, |
438 | rxq->bd, rxq->bd_dma); | 438 | rxq->bd, rxq->bd_dma); |
439 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | 439 | rxq->bd_dma = 0; |
440 | rxq->bd = NULL; | 440 | rxq->bd = NULL; |
441 | err_bd: | 441 | err_bd: |
442 | return -ENOMEM; | 442 | return -ENOMEM; |
@@ -455,6 +455,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) | |||
455 | 455 | ||
456 | /* Stop Rx DMA */ | 456 | /* Stop Rx DMA */ |
457 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | 457 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); |
458 | /* reset and flush pointers */ | ||
459 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0); | ||
460 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0); | ||
461 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RDPTR, 0); | ||
458 | 462 | ||
459 | /* Reset driver's Rx queue write index */ | 463 | /* Reset driver's Rx queue write index */ |
460 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | 464 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); |
@@ -491,7 +495,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
491 | { | 495 | { |
492 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 496 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
493 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 497 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
494 | |||
495 | int i, err; | 498 | int i, err; |
496 | unsigned long flags; | 499 | unsigned long flags; |
497 | 500 | ||
@@ -518,6 +521,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
518 | rxq->read = rxq->write = 0; | 521 | rxq->read = rxq->write = 0; |
519 | rxq->write_actual = 0; | 522 | rxq->write_actual = 0; |
520 | rxq->free_count = 0; | 523 | rxq->free_count = 0; |
524 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); | ||
521 | spin_unlock_irqrestore(&rxq->lock, flags); | 525 | spin_unlock_irqrestore(&rxq->lock, flags); |
522 | 526 | ||
523 | iwl_pcie_rx_replenish(trans); | 527 | iwl_pcie_rx_replenish(trans); |
@@ -545,13 +549,15 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
545 | return; | 549 | return; |
546 | } | 550 | } |
547 | 551 | ||
552 | cancel_work_sync(&trans_pcie->rx_replenish); | ||
553 | |||
548 | spin_lock_irqsave(&rxq->lock, flags); | 554 | spin_lock_irqsave(&rxq->lock, flags); |
549 | iwl_pcie_rxq_free_rbs(trans); | 555 | iwl_pcie_rxq_free_rbs(trans); |
550 | spin_unlock_irqrestore(&rxq->lock, flags); | 556 | spin_unlock_irqrestore(&rxq->lock, flags); |
551 | 557 | ||
552 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, | 558 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, |
553 | rxq->bd, rxq->bd_dma); | 559 | rxq->bd, rxq->bd_dma); |
554 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | 560 | rxq->bd_dma = 0; |
555 | rxq->bd = NULL; | 561 | rxq->bd = NULL; |
556 | 562 | ||
557 | if (rxq->rb_stts) | 563 | if (rxq->rb_stts) |
@@ -560,7 +566,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
560 | rxq->rb_stts, rxq->rb_stts_dma); | 566 | rxq->rb_stts, rxq->rb_stts_dma); |
561 | else | 567 | else |
562 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); | 568 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); |
563 | memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); | 569 | rxq->rb_stts_dma = 0; |
564 | rxq->rb_stts = NULL; | 570 | rxq->rb_stts = NULL; |
565 | } | 571 | } |
566 | 572 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 35708b959ad6..c57641eb83d5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -75,21 +75,16 @@ | |||
75 | #include "iwl-agn-hw.h" | 75 | #include "iwl-agn-hw.h" |
76 | #include "internal.h" | 76 | #include "internal.h" |
77 | 77 | ||
78 | static void iwl_pcie_set_pwr_vmain(struct iwl_trans *trans) | 78 | static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) |
79 | { | 79 | { |
80 | /* | 80 | if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) |
81 | * (for documentation purposes) | 81 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, |
82 | * to set power to V_AUX, do: | 82 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, |
83 | 83 | ~APMG_PS_CTRL_MSK_PWR_SRC); | |
84 | if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) | 84 | else |
85 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, | 85 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, |
86 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, | 86 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, |
87 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 87 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
88 | */ | ||
89 | |||
90 | iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, | ||
91 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, | ||
92 | ~APMG_PS_CTRL_MSK_PWR_SRC); | ||
93 | } | 88 | } |
94 | 89 | ||
95 | /* PCI registers */ | 90 | /* PCI registers */ |
@@ -259,7 +254,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) | |||
259 | 254 | ||
260 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 255 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
261 | 256 | ||
262 | iwl_pcie_set_pwr_vmain(trans); | 257 | iwl_pcie_set_pwr(trans, false); |
263 | 258 | ||
264 | iwl_op_mode_nic_config(trans->op_mode); | 259 | iwl_op_mode_nic_config(trans->op_mode); |
265 | 260 | ||
@@ -435,7 +430,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, | |||
435 | } | 430 | } |
436 | 431 | ||
437 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | 432 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, |
438 | const struct fw_img *fw) | 433 | const struct fw_img *fw, bool run_in_rfkill) |
439 | { | 434 | { |
440 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 435 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
441 | int ret; | 436 | int ret; |
@@ -454,7 +449,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | |||
454 | /* If platform's RF_KILL switch is NOT set to KILL */ | 449 | /* If platform's RF_KILL switch is NOT set to KILL */ |
455 | hw_rfkill = iwl_is_rfkill_set(trans); | 450 | hw_rfkill = iwl_is_rfkill_set(trans); |
456 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 451 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
457 | if (hw_rfkill) | 452 | if (hw_rfkill && !run_in_rfkill) |
458 | return -ERFKILL; | 453 | return -ERFKILL; |
459 | 454 | ||
460 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | 455 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
@@ -534,12 +529,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
534 | 529 | ||
535 | iwl_enable_rfkill_int(trans); | 530 | iwl_enable_rfkill_int(trans); |
536 | 531 | ||
537 | /* wait to make sure we flush pending tasklet*/ | ||
538 | synchronize_irq(trans_pcie->irq); | ||
539 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
540 | |||
541 | cancel_work_sync(&trans_pcie->rx_replenish); | ||
542 | |||
543 | /* stop and reset the on-board processor */ | 532 | /* stop and reset the on-board processor */ |
544 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 533 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
545 | 534 | ||
@@ -551,46 +540,87 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
551 | clear_bit(STATUS_RFKILL, &trans_pcie->status); | 540 | clear_bit(STATUS_RFKILL, &trans_pcie->status); |
552 | } | 541 | } |
553 | 542 | ||
554 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | 543 | static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans) |
555 | { | 544 | { |
556 | /* let the ucode operate on its own */ | 545 | /* let the ucode operate on its own */ |
557 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, | 546 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, |
558 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | 547 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); |
559 | 548 | ||
560 | iwl_disable_interrupts(trans); | 549 | iwl_disable_interrupts(trans); |
550 | iwl_pcie_disable_ict(trans); | ||
551 | |||
561 | iwl_clear_bit(trans, CSR_GP_CNTRL, | 552 | iwl_clear_bit(trans, CSR_GP_CNTRL, |
562 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 553 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
554 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
555 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
556 | |||
557 | /* | ||
558 | * reset TX queues -- some of their registers reset during S3 | ||
559 | * so if we don't reset everything here the D3 image would try | ||
560 | * to execute some invalid memory upon resume | ||
561 | */ | ||
562 | iwl_trans_pcie_tx_reset(trans); | ||
563 | |||
564 | iwl_pcie_set_pwr(trans, true); | ||
563 | } | 565 | } |
564 | 566 | ||
565 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | 567 | static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, |
568 | enum iwl_d3_status *status) | ||
566 | { | 569 | { |
567 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 570 | u32 val; |
568 | int err; | 571 | int ret; |
569 | bool hw_rfkill; | ||
570 | 572 | ||
571 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | 573 | iwl_pcie_set_pwr(trans, false); |
572 | 574 | ||
573 | if (!trans_pcie->irq_requested) { | 575 | val = iwl_read32(trans, CSR_RESET); |
574 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) | 576 | if (val & CSR_RESET_REG_FLAG_NEVO_RESET) { |
575 | iwl_pcie_tasklet, (unsigned long)trans); | 577 | *status = IWL_D3_STATUS_RESET; |
578 | return 0; | ||
579 | } | ||
576 | 580 | ||
577 | iwl_pcie_alloc_ict(trans); | 581 | /* |
582 | * Also enables interrupts - none will happen as the device doesn't | ||
583 | * know we're waking it up, only when the opmode actually tells it | ||
584 | * after this call. | ||
585 | */ | ||
586 | iwl_pcie_reset_ict(trans); | ||
578 | 587 | ||
579 | err = request_irq(trans_pcie->irq, iwl_pcie_isr_ict, | 588 | iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
580 | IRQF_SHARED, DRV_NAME, trans); | 589 | iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
581 | if (err) { | ||
582 | IWL_ERR(trans, "Error allocating IRQ %d\n", | ||
583 | trans_pcie->irq); | ||
584 | goto error; | ||
585 | } | ||
586 | 590 | ||
587 | trans_pcie->irq_requested = true; | 591 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, |
592 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
593 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
594 | 25000); | ||
595 | if (ret) { | ||
596 | IWL_ERR(trans, "Failed to resume the device (mac ready)\n"); | ||
597 | return ret; | ||
588 | } | 598 | } |
589 | 599 | ||
600 | iwl_trans_pcie_tx_reset(trans); | ||
601 | |||
602 | ret = iwl_pcie_rx_init(trans); | ||
603 | if (ret) { | ||
604 | IWL_ERR(trans, "Failed to resume the device (RX reset)\n"); | ||
605 | return ret; | ||
606 | } | ||
607 | |||
608 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, | ||
609 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
610 | |||
611 | *status = IWL_D3_STATUS_ALIVE; | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | ||
616 | { | ||
617 | bool hw_rfkill; | ||
618 | int err; | ||
619 | |||
590 | err = iwl_pcie_prepare_card_hw(trans); | 620 | err = iwl_pcie_prepare_card_hw(trans); |
591 | if (err) { | 621 | if (err) { |
592 | IWL_ERR(trans, "Error while preparing HW: %d\n", err); | 622 | IWL_ERR(trans, "Error while preparing HW: %d\n", err); |
593 | goto err_free_irq; | 623 | return err; |
594 | } | 624 | } |
595 | 625 | ||
596 | iwl_pcie_apm_init(trans); | 626 | iwl_pcie_apm_init(trans); |
@@ -601,15 +631,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
601 | hw_rfkill = iwl_is_rfkill_set(trans); | 631 | hw_rfkill = iwl_is_rfkill_set(trans); |
602 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 632 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
603 | 633 | ||
604 | return err; | 634 | return 0; |
605 | |||
606 | err_free_irq: | ||
607 | trans_pcie->irq_requested = false; | ||
608 | free_irq(trans_pcie->irq, trans); | ||
609 | error: | ||
610 | iwl_pcie_free_ict(trans); | ||
611 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
612 | return err; | ||
613 | } | 635 | } |
614 | 636 | ||
615 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, | 637 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, |
@@ -703,19 +725,21 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, | |||
703 | msecs_to_jiffies(trans_cfg->queue_watchdog_timeout); | 725 | msecs_to_jiffies(trans_cfg->queue_watchdog_timeout); |
704 | 726 | ||
705 | trans_pcie->command_names = trans_cfg->command_names; | 727 | trans_pcie->command_names = trans_cfg->command_names; |
728 | trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; | ||
706 | } | 729 | } |
707 | 730 | ||
708 | void iwl_trans_pcie_free(struct iwl_trans *trans) | 731 | void iwl_trans_pcie_free(struct iwl_trans *trans) |
709 | { | 732 | { |
710 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 733 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
711 | 734 | ||
735 | synchronize_irq(trans_pcie->pci_dev->irq); | ||
736 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
737 | |||
712 | iwl_pcie_tx_free(trans); | 738 | iwl_pcie_tx_free(trans); |
713 | iwl_pcie_rx_free(trans); | 739 | iwl_pcie_rx_free(trans); |
714 | 740 | ||
715 | if (trans_pcie->irq_requested == true) { | 741 | free_irq(trans_pcie->pci_dev->irq, trans); |
716 | free_irq(trans_pcie->irq, trans); | 742 | iwl_pcie_free_ict(trans); |
717 | iwl_pcie_free_ict(trans); | ||
718 | } | ||
719 | 743 | ||
720 | pci_disable_msi(trans_pcie->pci_dev); | 744 | pci_disable_msi(trans_pcie->pci_dev); |
721 | iounmap(trans_pcie->hw_base); | 745 | iounmap(trans_pcie->hw_base); |
@@ -751,13 +775,112 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
751 | hw_rfkill = iwl_is_rfkill_set(trans); | 775 | hw_rfkill = iwl_is_rfkill_set(trans); |
752 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 776 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
753 | 777 | ||
754 | if (!hw_rfkill) | ||
755 | iwl_enable_interrupts(trans); | ||
756 | |||
757 | return 0; | 778 | return 0; |
758 | } | 779 | } |
759 | #endif /* CONFIG_PM_SLEEP */ | 780 | #endif /* CONFIG_PM_SLEEP */ |
760 | 781 | ||
782 | static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) | ||
783 | { | ||
784 | int ret; | ||
785 | |||
786 | lockdep_assert_held(&trans->reg_lock); | ||
787 | |||
788 | /* this bit wakes up the NIC */ | ||
789 | __iwl_set_bit(trans, CSR_GP_CNTRL, | ||
790 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
791 | |||
792 | /* | ||
793 | * These bits say the device is running, and should keep running for | ||
794 | * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), | ||
795 | * but they do not indicate that embedded SRAM is restored yet; | ||
796 | * 3945 and 4965 have volatile SRAM, and must save/restore contents | ||
797 | * to/from host DRAM when sleeping/waking for power-saving. | ||
798 | * Each direction takes approximately 1/4 millisecond; with this | ||
799 | * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a | ||
800 | * series of register accesses are expected (e.g. reading Event Log), | ||
801 | * to keep device from sleeping. | ||
802 | * | ||
803 | * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that | ||
804 | * SRAM is okay/restored. We don't check that here because this call | ||
805 | * is just for hardware register access; but GP1 MAC_SLEEP check is a | ||
806 | * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). | ||
807 | * | ||
808 | * 5000 series and later (including 1000 series) have non-volatile SRAM, | ||
809 | * and do not save/restore SRAM when power cycling. | ||
810 | */ | ||
811 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
812 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | ||
813 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | ||
814 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); | ||
815 | if (unlikely(ret < 0)) { | ||
816 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); | ||
817 | if (!silent) { | ||
818 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); | ||
819 | WARN_ONCE(1, | ||
820 | "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", | ||
821 | val); | ||
822 | return false; | ||
823 | } | ||
824 | } | ||
825 | |||
826 | return true; | ||
827 | } | ||
828 | |||
829 | static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) | ||
830 | { | ||
831 | lockdep_assert_held(&trans->reg_lock); | ||
832 | __iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
833 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
834 | /* | ||
835 | * Above we read the CSR_GP_CNTRL register, which will flush | ||
836 | * any previous writes, but we need the write that clears the | ||
837 | * MAC_ACCESS_REQ bit to be performed before any other writes | ||
838 | * scheduled on different CPUs (after we drop reg_lock). | ||
839 | */ | ||
840 | mmiowb(); | ||
841 | } | ||
842 | |||
843 | static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, | ||
844 | void *buf, int dwords) | ||
845 | { | ||
846 | unsigned long flags; | ||
847 | int offs, ret = 0; | ||
848 | u32 *vals = buf; | ||
849 | |||
850 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
851 | if (iwl_trans_grab_nic_access(trans, false)) { | ||
852 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | ||
853 | for (offs = 0; offs < dwords; offs++) | ||
854 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | ||
855 | iwl_trans_release_nic_access(trans); | ||
856 | } else { | ||
857 | ret = -EBUSY; | ||
858 | } | ||
859 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
860 | return ret; | ||
861 | } | ||
862 | |||
863 | static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, | ||
864 | void *buf, int dwords) | ||
865 | { | ||
866 | unsigned long flags; | ||
867 | int offs, ret = 0; | ||
868 | u32 *vals = buf; | ||
869 | |||
870 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
871 | if (iwl_trans_grab_nic_access(trans, false)) { | ||
872 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); | ||
873 | for (offs = 0; offs < dwords; offs++) | ||
874 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, | ||
875 | vals ? vals[offs] : 0); | ||
876 | iwl_trans_release_nic_access(trans); | ||
877 | } else { | ||
878 | ret = -EBUSY; | ||
879 | } | ||
880 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
881 | return ret; | ||
882 | } | ||
883 | |||
761 | #define IWL_FLUSH_WAIT_MS 2000 | 884 | #define IWL_FLUSH_WAIT_MS 2000 |
762 | 885 | ||
763 | static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | 886 | static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) |
@@ -767,6 +890,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | |||
767 | struct iwl_queue *q; | 890 | struct iwl_queue *q; |
768 | int cnt; | 891 | int cnt; |
769 | unsigned long now = jiffies; | 892 | unsigned long now = jiffies; |
893 | u32 scd_sram_addr; | ||
894 | u8 buf[16]; | ||
770 | int ret = 0; | 895 | int ret = 0; |
771 | 896 | ||
772 | /* waiting for all the tx frames complete might take a while */ | 897 | /* waiting for all the tx frames complete might take a while */ |
@@ -780,11 +905,50 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | |||
780 | msleep(1); | 905 | msleep(1); |
781 | 906 | ||
782 | if (q->read_ptr != q->write_ptr) { | 907 | if (q->read_ptr != q->write_ptr) { |
783 | IWL_ERR(trans, "fail to flush all tx fifo queues\n"); | 908 | IWL_ERR(trans, |
909 | "fail to flush all tx fifo queues Q %d\n", cnt); | ||
784 | ret = -ETIMEDOUT; | 910 | ret = -ETIMEDOUT; |
785 | break; | 911 | break; |
786 | } | 912 | } |
787 | } | 913 | } |
914 | |||
915 | if (!ret) | ||
916 | return 0; | ||
917 | |||
918 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | ||
919 | txq->q.read_ptr, txq->q.write_ptr); | ||
920 | |||
921 | scd_sram_addr = trans_pcie->scd_base_addr + | ||
922 | SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); | ||
923 | iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | ||
924 | |||
925 | iwl_print_hex_error(trans, buf, sizeof(buf)); | ||
926 | |||
927 | for (cnt = 0; cnt < FH_TCSR_CHNL_NUM; cnt++) | ||
928 | IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", cnt, | ||
929 | iwl_read_direct32(trans, FH_TX_TRB_REG(cnt))); | ||
930 | |||
931 | for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) { | ||
932 | u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(cnt)); | ||
933 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | ||
934 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | ||
935 | u32 tbl_dw = | ||
936 | iwl_trans_read_mem32(trans, trans_pcie->scd_base_addr + | ||
937 | SCD_TRANS_TBL_OFFSET_QUEUE(cnt)); | ||
938 | |||
939 | if (cnt & 0x1) | ||
940 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | ||
941 | else | ||
942 | tbl_dw = tbl_dw & 0x0000FFFF; | ||
943 | |||
944 | IWL_ERR(trans, | ||
945 | "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", | ||
946 | cnt, active ? "" : "in", fifo, tbl_dw, | ||
947 | iwl_read_prph(trans, | ||
948 | SCD_QUEUE_RDPTR(cnt)) & (txq->q.n_bd - 1), | ||
949 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); | ||
950 | } | ||
951 | |||
788 | return ret; | 952 | return ret; |
789 | } | 953 | } |
790 | 954 | ||
@@ -1212,7 +1376,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
1212 | .start_fw = iwl_trans_pcie_start_fw, | 1376 | .start_fw = iwl_trans_pcie_start_fw, |
1213 | .stop_device = iwl_trans_pcie_stop_device, | 1377 | .stop_device = iwl_trans_pcie_stop_device, |
1214 | 1378 | ||
1215 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, | 1379 | .d3_suspend = iwl_trans_pcie_d3_suspend, |
1380 | .d3_resume = iwl_trans_pcie_d3_resume, | ||
1216 | 1381 | ||
1217 | .send_cmd = iwl_trans_pcie_send_hcmd, | 1382 | .send_cmd = iwl_trans_pcie_send_hcmd, |
1218 | 1383 | ||
@@ -1235,8 +1400,12 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
1235 | .read32 = iwl_trans_pcie_read32, | 1400 | .read32 = iwl_trans_pcie_read32, |
1236 | .read_prph = iwl_trans_pcie_read_prph, | 1401 | .read_prph = iwl_trans_pcie_read_prph, |
1237 | .write_prph = iwl_trans_pcie_write_prph, | 1402 | .write_prph = iwl_trans_pcie_write_prph, |
1403 | .read_mem = iwl_trans_pcie_read_mem, | ||
1404 | .write_mem = iwl_trans_pcie_write_mem, | ||
1238 | .configure = iwl_trans_pcie_configure, | 1405 | .configure = iwl_trans_pcie_configure, |
1239 | .set_pmi = iwl_trans_pcie_set_pmi, | 1406 | .set_pmi = iwl_trans_pcie_set_pmi, |
1407 | .grab_nic_access = iwl_trans_pcie_grab_nic_access, | ||
1408 | .release_nic_access = iwl_trans_pcie_release_nic_access | ||
1240 | }; | 1409 | }; |
1241 | 1410 | ||
1242 | struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | 1411 | struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, |
@@ -1318,7 +1487,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1318 | } | 1487 | } |
1319 | 1488 | ||
1320 | trans->dev = &pdev->dev; | 1489 | trans->dev = &pdev->dev; |
1321 | trans_pcie->irq = pdev->irq; | ||
1322 | trans_pcie->pci_dev = pdev; | 1490 | trans_pcie->pci_dev = pdev; |
1323 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); | 1491 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); |
1324 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | 1492 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; |
@@ -1344,8 +1512,27 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1344 | if (!trans->dev_cmd_pool) | 1512 | if (!trans->dev_cmd_pool) |
1345 | goto out_pci_disable_msi; | 1513 | goto out_pci_disable_msi; |
1346 | 1514 | ||
1515 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | ||
1516 | |||
1517 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) | ||
1518 | iwl_pcie_tasklet, (unsigned long)trans); | ||
1519 | |||
1520 | if (iwl_pcie_alloc_ict(trans)) | ||
1521 | goto out_free_cmd_pool; | ||
1522 | |||
1523 | err = request_irq(pdev->irq, iwl_pcie_isr_ict, | ||
1524 | IRQF_SHARED, DRV_NAME, trans); | ||
1525 | if (err) { | ||
1526 | IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); | ||
1527 | goto out_free_ict; | ||
1528 | } | ||
1529 | |||
1347 | return trans; | 1530 | return trans; |
1348 | 1531 | ||
1532 | out_free_ict: | ||
1533 | iwl_pcie_free_ict(trans); | ||
1534 | out_free_cmd_pool: | ||
1535 | kmem_cache_destroy(trans->dev_cmd_pool); | ||
1349 | out_pci_disable_msi: | 1536 | out_pci_disable_msi: |
1350 | pci_disable_msi(pdev); | 1537 | pci_disable_msi(pdev); |
1351 | out_pci_release_regions: | 1538 | out_pci_release_regions: |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 6c5b867c353a..a93f06762b96 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -160,7 +160,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
160 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | 160 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", |
161 | txq->q.read_ptr, txq->q.write_ptr); | 161 | txq->q.read_ptr, txq->q.write_ptr); |
162 | 162 | ||
163 | iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | 163 | iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); |
164 | 164 | ||
165 | iwl_print_hex_error(trans, buf, sizeof(buf)); | 165 | iwl_print_hex_error(trans, buf, sizeof(buf)); |
166 | 166 | ||
@@ -173,9 +173,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
173 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | 173 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; |
174 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | 174 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); |
175 | u32 tbl_dw = | 175 | u32 tbl_dw = |
176 | iwl_read_targ_mem(trans, | 176 | iwl_trans_read_mem32(trans, |
177 | trans_pcie->scd_base_addr + | 177 | trans_pcie->scd_base_addr + |
178 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); | 178 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); |
179 | 179 | ||
180 | if (i & 0x1) | 180 | if (i & 0x1) |
181 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | 181 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; |
@@ -237,7 +237,10 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | |||
237 | break; | 237 | break; |
238 | } | 238 | } |
239 | 239 | ||
240 | bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); | 240 | if (trans_pcie->bc_table_dword) |
241 | len = DIV_ROUND_UP(len, 4); | ||
242 | |||
243 | bc_ent = cpu_to_le16(len | (sta_id << 12)); | ||
241 | 244 | ||
242 | scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; | 245 | scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; |
243 | 246 | ||
@@ -306,6 +309,9 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) | |||
306 | return; | 309 | return; |
307 | } | 310 | } |
308 | 311 | ||
312 | IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, | ||
313 | txq->q.write_ptr); | ||
314 | |||
309 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 315 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
310 | txq->q.write_ptr | (txq_id << 8)); | 316 | txq->q.write_ptr | (txq_id << 8)); |
311 | 317 | ||
@@ -612,7 +618,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | |||
612 | if (txq->q.n_bd) { | 618 | if (txq->q.n_bd) { |
613 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * | 619 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * |
614 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | 620 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); |
615 | memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr)); | 621 | txq->q.dma_addr = 0; |
616 | } | 622 | } |
617 | 623 | ||
618 | kfree(txq->entries); | 624 | kfree(txq->entries); |
@@ -638,9 +644,11 @@ static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) | |||
638 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | 644 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) |
639 | { | 645 | { |
640 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 646 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
641 | u32 a; | 647 | int nq = trans->cfg->base_params->num_of_queues; |
642 | int chan; | 648 | int chan; |
643 | u32 reg_val; | 649 | u32 reg_val; |
650 | int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) - | ||
651 | SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(u32); | ||
644 | 652 | ||
645 | /* make sure all queue are not stopped/used */ | 653 | /* make sure all queue are not stopped/used */ |
646 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | 654 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); |
@@ -652,20 +660,10 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | |||
652 | WARN_ON(scd_base_addr != 0 && | 660 | WARN_ON(scd_base_addr != 0 && |
653 | scd_base_addr != trans_pcie->scd_base_addr); | 661 | scd_base_addr != trans_pcie->scd_base_addr); |
654 | 662 | ||
655 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | 663 | /* reset context data, TX status and translation data */ |
656 | /* reset conext data memory */ | 664 | iwl_trans_write_mem(trans, trans_pcie->scd_base_addr + |
657 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; | 665 | SCD_CONTEXT_MEM_LOWER_BOUND, |
658 | a += 4) | 666 | NULL, clear_dwords); |
659 | iwl_write_targ_mem(trans, a, 0); | ||
660 | /* reset tx status memory */ | ||
661 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; | ||
662 | a += 4) | ||
663 | iwl_write_targ_mem(trans, a, 0); | ||
664 | for (; a < trans_pcie->scd_base_addr + | ||
665 | SCD_TRANS_TBL_OFFSET_QUEUE( | ||
666 | trans->cfg->base_params->num_of_queues); | ||
667 | a += 4) | ||
668 | iwl_write_targ_mem(trans, a, 0); | ||
669 | 667 | ||
670 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, | 668 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, |
671 | trans_pcie->scd_bc_tbls.dma >> 10); | 669 | trans_pcie->scd_bc_tbls.dma >> 10); |
@@ -697,6 +695,29 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | |||
697 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 695 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
698 | } | 696 | } |
699 | 697 | ||
698 | void iwl_trans_pcie_tx_reset(struct iwl_trans *trans) | ||
699 | { | ||
700 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
701 | int txq_id; | ||
702 | |||
703 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
704 | txq_id++) { | ||
705 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | ||
706 | |||
707 | iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), | ||
708 | txq->q.dma_addr >> 8); | ||
709 | iwl_pcie_txq_unmap(trans, txq_id); | ||
710 | txq->q.read_ptr = 0; | ||
711 | txq->q.write_ptr = 0; | ||
712 | } | ||
713 | |||
714 | /* Tell NIC where to find the "keep warm" buffer */ | ||
715 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, | ||
716 | trans_pcie->kw.dma >> 4); | ||
717 | |||
718 | iwl_pcie_tx_start(trans, trans_pcie->scd_base_addr); | ||
719 | } | ||
720 | |||
700 | /* | 721 | /* |
701 | * iwl_pcie_tx_stop - Stop all Tx DMA channels | 722 | * iwl_pcie_tx_stop - Stop all Tx DMA channels |
702 | */ | 723 | */ |
@@ -1002,14 +1023,14 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, | |||
1002 | tbl_dw_addr = trans_pcie->scd_base_addr + | 1023 | tbl_dw_addr = trans_pcie->scd_base_addr + |
1003 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); | 1024 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); |
1004 | 1025 | ||
1005 | tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); | 1026 | tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr); |
1006 | 1027 | ||
1007 | if (txq_id & 0x1) | 1028 | if (txq_id & 0x1) |
1008 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); | 1029 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); |
1009 | else | 1030 | else |
1010 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); | 1031 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); |
1011 | 1032 | ||
1012 | iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); | 1033 | iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw); |
1013 | 1034 | ||
1014 | return 0; | 1035 | return 0; |
1015 | } | 1036 | } |
@@ -1068,9 +1089,9 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
1068 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | 1089 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); |
1069 | 1090 | ||
1070 | /* Set up Tx window size and frame limit for this queue */ | 1091 | /* Set up Tx window size and frame limit for this queue */ |
1071 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1092 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1072 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | 1093 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); |
1073 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1094 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1074 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 1095 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
1075 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 1096 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
1076 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 1097 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
@@ -1101,8 +1122,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
1101 | 1122 | ||
1102 | iwl_pcie_txq_set_inactive(trans, txq_id); | 1123 | iwl_pcie_txq_set_inactive(trans, txq_id); |
1103 | 1124 | ||
1104 | _iwl_write_targ_mem_dwords(trans, stts_addr, | 1125 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, |
1105 | zero_val, ARRAY_SIZE(zero_val)); | 1126 | ARRAY_SIZE(zero_val)); |
1106 | 1127 | ||
1107 | iwl_pcie_txq_unmap(trans, txq_id); | 1128 | iwl_pcie_txq_unmap(trans, txq_id); |
1108 | 1129 | ||
@@ -1642,10 +1663,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1642 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 1663 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
1643 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | 1664 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); |
1644 | 1665 | ||
1645 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", | ||
1646 | le16_to_cpu(dev_cmd->hdr.sequence)); | ||
1647 | IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | ||
1648 | |||
1649 | /* Set up entry for this TFD in Tx byte-count array */ | 1666 | /* Set up entry for this TFD in Tx byte-count array */ |
1650 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | 1667 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
1651 | 1668 | ||
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index ec6d5d6b452e..230f8ebbe289 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -2132,6 +2132,21 @@ static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv) | |||
2132 | lbs_deb_leave(LBS_DEB_CFG80211); | 2132 | lbs_deb_leave(LBS_DEB_CFG80211); |
2133 | } | 2133 | } |
2134 | 2134 | ||
2135 | static void lbs_reg_notifier(struct wiphy *wiphy, | ||
2136 | struct regulatory_request *request) | ||
2137 | { | ||
2138 | struct lbs_private *priv = wiphy_priv(wiphy); | ||
2139 | |||
2140 | lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " | ||
2141 | "callback for domain %c%c\n", request->alpha2[0], | ||
2142 | request->alpha2[1]); | ||
2143 | |||
2144 | memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); | ||
2145 | if (lbs_iface_active(priv)) | ||
2146 | lbs_set_11d_domain_info(priv); | ||
2147 | |||
2148 | lbs_deb_leave(LBS_DEB_CFG80211); | ||
2149 | } | ||
2135 | 2150 | ||
2136 | /* | 2151 | /* |
2137 | * This function get's called after lbs_setup_firmware() determined the | 2152 | * This function get's called after lbs_setup_firmware() determined the |
@@ -2184,24 +2199,6 @@ int lbs_cfg_register(struct lbs_private *priv) | |||
2184 | return ret; | 2199 | return ret; |
2185 | } | 2200 | } |
2186 | 2201 | ||
2187 | int lbs_reg_notifier(struct wiphy *wiphy, | ||
2188 | struct regulatory_request *request) | ||
2189 | { | ||
2190 | struct lbs_private *priv = wiphy_priv(wiphy); | ||
2191 | int ret = 0; | ||
2192 | |||
2193 | lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " | ||
2194 | "callback for domain %c%c\n", request->alpha2[0], | ||
2195 | request->alpha2[1]); | ||
2196 | |||
2197 | memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); | ||
2198 | if (lbs_iface_active(priv)) | ||
2199 | ret = lbs_set_11d_domain_info(priv); | ||
2200 | |||
2201 | lbs_deb_leave(LBS_DEB_CFG80211); | ||
2202 | return ret; | ||
2203 | } | ||
2204 | |||
2205 | void lbs_scan_deinit(struct lbs_private *priv) | 2202 | void lbs_scan_deinit(struct lbs_private *priv) |
2206 | { | 2203 | { |
2207 | lbs_deb_enter(LBS_DEB_CFG80211); | 2204 | lbs_deb_enter(LBS_DEB_CFG80211); |
diff --git a/drivers/net/wireless/libertas/cfg.h b/drivers/net/wireless/libertas/cfg.h index 558168ce634d..10995f59fe34 100644 --- a/drivers/net/wireless/libertas/cfg.h +++ b/drivers/net/wireless/libertas/cfg.h | |||
@@ -10,9 +10,6 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev); | |||
10 | int lbs_cfg_register(struct lbs_private *priv); | 10 | int lbs_cfg_register(struct lbs_private *priv); |
11 | void lbs_cfg_free(struct lbs_private *priv); | 11 | void lbs_cfg_free(struct lbs_private *priv); |
12 | 12 | ||
13 | int lbs_reg_notifier(struct wiphy *wiphy, | ||
14 | struct regulatory_request *request); | ||
15 | |||
16 | void lbs_send_disconnect_notification(struct lbs_private *priv); | 13 | void lbs_send_disconnect_notification(struct lbs_private *priv); |
17 | void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); | 14 | void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); |
18 | 15 | ||
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ff9085502bea..b73e497fe770 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -48,6 +48,10 @@ static int channels = 1; | |||
48 | module_param(channels, int, 0444); | 48 | module_param(channels, int, 0444); |
49 | MODULE_PARM_DESC(channels, "Number of concurrent channels"); | 49 | MODULE_PARM_DESC(channels, "Number of concurrent channels"); |
50 | 50 | ||
51 | static bool paged_rx = false; | ||
52 | module_param(paged_rx, bool, 0644); | ||
53 | MODULE_PARM_DESC(paged_rx, "Use paged SKBs for RX instead of linear ones"); | ||
54 | |||
51 | /** | 55 | /** |
52 | * enum hwsim_regtest - the type of regulatory tests we offer | 56 | * enum hwsim_regtest - the type of regulatory tests we offer |
53 | * | 57 | * |
@@ -333,11 +337,11 @@ struct mac80211_hwsim_data { | |||
333 | int scan_chan_idx; | 337 | int scan_chan_idx; |
334 | 338 | ||
335 | struct ieee80211_channel *channel; | 339 | struct ieee80211_channel *channel; |
336 | unsigned long beacon_int; /* in jiffies unit */ | 340 | u64 beacon_int /* beacon interval in us */; |
337 | unsigned int rx_filter; | 341 | unsigned int rx_filter; |
338 | bool started, idle, scanning; | 342 | bool started, idle, scanning; |
339 | struct mutex mutex; | 343 | struct mutex mutex; |
340 | struct timer_list beacon_timer; | 344 | struct tasklet_hrtimer beacon_timer; |
341 | enum ps_mode { | 345 | enum ps_mode { |
342 | PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL | 346 | PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL |
343 | } ps; | 347 | } ps; |
@@ -357,7 +361,10 @@ struct mac80211_hwsim_data { | |||
357 | int power_level; | 361 | int power_level; |
358 | 362 | ||
359 | /* difference between this hw's clock and the real clock, in usecs */ | 363 | /* difference between this hw's clock and the real clock, in usecs */ |
360 | u64 tsf_offset; | 364 | s64 tsf_offset; |
365 | s64 bcn_delta; | ||
366 | /* absolute beacon transmission time. Used to cover up "tx" delay. */ | ||
367 | u64 abs_bcn_ts; | ||
361 | }; | 368 | }; |
362 | 369 | ||
363 | 370 | ||
@@ -405,15 +412,19 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, | |||
405 | return NETDEV_TX_OK; | 412 | return NETDEV_TX_OK; |
406 | } | 413 | } |
407 | 414 | ||
415 | static inline u64 mac80211_hwsim_get_tsf_raw(void) | ||
416 | { | ||
417 | return ktime_to_us(ktime_get_real()); | ||
418 | } | ||
419 | |||
408 | static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) | 420 | static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) |
409 | { | 421 | { |
410 | struct timeval tv = ktime_to_timeval(ktime_get_real()); | 422 | u64 now = mac80211_hwsim_get_tsf_raw(); |
411 | u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; | ||
412 | return cpu_to_le64(now + data->tsf_offset); | 423 | return cpu_to_le64(now + data->tsf_offset); |
413 | } | 424 | } |
414 | 425 | ||
415 | static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, | 426 | static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, |
416 | struct ieee80211_vif *vif) | 427 | struct ieee80211_vif *vif) |
417 | { | 428 | { |
418 | struct mac80211_hwsim_data *data = hw->priv; | 429 | struct mac80211_hwsim_data *data = hw->priv; |
419 | return le64_to_cpu(__mac80211_hwsim_get_tsf(data)); | 430 | return le64_to_cpu(__mac80211_hwsim_get_tsf(data)); |
@@ -423,9 +434,13 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, | |||
423 | struct ieee80211_vif *vif, u64 tsf) | 434 | struct ieee80211_vif *vif, u64 tsf) |
424 | { | 435 | { |
425 | struct mac80211_hwsim_data *data = hw->priv; | 436 | struct mac80211_hwsim_data *data = hw->priv; |
426 | struct timeval tv = ktime_to_timeval(ktime_get_real()); | 437 | u64 now = mac80211_hwsim_get_tsf(hw, vif); |
427 | u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; | 438 | u32 bcn_int = data->beacon_int; |
428 | data->tsf_offset = tsf - now; | 439 | s64 delta = tsf - now; |
440 | |||
441 | data->tsf_offset += delta; | ||
442 | /* adjust after beaconing with new timestamp at old TBTT */ | ||
443 | data->bcn_delta = do_div(delta, bcn_int); | ||
429 | } | 444 | } |
430 | 445 | ||
431 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | 446 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, |
@@ -696,7 +711,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
696 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 711 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
697 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 712 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
698 | struct ieee80211_rx_status rx_status; | 713 | struct ieee80211_rx_status rx_status; |
699 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); | 714 | u64 now; |
700 | 715 | ||
701 | memset(&rx_status, 0, sizeof(rx_status)); | 716 | memset(&rx_status, 0, sizeof(rx_status)); |
702 | rx_status.flag |= RX_FLAG_MACTIME_START; | 717 | rx_status.flag |= RX_FLAG_MACTIME_START; |
@@ -722,11 +737,23 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
722 | secpath_reset(skb); | 737 | secpath_reset(skb); |
723 | nf_reset(skb); | 738 | nf_reset(skb); |
724 | 739 | ||
740 | /* | ||
741 | * Get absolute mactime here so all HWs RX at the "same time", and | ||
742 | * absolute TX time for beacon mactime so the timestamp matches. | ||
743 | * Giving beacons a different mactime than non-beacons looks messy, but | ||
744 | * it helps the Toffset be exact and a ~10us mactime discrepancy | ||
745 | * probably doesn't really matter. | ||
746 | */ | ||
747 | if (ieee80211_is_beacon(hdr->frame_control) || | ||
748 | ieee80211_is_probe_resp(hdr->frame_control)) | ||
749 | now = data->abs_bcn_ts; | ||
750 | else | ||
751 | now = mac80211_hwsim_get_tsf_raw(); | ||
752 | |||
725 | /* Copy skb to all enabled radios that are on the current frequency */ | 753 | /* Copy skb to all enabled radios that are on the current frequency */ |
726 | spin_lock(&hwsim_radio_lock); | 754 | spin_lock(&hwsim_radio_lock); |
727 | list_for_each_entry(data2, &hwsim_radios, list) { | 755 | list_for_each_entry(data2, &hwsim_radios, list) { |
728 | struct sk_buff *nskb; | 756 | struct sk_buff *nskb; |
729 | struct ieee80211_mgmt *mgmt; | ||
730 | struct tx_iter_data tx_iter_data = { | 757 | struct tx_iter_data tx_iter_data = { |
731 | .receive = false, | 758 | .receive = false, |
732 | .channel = chan, | 759 | .channel = chan, |
@@ -755,24 +782,30 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
755 | * reserve some space for our vendor and the normal | 782 | * reserve some space for our vendor and the normal |
756 | * radiotap header, since we're copying anyway | 783 | * radiotap header, since we're copying anyway |
757 | */ | 784 | */ |
758 | nskb = skb_copy_expand(skb, 64, 0, GFP_ATOMIC); | 785 | if (skb->len < PAGE_SIZE && paged_rx) { |
759 | if (nskb == NULL) | 786 | struct page *page = alloc_page(GFP_ATOMIC); |
760 | continue; | 787 | |
788 | if (!page) | ||
789 | continue; | ||
790 | |||
791 | nskb = dev_alloc_skb(128); | ||
792 | if (!nskb) { | ||
793 | __free_page(page); | ||
794 | continue; | ||
795 | } | ||
796 | |||
797 | memcpy(page_address(page), skb->data, skb->len); | ||
798 | skb_add_rx_frag(nskb, 0, page, 0, skb->len, skb->len); | ||
799 | } else { | ||
800 | nskb = skb_copy(skb, GFP_ATOMIC); | ||
801 | if (!nskb) | ||
802 | continue; | ||
803 | } | ||
761 | 804 | ||
762 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) | 805 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) |
763 | ack = true; | 806 | ack = true; |
764 | 807 | ||
765 | /* set bcn timestamp relative to receiver mactime */ | 808 | rx_status.mactime = now + data2->tsf_offset; |
766 | rx_status.mactime = | ||
767 | le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); | ||
768 | mgmt = (struct ieee80211_mgmt *) nskb->data; | ||
769 | if (ieee80211_is_beacon(mgmt->frame_control) || | ||
770 | ieee80211_is_probe_resp(mgmt->frame_control)) | ||
771 | mgmt->u.beacon.timestamp = cpu_to_le64( | ||
772 | rx_status.mactime + | ||
773 | (data->tsf_offset - data2->tsf_offset) + | ||
774 | 24 * 8 * 10 / txrate->bitrate); | ||
775 | |||
776 | #if 0 | 809 | #if 0 |
777 | /* | 810 | /* |
778 | * Don't enable this code by default as the OUI 00:00:00 | 811 | * Don't enable this code by default as the OUI 00:00:00 |
@@ -896,7 +929,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) | |||
896 | { | 929 | { |
897 | struct mac80211_hwsim_data *data = hw->priv; | 930 | struct mac80211_hwsim_data *data = hw->priv; |
898 | data->started = false; | 931 | data->started = false; |
899 | del_timer(&data->beacon_timer); | 932 | tasklet_hrtimer_cancel(&data->beacon_timer); |
900 | wiphy_debug(hw->wiphy, "%s\n", __func__); | 933 | wiphy_debug(hw->wiphy, "%s\n", __func__); |
901 | } | 934 | } |
902 | 935 | ||
@@ -962,7 +995,11 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
962 | static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | 995 | static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, |
963 | struct ieee80211_vif *vif) | 996 | struct ieee80211_vif *vif) |
964 | { | 997 | { |
965 | struct ieee80211_hw *hw = arg; | 998 | struct mac80211_hwsim_data *data = arg; |
999 | struct ieee80211_hw *hw = data->hw; | ||
1000 | struct ieee80211_tx_info *info; | ||
1001 | struct ieee80211_rate *txrate; | ||
1002 | struct ieee80211_mgmt *mgmt; | ||
966 | struct sk_buff *skb; | 1003 | struct sk_buff *skb; |
967 | 1004 | ||
968 | hwsim_check_magic(vif); | 1005 | hwsim_check_magic(vif); |
@@ -975,26 +1012,48 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
975 | skb = ieee80211_beacon_get(hw, vif); | 1012 | skb = ieee80211_beacon_get(hw, vif); |
976 | if (skb == NULL) | 1013 | if (skb == NULL) |
977 | return; | 1014 | return; |
1015 | info = IEEE80211_SKB_CB(skb); | ||
1016 | txrate = ieee80211_get_tx_rate(hw, info); | ||
1017 | |||
1018 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
1019 | /* fake header transmission time */ | ||
1020 | data->abs_bcn_ts = mac80211_hwsim_get_tsf_raw(); | ||
1021 | mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts + | ||
1022 | data->tsf_offset + | ||
1023 | 24 * 8 * 10 / txrate->bitrate); | ||
978 | 1024 | ||
979 | mac80211_hwsim_tx_frame(hw, skb, | 1025 | mac80211_hwsim_tx_frame(hw, skb, |
980 | rcu_dereference(vif->chanctx_conf)->def.chan); | 1026 | rcu_dereference(vif->chanctx_conf)->def.chan); |
981 | } | 1027 | } |
982 | 1028 | ||
983 | 1029 | static enum hrtimer_restart | |
984 | static void mac80211_hwsim_beacon(unsigned long arg) | 1030 | mac80211_hwsim_beacon(struct hrtimer *timer) |
985 | { | 1031 | { |
986 | struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; | 1032 | struct mac80211_hwsim_data *data = |
987 | struct mac80211_hwsim_data *data = hw->priv; | 1033 | container_of(timer, struct mac80211_hwsim_data, |
1034 | beacon_timer.timer); | ||
1035 | struct ieee80211_hw *hw = data->hw; | ||
1036 | u64 bcn_int = data->beacon_int; | ||
1037 | ktime_t next_bcn; | ||
988 | 1038 | ||
989 | if (!data->started) | 1039 | if (!data->started) |
990 | return; | 1040 | goto out; |
991 | 1041 | ||
992 | ieee80211_iterate_active_interfaces_atomic( | 1042 | ieee80211_iterate_active_interfaces_atomic( |
993 | hw, IEEE80211_IFACE_ITER_NORMAL, | 1043 | hw, IEEE80211_IFACE_ITER_NORMAL, |
994 | mac80211_hwsim_beacon_tx, hw); | 1044 | mac80211_hwsim_beacon_tx, data); |
1045 | |||
1046 | /* beacon at new TBTT + beacon interval */ | ||
1047 | if (data->bcn_delta) { | ||
1048 | bcn_int -= data->bcn_delta; | ||
1049 | data->bcn_delta = 0; | ||
1050 | } | ||
995 | 1051 | ||
996 | data->beacon_timer.expires = jiffies + data->beacon_int; | 1052 | next_bcn = ktime_add(hrtimer_get_expires(timer), |
997 | add_timer(&data->beacon_timer); | 1053 | ns_to_ktime(bcn_int * 1000)); |
1054 | tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS); | ||
1055 | out: | ||
1056 | return HRTIMER_NORESTART; | ||
998 | } | 1057 | } |
999 | 1058 | ||
1000 | static const char *hwsim_chantypes[] = { | 1059 | static const char *hwsim_chantypes[] = { |
@@ -1032,9 +1091,16 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
1032 | 1091 | ||
1033 | data->power_level = conf->power_level; | 1092 | data->power_level = conf->power_level; |
1034 | if (!data->started || !data->beacon_int) | 1093 | if (!data->started || !data->beacon_int) |
1035 | del_timer(&data->beacon_timer); | 1094 | tasklet_hrtimer_cancel(&data->beacon_timer); |
1036 | else | 1095 | else if (!hrtimer_is_queued(&data->beacon_timer.timer)) { |
1037 | mod_timer(&data->beacon_timer, jiffies + data->beacon_int); | 1096 | u64 tsf = mac80211_hwsim_get_tsf(hw, NULL); |
1097 | u32 bcn_int = data->beacon_int; | ||
1098 | u64 until_tbtt = bcn_int - do_div(tsf, bcn_int); | ||
1099 | |||
1100 | tasklet_hrtimer_start(&data->beacon_timer, | ||
1101 | ns_to_ktime(until_tbtt * 1000), | ||
1102 | HRTIMER_MODE_REL); | ||
1103 | } | ||
1038 | 1104 | ||
1039 | return 0; | 1105 | return 0; |
1040 | } | 1106 | } |
@@ -1084,12 +1150,26 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
1084 | 1150 | ||
1085 | if (changed & BSS_CHANGED_BEACON_INT) { | 1151 | if (changed & BSS_CHANGED_BEACON_INT) { |
1086 | wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int); | 1152 | wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int); |
1087 | data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000; | 1153 | data->beacon_int = info->beacon_int * 1024; |
1088 | if (WARN_ON(!data->beacon_int)) | 1154 | } |
1089 | data->beacon_int = 1; | 1155 | |
1090 | if (data->started) | 1156 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
1091 | mod_timer(&data->beacon_timer, | 1157 | wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon); |
1092 | jiffies + data->beacon_int); | 1158 | if (data->started && |
1159 | !hrtimer_is_queued(&data->beacon_timer.timer) && | ||
1160 | info->enable_beacon) { | ||
1161 | u64 tsf, until_tbtt; | ||
1162 | u32 bcn_int; | ||
1163 | if (WARN_ON(!data->beacon_int)) | ||
1164 | data->beacon_int = 1000 * 1024; | ||
1165 | tsf = mac80211_hwsim_get_tsf(hw, vif); | ||
1166 | bcn_int = data->beacon_int; | ||
1167 | until_tbtt = bcn_int - do_div(tsf, bcn_int); | ||
1168 | tasklet_hrtimer_start(&data->beacon_timer, | ||
1169 | ns_to_ktime(until_tbtt * 1000), | ||
1170 | HRTIMER_MODE_REL); | ||
1171 | } else if (!info->enable_beacon) | ||
1172 | tasklet_hrtimer_cancel(&data->beacon_timer); | ||
1093 | } | 1173 | } |
1094 | 1174 | ||
1095 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | 1175 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
@@ -1292,7 +1372,9 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw, | |||
1292 | case IEEE80211_AMPDU_TX_START: | 1372 | case IEEE80211_AMPDU_TX_START: |
1293 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1373 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1294 | break; | 1374 | break; |
1295 | case IEEE80211_AMPDU_TX_STOP: | 1375 | case IEEE80211_AMPDU_TX_STOP_CONT: |
1376 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
1377 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
1296 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1378 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
1297 | break; | 1379 | break; |
1298 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 1380 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
@@ -2370,8 +2452,9 @@ static int __init init_mac80211_hwsim(void) | |||
2370 | data->debugfs, data, | 2452 | data->debugfs, data, |
2371 | &hwsim_fops_group); | 2453 | &hwsim_fops_group); |
2372 | 2454 | ||
2373 | setup_timer(&data->beacon_timer, mac80211_hwsim_beacon, | 2455 | tasklet_hrtimer_init(&data->beacon_timer, |
2374 | (unsigned long) hw); | 2456 | mac80211_hwsim_beacon, |
2457 | CLOCK_REALTIME, HRTIMER_MODE_ABS); | ||
2375 | 2458 | ||
2376 | list_add_tail(&data->list, &hwsim_radios); | 2459 | list_add_tail(&data->list, &hwsim_radios); |
2377 | } | 2460 | } |
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 245a371f1a43..9cd6216c61e6 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -53,7 +53,9 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, | |||
53 | sizeof(sband->ht_cap.mcs)); | 53 | sizeof(sband->ht_cap.mcs)); |
54 | 54 | ||
55 | if (priv->bss_mode == NL80211_IFTYPE_STATION || | 55 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
56 | sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | 56 | (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && |
57 | (priv->adapter->sec_chan_offset != | ||
58 | IEEE80211_HT_PARAM_CHA_SEC_NONE))) | ||
57 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ | 59 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ |
58 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); | 60 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); |
59 | 61 | ||
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 68d52cfc1ebd..af8fe6352eed 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
@@ -278,14 +278,16 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
278 | dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); | 278 | dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); |
279 | break; | 279 | break; |
280 | case -1: | 280 | case -1: |
281 | adapter->data_sent = false; | 281 | if (adapter->iface_type != MWIFIEX_PCIE) |
282 | adapter->data_sent = false; | ||
282 | dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", | 283 | dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", |
283 | __func__, ret); | 284 | __func__, ret); |
284 | adapter->dbg.num_tx_host_to_card_failure++; | 285 | adapter->dbg.num_tx_host_to_card_failure++; |
285 | mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); | 286 | mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); |
286 | return 0; | 287 | return 0; |
287 | case -EINPROGRESS: | 288 | case -EINPROGRESS: |
288 | adapter->data_sent = false; | 289 | if (adapter->iface_type != MWIFIEX_PCIE) |
290 | adapter->data_sent = false; | ||
289 | break; | 291 | break; |
290 | case 0: | 292 | case 0: |
291 | mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); | 293 | mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ad3baa7e7982..ab92e799cf75 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -519,8 +519,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
519 | * - Set by user | 519 | * - Set by user |
520 | * - Set bt Country IE | 520 | * - Set bt Country IE |
521 | */ | 521 | */ |
522 | static int mwifiex_reg_notifier(struct wiphy *wiphy, | 522 | static void mwifiex_reg_notifier(struct wiphy *wiphy, |
523 | struct regulatory_request *request) | 523 | struct regulatory_request *request) |
524 | { | 524 | { |
525 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); | 525 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
526 | 526 | ||
@@ -540,8 +540,6 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy, | |||
540 | break; | 540 | break; |
541 | } | 541 | } |
542 | mwifiex_send_domain_info_cmd_fw(wiphy); | 542 | mwifiex_send_domain_info_cmd_fw(wiphy); |
543 | |||
544 | return 0; | ||
545 | } | 543 | } |
546 | 544 | ||
547 | /* | 545 | /* |
@@ -1327,6 +1325,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1327 | } | 1325 | } |
1328 | 1326 | ||
1329 | mwifiex_set_ht_params(priv, bss_cfg, params); | 1327 | mwifiex_set_ht_params(priv, bss_cfg, params); |
1328 | mwifiex_set_wmm_params(priv, bss_cfg, params); | ||
1330 | 1329 | ||
1331 | if (params->inactivity_timeout > 0) { | 1330 | if (params->inactivity_timeout > 0) { |
1332 | /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */ | 1331 | /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */ |
@@ -1459,7 +1458,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1459 | struct cfg80211_ssid req_ssid; | 1458 | struct cfg80211_ssid req_ssid; |
1460 | int ret, auth_type = 0; | 1459 | int ret, auth_type = 0; |
1461 | struct cfg80211_bss *bss = NULL; | 1460 | struct cfg80211_bss *bss = NULL; |
1462 | u8 is_scanning_required = 0, config_bands = 0; | 1461 | u8 is_scanning_required = 0; |
1463 | 1462 | ||
1464 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); | 1463 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); |
1465 | 1464 | ||
@@ -1478,19 +1477,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1478 | /* disconnect before try to associate */ | 1477 | /* disconnect before try to associate */ |
1479 | mwifiex_deauthenticate(priv, NULL); | 1478 | mwifiex_deauthenticate(priv, NULL); |
1480 | 1479 | ||
1481 | if (channel) { | ||
1482 | if (mode == NL80211_IFTYPE_STATION) { | ||
1483 | if (channel->band == IEEE80211_BAND_2GHZ) | ||
1484 | config_bands = BAND_B | BAND_G | BAND_GN; | ||
1485 | else | ||
1486 | config_bands = BAND_A | BAND_AN; | ||
1487 | |||
1488 | if (!((config_bands | priv->adapter->fw_bands) & | ||
1489 | ~priv->adapter->fw_bands)) | ||
1490 | priv->adapter->config_bands = config_bands; | ||
1491 | } | ||
1492 | } | ||
1493 | |||
1494 | /* As this is new association, clear locally stored | 1480 | /* As this is new association, clear locally stored |
1495 | * keys and security related flags */ | 1481 | * keys and security related flags */ |
1496 | priv->sec_info.wpa_enabled = false; | 1482 | priv->sec_info.wpa_enabled = false; |
@@ -1707,7 +1693,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv, | |||
1707 | 1693 | ||
1708 | if (cfg80211_get_chandef_type(¶ms->chandef) != | 1694 | if (cfg80211_get_chandef_type(¶ms->chandef) != |
1709 | NL80211_CHAN_NO_HT) | 1695 | NL80211_CHAN_NO_HT) |
1710 | config_bands |= BAND_GN; | 1696 | config_bands |= BAND_G | BAND_GN; |
1711 | } else { | 1697 | } else { |
1712 | if (cfg80211_get_chandef_type(¶ms->chandef) == | 1698 | if (cfg80211_get_chandef_type(¶ms->chandef) == |
1713 | NL80211_CHAN_NO_HT) | 1699 | NL80211_CHAN_NO_HT) |
@@ -2260,6 +2246,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) | |||
2260 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 2246 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
2261 | wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | | 2247 | wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | |
2262 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | | 2248 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | |
2249 | WIPHY_FLAG_AP_UAPSD | | ||
2263 | WIPHY_FLAG_CUSTOM_REGULATORY | | 2250 | WIPHY_FLAG_CUSTOM_REGULATORY | |
2264 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 2251 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
2265 | 2252 | ||
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index e9357d87d327..e8a569aaa2e8 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/wait.h> | 26 | #include <linux/wait.h> |
27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
28 | #include <linux/ieee80211.h> | 28 | #include <linux/ieee80211.h> |
29 | #include <net/mac80211.h> | ||
29 | 30 | ||
30 | 31 | ||
31 | #define MWIFIEX_MAX_BSS_NUM (3) | 32 | #define MWIFIEX_MAX_BSS_NUM (3) |
@@ -58,6 +59,8 @@ | |||
58 | #define MWIFIEX_RTS_MAX_VALUE (2347) | 59 | #define MWIFIEX_RTS_MAX_VALUE (2347) |
59 | #define MWIFIEX_FRAG_MIN_VALUE (256) | 60 | #define MWIFIEX_FRAG_MIN_VALUE (256) |
60 | #define MWIFIEX_FRAG_MAX_VALUE (2346) | 61 | #define MWIFIEX_FRAG_MAX_VALUE (2346) |
62 | #define MWIFIEX_WMM_VERSION 0x01 | ||
63 | #define MWIFIEX_WMM_SUBTYPE 0x01 | ||
61 | 64 | ||
62 | #define MWIFIEX_RETRY_LIMIT 14 | 65 | #define MWIFIEX_RETRY_LIMIT 14 |
63 | #define MWIFIEX_SDIO_BLOCK_SIZE 256 | 66 | #define MWIFIEX_SDIO_BLOCK_SIZE 256 |
@@ -126,4 +129,19 @@ enum mwifiex_wmm_ac_e { | |||
126 | WMM_AC_VI, | 129 | WMM_AC_VI, |
127 | WMM_AC_VO | 130 | WMM_AC_VO |
128 | } __packed; | 131 | } __packed; |
132 | |||
133 | struct ieee_types_wmm_ac_parameters { | ||
134 | u8 aci_aifsn_bitmap; | ||
135 | u8 ecw_bitmap; | ||
136 | __le16 tx_op_limit; | ||
137 | } __packed; | ||
138 | |||
139 | struct mwifiex_types_wmm_info { | ||
140 | u8 oui[4]; | ||
141 | u8 subtype; | ||
142 | u8 version; | ||
143 | u8 qos_info; | ||
144 | u8 reserved; | ||
145 | struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS]; | ||
146 | } __packed; | ||
129 | #endif /* !_MWIFIEX_DECL_H_ */ | 147 | #endif /* !_MWIFIEX_DECL_H_ */ |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 4dc8e2e9a889..ebe2f6a7984c 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -330,6 +330,9 @@ enum P2P_MODES { | |||
330 | #define HOST_SLEEP_CFG_GPIO_DEF 0xff | 330 | #define HOST_SLEEP_CFG_GPIO_DEF 0xff |
331 | #define HOST_SLEEP_CFG_GAP_DEF 0 | 331 | #define HOST_SLEEP_CFG_GAP_DEF 0 |
332 | 332 | ||
333 | #define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc | ||
334 | #define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 | ||
335 | |||
333 | #define CMD_F_HOSTCMD (1 << 0) | 336 | #define CMD_F_HOSTCMD (1 << 0) |
334 | #define CMD_F_CANCELED (1 << 1) | 337 | #define CMD_F_CANCELED (1 << 1) |
335 | 338 | ||
@@ -1131,12 +1134,6 @@ struct ieee_types_vendor_header { | |||
1131 | u8 version; | 1134 | u8 version; |
1132 | } __packed; | 1135 | } __packed; |
1133 | 1136 | ||
1134 | struct ieee_types_wmm_ac_parameters { | ||
1135 | u8 aci_aifsn_bitmap; | ||
1136 | u8 ecw_bitmap; | ||
1137 | __le16 tx_op_limit; | ||
1138 | } __packed; | ||
1139 | |||
1140 | struct ieee_types_wmm_parameter { | 1137 | struct ieee_types_wmm_parameter { |
1141 | /* | 1138 | /* |
1142 | * WMM Parameter IE - Vendor Specific Header: | 1139 | * WMM Parameter IE - Vendor Specific Header: |
@@ -1186,6 +1183,11 @@ struct mwifiex_ie_types_htcap { | |||
1186 | struct ieee80211_ht_cap ht_cap; | 1183 | struct ieee80211_ht_cap ht_cap; |
1187 | } __packed; | 1184 | } __packed; |
1188 | 1185 | ||
1186 | struct mwifiex_ie_types_wmmcap { | ||
1187 | struct mwifiex_ie_types_header header; | ||
1188 | struct mwifiex_types_wmm_info wmm_info; | ||
1189 | } __packed; | ||
1190 | |||
1189 | struct mwifiex_ie_types_htinfo { | 1191 | struct mwifiex_ie_types_htinfo { |
1190 | struct mwifiex_ie_types_header header; | 1192 | struct mwifiex_ie_types_header header; |
1191 | struct ieee80211_ht_operation ht_oper; | 1193 | struct ieee80211_ht_operation ht_oper; |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 39f03ce5a5b1..e00b8060aff7 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -591,6 +591,12 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter) | |||
591 | return -1; | 591 | return -1; |
592 | } | 592 | } |
593 | } | 593 | } |
594 | |||
595 | if (adapter->if_ops.init_fw_port) { | ||
596 | if (adapter->if_ops.init_fw_port(adapter)) | ||
597 | return -1; | ||
598 | } | ||
599 | |||
594 | for (i = 0; i < adapter->priv_num; i++) { | 600 | for (i = 0; i < adapter->priv_num; i++) { |
595 | if (adapter->priv[i]) { | 601 | if (adapter->priv[i]) { |
596 | ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta); | 602 | ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta); |
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 4e31c6013ebe..6095b3e53f4e 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h | |||
@@ -20,7 +20,6 @@ | |||
20 | #ifndef _MWIFIEX_IOCTL_H_ | 20 | #ifndef _MWIFIEX_IOCTL_H_ |
21 | #define _MWIFIEX_IOCTL_H_ | 21 | #define _MWIFIEX_IOCTL_H_ |
22 | 22 | ||
23 | #include <net/mac80211.h> | ||
24 | #include <net/lib80211.h> | 23 | #include <net/lib80211.h> |
25 | 24 | ||
26 | enum { | 25 | enum { |
@@ -107,6 +106,8 @@ struct mwifiex_uap_bss_param { | |||
107 | u8 rates[MWIFIEX_SUPPORTED_RATES]; | 106 | u8 rates[MWIFIEX_SUPPORTED_RATES]; |
108 | u32 sta_ao_timer; | 107 | u32 sta_ao_timer; |
109 | u32 ps_sta_ao_timer; | 108 | u32 ps_sta_ao_timer; |
109 | u8 qos_info; | ||
110 | struct mwifiex_types_wmm_info wmm_info; | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | enum { | 113 | enum { |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 88664ae667ba..893d809ba83c 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -615,23 +615,33 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
615 | struct ieee_types_assoc_rsp *assoc_rsp; | 615 | struct ieee_types_assoc_rsp *assoc_rsp; |
616 | struct mwifiex_bssdescriptor *bss_desc; | 616 | struct mwifiex_bssdescriptor *bss_desc; |
617 | u8 enable_data = true; | 617 | u8 enable_data = true; |
618 | u16 cap_info, status_code; | ||
618 | 619 | ||
619 | assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; | 620 | assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; |
620 | 621 | ||
622 | cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap); | ||
623 | status_code = le16_to_cpu(assoc_rsp->status_code); | ||
624 | |||
621 | priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, | 625 | priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, |
622 | sizeof(priv->assoc_rsp_buf)); | 626 | sizeof(priv->assoc_rsp_buf)); |
623 | 627 | ||
624 | memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); | 628 | memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); |
625 | 629 | ||
626 | if (le16_to_cpu(assoc_rsp->status_code)) { | 630 | if (status_code) { |
627 | priv->adapter->dbg.num_cmd_assoc_failure++; | 631 | priv->adapter->dbg.num_cmd_assoc_failure++; |
628 | dev_err(priv->adapter->dev, | 632 | dev_err(priv->adapter->dev, |
629 | "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n", | 633 | "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n", |
630 | le16_to_cpu(assoc_rsp->status_code), | 634 | status_code, cap_info, le16_to_cpu(assoc_rsp->a_id)); |
631 | le16_to_cpu(assoc_rsp->cap_info_bitmap), | 635 | |
632 | le16_to_cpu(assoc_rsp->a_id)); | 636 | if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { |
637 | if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) | ||
638 | ret = WLAN_STATUS_AUTH_TIMEOUT; | ||
639 | else | ||
640 | ret = WLAN_STATUS_UNSPECIFIED_FAILURE; | ||
641 | } else { | ||
642 | ret = status_code; | ||
643 | } | ||
633 | 644 | ||
634 | ret = le16_to_cpu(assoc_rsp->status_code); | ||
635 | goto done; | 645 | goto done; |
636 | } | 646 | } |
637 | 647 | ||
@@ -969,6 +979,16 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
969 | priv->adapter->config_bands); | 979 | priv->adapter->config_bands); |
970 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); | 980 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); |
971 | 981 | ||
982 | if (adapter->sec_chan_offset == | ||
983 | IEEE80211_HT_PARAM_CHA_SEC_NONE) { | ||
984 | u16 tmp_ht_cap; | ||
985 | |||
986 | tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info); | ||
987 | tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
988 | tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
989 | ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap); | ||
990 | } | ||
991 | |||
972 | pos += sizeof(struct mwifiex_ie_types_htcap); | 992 | pos += sizeof(struct mwifiex_ie_types_htcap); |
973 | cmd_append_size += sizeof(struct mwifiex_ie_types_htcap); | 993 | cmd_append_size += sizeof(struct mwifiex_ie_types_htcap); |
974 | 994 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 1b3cfc821940..51044e3ea89b 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -599,8 +599,10 @@ struct mwifiex_if_ops { | |||
599 | int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *); | 599 | int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *); |
600 | int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); | 600 | int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); |
601 | int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); | 601 | int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); |
602 | int (*init_fw_port) (struct mwifiex_adapter *); | ||
602 | int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); | 603 | int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); |
603 | void (*card_reset) (struct mwifiex_adapter *); | 604 | void (*card_reset) (struct mwifiex_adapter *); |
605 | int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); | ||
604 | }; | 606 | }; |
605 | 607 | ||
606 | struct mwifiex_adapter { | 608 | struct mwifiex_adapter { |
@@ -890,6 +892,10 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv, | |||
890 | struct cfg80211_ap_settings *params); | 892 | struct cfg80211_ap_settings *params); |
891 | void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, | 893 | void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, |
892 | struct cfg80211_ap_settings *params); | 894 | struct cfg80211_ap_settings *params); |
895 | void | ||
896 | mwifiex_set_wmm_params(struct mwifiex_private *priv, | ||
897 | struct mwifiex_uap_bss_param *bss_cfg, | ||
898 | struct cfg80211_ap_settings *params); | ||
893 | 899 | ||
894 | /* | 900 | /* |
895 | * This function checks if the queuing is RA based or not. | 901 | * This function checks if the queuing is RA based or not. |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 13fbc4eb1595..237949c070cc 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -39,17 +39,20 @@ static struct semaphore add_remove_card_sem; | |||
39 | static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter); | 39 | static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter); |
40 | static int mwifiex_pcie_resume(struct pci_dev *pdev); | 40 | static int mwifiex_pcie_resume(struct pci_dev *pdev); |
41 | 41 | ||
42 | /* | 42 | static int |
43 | * This function is called after skb allocation to update | 43 | mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, |
44 | * "skb->cb" with physical address of data pointer. | 44 | int size, int flags) |
45 | */ | ||
46 | static phys_addr_t *mwifiex_update_sk_buff_pa(struct sk_buff *skb) | ||
47 | { | 45 | { |
48 | phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); | 46 | struct pcie_service_card *card = adapter->card; |
49 | 47 | dma_addr_t buf_pa; | |
50 | *buf_pa = (phys_addr_t)virt_to_phys(skb->data); | ||
51 | 48 | ||
52 | return buf_pa; | 49 | buf_pa = pci_map_single(card->dev, skb->data, size, flags); |
50 | if (pci_dma_mapping_error(card->dev, buf_pa)) { | ||
51 | dev_err(adapter->dev, "failed to map pci memory!\n"); | ||
52 | return -1; | ||
53 | } | ||
54 | memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t)); | ||
55 | return 0; | ||
53 | } | 56 | } |
54 | 57 | ||
55 | /* | 58 | /* |
@@ -60,8 +63,8 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter) | |||
60 | u32 *cookie_addr; | 63 | u32 *cookie_addr; |
61 | struct pcie_service_card *card = adapter->card; | 64 | struct pcie_service_card *card = adapter->card; |
62 | 65 | ||
63 | if (card->sleep_cookie) { | 66 | if (card->sleep_cookie_vbase) { |
64 | cookie_addr = (u32 *)card->sleep_cookie->data; | 67 | cookie_addr = (u32 *)card->sleep_cookie_vbase; |
65 | dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n", | 68 | dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n", |
66 | *cookie_addr); | 69 | *cookie_addr); |
67 | if (*cookie_addr == FW_AWAKE_COOKIE) | 70 | if (*cookie_addr == FW_AWAKE_COOKIE) |
@@ -161,7 +164,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) | |||
161 | 164 | ||
162 | if (pdev) { | 165 | if (pdev) { |
163 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); | 166 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); |
164 | if (!card || card->adapter) { | 167 | if (!card || !card->adapter) { |
165 | pr_err("Card or adapter structure is not valid\n"); | 168 | pr_err("Card or adapter structure is not valid\n"); |
166 | return 0; | 169 | return 0; |
167 | } | 170 | } |
@@ -366,9 +369,7 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) | |||
366 | static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | 369 | static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) |
367 | { | 370 | { |
368 | struct pcie_service_card *card = adapter->card; | 371 | struct pcie_service_card *card = adapter->card; |
369 | struct sk_buff *skb; | ||
370 | int i; | 372 | int i; |
371 | phys_addr_t *buf_pa; | ||
372 | 373 | ||
373 | /* | 374 | /* |
374 | * driver maintaines the write pointer and firmware maintaines the read | 375 | * driver maintaines the write pointer and firmware maintaines the read |
@@ -384,16 +385,18 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
384 | MWIFIEX_MAX_TXRX_BD; | 385 | MWIFIEX_MAX_TXRX_BD; |
385 | dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", | 386 | dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", |
386 | card->txbd_ring_size); | 387 | card->txbd_ring_size); |
387 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); | 388 | card->txbd_ring_vbase = pci_alloc_consistent(card->dev, |
389 | card->txbd_ring_size, | ||
390 | &card->txbd_ring_pbase); | ||
388 | if (!card->txbd_ring_vbase) { | 391 | if (!card->txbd_ring_vbase) { |
389 | dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n"); | 392 | dev_err(adapter->dev, |
393 | "allocate consistent memory (%d bytes) failed!\n", | ||
394 | card->txbd_ring_size); | ||
390 | return -ENOMEM; | 395 | return -ENOMEM; |
391 | } | 396 | } |
392 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); | ||
393 | |||
394 | dev_dbg(adapter->dev, | 397 | dev_dbg(adapter->dev, |
395 | "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", | 398 | "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", |
396 | card->txbd_ring_vbase, (u32)card->txbd_ring_pbase, | 399 | card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase, |
397 | (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); | 400 | (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); |
398 | 401 | ||
399 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { | 402 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { |
@@ -402,24 +405,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
402 | (sizeof(struct mwifiex_pcie_buf_desc) | 405 | (sizeof(struct mwifiex_pcie_buf_desc) |
403 | * i)); | 406 | * i)); |
404 | 407 | ||
405 | /* Allocate buffer here so that firmware can DMA data from it */ | 408 | card->tx_buf_list[i] = NULL; |
406 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); | 409 | card->txbd_ring[i]->paddr = 0; |
407 | if (!skb) { | 410 | card->txbd_ring[i]->len = 0; |
408 | dev_err(adapter->dev, "Unable to allocate skb for TX ring.\n"); | ||
409 | kfree(card->txbd_ring_vbase); | ||
410 | return -ENOMEM; | ||
411 | } | ||
412 | buf_pa = mwifiex_update_sk_buff_pa(skb); | ||
413 | |||
414 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); | ||
415 | dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " | ||
416 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", | ||
417 | skb, skb->data, (u32)*buf_pa, | ||
418 | (u32)(((u64)*buf_pa >> 32)), skb->len); | ||
419 | |||
420 | card->tx_buf_list[i] = skb; | ||
421 | card->txbd_ring[i]->paddr = *buf_pa; | ||
422 | card->txbd_ring[i]->len = (u16)skb->len; | ||
423 | card->txbd_ring[i]->flags = 0; | 411 | card->txbd_ring[i]->flags = 0; |
424 | } | 412 | } |
425 | 413 | ||
@@ -429,11 +417,16 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
429 | static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) | 417 | static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) |
430 | { | 418 | { |
431 | struct pcie_service_card *card = adapter->card; | 419 | struct pcie_service_card *card = adapter->card; |
420 | struct sk_buff *skb; | ||
432 | int i; | 421 | int i; |
433 | 422 | ||
434 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { | 423 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { |
435 | if (card->tx_buf_list[i]) | 424 | if (card->tx_buf_list[i]) { |
436 | dev_kfree_skb_any(card->tx_buf_list[i]); | 425 | skb = card->tx_buf_list[i]; |
426 | pci_unmap_single(card->dev, card->txbd_ring[i]->paddr, | ||
427 | skb->len, PCI_DMA_TODEVICE); | ||
428 | dev_kfree_skb_any(skb); | ||
429 | } | ||
437 | card->tx_buf_list[i] = NULL; | 430 | card->tx_buf_list[i] = NULL; |
438 | card->txbd_ring[i]->paddr = 0; | 431 | card->txbd_ring[i]->paddr = 0; |
439 | card->txbd_ring[i]->len = 0; | 432 | card->txbd_ring[i]->len = 0; |
@@ -441,11 +434,15 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) | |||
441 | card->txbd_ring[i] = NULL; | 434 | card->txbd_ring[i] = NULL; |
442 | } | 435 | } |
443 | 436 | ||
444 | kfree(card->txbd_ring_vbase); | 437 | if (card->txbd_ring_vbase) |
438 | pci_free_consistent(card->dev, card->txbd_ring_size, | ||
439 | card->txbd_ring_vbase, | ||
440 | card->txbd_ring_pbase); | ||
445 | card->txbd_ring_size = 0; | 441 | card->txbd_ring_size = 0; |
446 | card->txbd_wrptr = 0; | 442 | card->txbd_wrptr = 0; |
447 | card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; | 443 | card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; |
448 | card->txbd_ring_vbase = NULL; | 444 | card->txbd_ring_vbase = NULL; |
445 | card->txbd_ring_pbase = 0; | ||
449 | 446 | ||
450 | return 0; | 447 | return 0; |
451 | } | 448 | } |
@@ -458,7 +455,7 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
458 | struct pcie_service_card *card = adapter->card; | 455 | struct pcie_service_card *card = adapter->card; |
459 | struct sk_buff *skb; | 456 | struct sk_buff *skb; |
460 | int i; | 457 | int i; |
461 | phys_addr_t *buf_pa; | 458 | dma_addr_t buf_pa; |
462 | 459 | ||
463 | /* | 460 | /* |
464 | * driver maintaines the read pointer and firmware maintaines the write | 461 | * driver maintaines the read pointer and firmware maintaines the write |
@@ -472,13 +469,15 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
472 | MWIFIEX_MAX_TXRX_BD; | 469 | MWIFIEX_MAX_TXRX_BD; |
473 | dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", | 470 | dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", |
474 | card->rxbd_ring_size); | 471 | card->rxbd_ring_size); |
475 | card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); | 472 | card->rxbd_ring_vbase = pci_alloc_consistent(card->dev, |
473 | card->rxbd_ring_size, | ||
474 | &card->rxbd_ring_pbase); | ||
476 | if (!card->rxbd_ring_vbase) { | 475 | if (!card->rxbd_ring_vbase) { |
477 | dev_err(adapter->dev, "Unable to allocate buffer for " | 476 | dev_err(adapter->dev, |
478 | "rxbd_ring.\n"); | 477 | "allocate consistent memory (%d bytes) failed!\n", |
478 | card->rxbd_ring_size); | ||
479 | return -ENOMEM; | 479 | return -ENOMEM; |
480 | } | 480 | } |
481 | card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); | ||
482 | 481 | ||
483 | dev_dbg(adapter->dev, | 482 | dev_dbg(adapter->dev, |
484 | "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", | 483 | "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", |
@@ -500,16 +499,20 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
500 | kfree(card->rxbd_ring_vbase); | 499 | kfree(card->rxbd_ring_vbase); |
501 | return -ENOMEM; | 500 | return -ENOMEM; |
502 | } | 501 | } |
503 | buf_pa = mwifiex_update_sk_buff_pa(skb); | 502 | if (mwifiex_map_pci_memory(adapter, skb, |
504 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); | 503 | MWIFIEX_RX_DATA_BUF_SIZE, |
504 | PCI_DMA_FROMDEVICE)) | ||
505 | return -1; | ||
506 | |||
507 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
505 | 508 | ||
506 | dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " | 509 | dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " |
507 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", | 510 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
508 | skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), | 511 | skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32), |
509 | skb->len); | 512 | skb->len); |
510 | 513 | ||
511 | card->rx_buf_list[i] = skb; | 514 | card->rx_buf_list[i] = skb; |
512 | card->rxbd_ring[i]->paddr = *buf_pa; | 515 | card->rxbd_ring[i]->paddr = buf_pa; |
513 | card->rxbd_ring[i]->len = (u16)skb->len; | 516 | card->rxbd_ring[i]->len = (u16)skb->len; |
514 | card->rxbd_ring[i]->flags = 0; | 517 | card->rxbd_ring[i]->flags = 0; |
515 | } | 518 | } |
@@ -523,11 +526,17 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
523 | static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) | 526 | static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) |
524 | { | 527 | { |
525 | struct pcie_service_card *card = adapter->card; | 528 | struct pcie_service_card *card = adapter->card; |
529 | struct sk_buff *skb; | ||
526 | int i; | 530 | int i; |
527 | 531 | ||
528 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { | 532 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { |
529 | if (card->rx_buf_list[i]) | 533 | if (card->rx_buf_list[i]) { |
530 | dev_kfree_skb_any(card->rx_buf_list[i]); | 534 | skb = card->rx_buf_list[i]; |
535 | pci_unmap_single(card->dev, card->rxbd_ring[i]->paddr , | ||
536 | MWIFIEX_RX_DATA_BUF_SIZE, | ||
537 | PCI_DMA_FROMDEVICE); | ||
538 | dev_kfree_skb_any(skb); | ||
539 | } | ||
531 | card->rx_buf_list[i] = NULL; | 540 | card->rx_buf_list[i] = NULL; |
532 | card->rxbd_ring[i]->paddr = 0; | 541 | card->rxbd_ring[i]->paddr = 0; |
533 | card->rxbd_ring[i]->len = 0; | 542 | card->rxbd_ring[i]->len = 0; |
@@ -535,11 +544,15 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) | |||
535 | card->rxbd_ring[i] = NULL; | 544 | card->rxbd_ring[i] = NULL; |
536 | } | 545 | } |
537 | 546 | ||
538 | kfree(card->rxbd_ring_vbase); | 547 | if (card->rxbd_ring_vbase) |
548 | pci_free_consistent(card->dev, card->rxbd_ring_size, | ||
549 | card->rxbd_ring_vbase, | ||
550 | card->rxbd_ring_pbase); | ||
539 | card->rxbd_ring_size = 0; | 551 | card->rxbd_ring_size = 0; |
540 | card->rxbd_wrptr = 0; | 552 | card->rxbd_wrptr = 0; |
541 | card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; | 553 | card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; |
542 | card->rxbd_ring_vbase = NULL; | 554 | card->rxbd_ring_vbase = NULL; |
555 | card->rxbd_ring_pbase = 0; | ||
543 | 556 | ||
544 | return 0; | 557 | return 0; |
545 | } | 558 | } |
@@ -552,7 +565,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
552 | struct pcie_service_card *card = adapter->card; | 565 | struct pcie_service_card *card = adapter->card; |
553 | struct sk_buff *skb; | 566 | struct sk_buff *skb; |
554 | int i; | 567 | int i; |
555 | phys_addr_t *buf_pa; | 568 | dma_addr_t buf_pa; |
556 | 569 | ||
557 | /* | 570 | /* |
558 | * driver maintaines the read pointer and firmware maintaines the write | 571 | * driver maintaines the read pointer and firmware maintaines the write |
@@ -566,13 +579,15 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
566 | MWIFIEX_MAX_EVT_BD; | 579 | MWIFIEX_MAX_EVT_BD; |
567 | dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", | 580 | dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", |
568 | card->evtbd_ring_size); | 581 | card->evtbd_ring_size); |
569 | card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); | 582 | card->evtbd_ring_vbase = pci_alloc_consistent(card->dev, |
583 | card->evtbd_ring_size, | ||
584 | &card->evtbd_ring_pbase); | ||
570 | if (!card->evtbd_ring_vbase) { | 585 | if (!card->evtbd_ring_vbase) { |
571 | dev_err(adapter->dev, | 586 | dev_err(adapter->dev, |
572 | "Unable to allocate buffer. Terminating download\n"); | 587 | "allocate consistent memory (%d bytes) failed!\n", |
588 | card->evtbd_ring_size); | ||
573 | return -ENOMEM; | 589 | return -ENOMEM; |
574 | } | 590 | } |
575 | card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); | ||
576 | 591 | ||
577 | dev_dbg(adapter->dev, | 592 | dev_dbg(adapter->dev, |
578 | "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", | 593 | "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", |
@@ -594,16 +609,20 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
594 | kfree(card->evtbd_ring_vbase); | 609 | kfree(card->evtbd_ring_vbase); |
595 | return -ENOMEM; | 610 | return -ENOMEM; |
596 | } | 611 | } |
597 | buf_pa = mwifiex_update_sk_buff_pa(skb); | ||
598 | skb_put(skb, MAX_EVENT_SIZE); | 612 | skb_put(skb, MAX_EVENT_SIZE); |
599 | 613 | ||
614 | if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, | ||
615 | PCI_DMA_FROMDEVICE)) | ||
616 | return -1; | ||
617 | |||
618 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
600 | dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " | 619 | dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " |
601 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", | 620 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
602 | skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), | 621 | skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32), |
603 | skb->len); | 622 | skb->len); |
604 | 623 | ||
605 | card->evt_buf_list[i] = skb; | 624 | card->evt_buf_list[i] = skb; |
606 | card->evtbd_ring[i]->paddr = *buf_pa; | 625 | card->evtbd_ring[i]->paddr = buf_pa; |
607 | card->evtbd_ring[i]->len = (u16)skb->len; | 626 | card->evtbd_ring[i]->len = (u16)skb->len; |
608 | card->evtbd_ring[i]->flags = 0; | 627 | card->evtbd_ring[i]->flags = 0; |
609 | } | 628 | } |
@@ -617,11 +636,16 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
617 | static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) | 636 | static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) |
618 | { | 637 | { |
619 | struct pcie_service_card *card = adapter->card; | 638 | struct pcie_service_card *card = adapter->card; |
639 | struct sk_buff *skb; | ||
620 | int i; | 640 | int i; |
621 | 641 | ||
622 | for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { | 642 | for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { |
623 | if (card->evt_buf_list[i]) | 643 | if (card->evt_buf_list[i]) { |
624 | dev_kfree_skb_any(card->evt_buf_list[i]); | 644 | skb = card->evt_buf_list[i]; |
645 | pci_unmap_single(card->dev, card->evtbd_ring[i]->paddr, | ||
646 | MAX_EVENT_SIZE, PCI_DMA_FROMDEVICE); | ||
647 | dev_kfree_skb_any(skb); | ||
648 | } | ||
625 | card->evt_buf_list[i] = NULL; | 649 | card->evt_buf_list[i] = NULL; |
626 | card->evtbd_ring[i]->paddr = 0; | 650 | card->evtbd_ring[i]->paddr = 0; |
627 | card->evtbd_ring[i]->len = 0; | 651 | card->evtbd_ring[i]->len = 0; |
@@ -629,11 +653,15 @@ static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) | |||
629 | card->evtbd_ring[i] = NULL; | 653 | card->evtbd_ring[i] = NULL; |
630 | } | 654 | } |
631 | 655 | ||
632 | kfree(card->evtbd_ring_vbase); | 656 | if (card->evtbd_ring_vbase) |
657 | pci_free_consistent(card->dev, card->evtbd_ring_size, | ||
658 | card->evtbd_ring_vbase, | ||
659 | card->evtbd_ring_pbase); | ||
633 | card->evtbd_wrptr = 0; | 660 | card->evtbd_wrptr = 0; |
634 | card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; | 661 | card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; |
635 | card->evtbd_ring_size = 0; | 662 | card->evtbd_ring_size = 0; |
636 | card->evtbd_ring_vbase = NULL; | 663 | card->evtbd_ring_vbase = NULL; |
664 | card->evtbd_ring_pbase = 0; | ||
637 | 665 | ||
638 | return 0; | 666 | return 0; |
639 | } | 667 | } |
@@ -653,21 +681,12 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
653 | "Unable to allocate skb for command response data.\n"); | 681 | "Unable to allocate skb for command response data.\n"); |
654 | return -ENOMEM; | 682 | return -ENOMEM; |
655 | } | 683 | } |
656 | mwifiex_update_sk_buff_pa(skb); | ||
657 | skb_put(skb, MWIFIEX_UPLD_SIZE); | 684 | skb_put(skb, MWIFIEX_UPLD_SIZE); |
658 | card->cmdrsp_buf = skb; | 685 | if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, |
686 | PCI_DMA_FROMDEVICE)) | ||
687 | return -1; | ||
659 | 688 | ||
660 | skb = NULL; | 689 | card->cmdrsp_buf = skb; |
661 | /* Allocate memory for sending command to firmware */ | ||
662 | skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); | ||
663 | if (!skb) { | ||
664 | dev_err(adapter->dev, | ||
665 | "Unable to allocate skb for command data.\n"); | ||
666 | return -ENOMEM; | ||
667 | } | ||
668 | mwifiex_update_sk_buff_pa(skb); | ||
669 | skb_put(skb, MWIFIEX_SIZE_OF_CMD_BUFFER); | ||
670 | card->cmd_buf = skb; | ||
671 | 690 | ||
672 | return 0; | 691 | return 0; |
673 | } | 692 | } |
@@ -678,18 +697,26 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
678 | static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) | 697 | static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) |
679 | { | 698 | { |
680 | struct pcie_service_card *card; | 699 | struct pcie_service_card *card; |
700 | dma_addr_t buf_pa; | ||
681 | 701 | ||
682 | if (!adapter) | 702 | if (!adapter) |
683 | return 0; | 703 | return 0; |
684 | 704 | ||
685 | card = adapter->card; | 705 | card = adapter->card; |
686 | 706 | ||
687 | if (card && card->cmdrsp_buf) | 707 | if (card && card->cmdrsp_buf) { |
708 | MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa); | ||
709 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, | ||
710 | PCI_DMA_FROMDEVICE); | ||
688 | dev_kfree_skb_any(card->cmdrsp_buf); | 711 | dev_kfree_skb_any(card->cmdrsp_buf); |
712 | } | ||
689 | 713 | ||
690 | if (card && card->cmd_buf) | 714 | if (card && card->cmd_buf) { |
715 | MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa); | ||
716 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER, | ||
717 | PCI_DMA_TODEVICE); | ||
691 | dev_kfree_skb_any(card->cmd_buf); | 718 | dev_kfree_skb_any(card->cmd_buf); |
692 | 719 | } | |
693 | return 0; | 720 | return 0; |
694 | } | 721 | } |
695 | 722 | ||
@@ -698,27 +725,19 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
698 | */ | 725 | */ |
699 | static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) | 726 | static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) |
700 | { | 727 | { |
701 | struct sk_buff *skb; | ||
702 | struct pcie_service_card *card = adapter->card; | 728 | struct pcie_service_card *card = adapter->card; |
703 | 729 | ||
704 | /* Allocate memory for sleep cookie */ | 730 | card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32), |
705 | skb = dev_alloc_skb(sizeof(u32)); | 731 | &card->sleep_cookie_pbase); |
706 | if (!skb) { | 732 | if (!card->sleep_cookie_vbase) { |
707 | dev_err(adapter->dev, | 733 | dev_err(adapter->dev, "pci_alloc_consistent failed!\n"); |
708 | "Unable to allocate skb for sleep cookie!\n"); | ||
709 | return -ENOMEM; | 734 | return -ENOMEM; |
710 | } | 735 | } |
711 | mwifiex_update_sk_buff_pa(skb); | ||
712 | skb_put(skb, sizeof(u32)); | ||
713 | |||
714 | /* Init val of Sleep Cookie */ | 736 | /* Init val of Sleep Cookie */ |
715 | *(u32 *)skb->data = FW_AWAKE_COOKIE; | 737 | *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE; |
716 | 738 | ||
717 | dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", | 739 | dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", |
718 | *((u32 *)skb->data)); | 740 | *((u32 *)card->sleep_cookie_vbase)); |
719 | |||
720 | /* Save the sleep cookie */ | ||
721 | card->sleep_cookie = skb; | ||
722 | 741 | ||
723 | return 0; | 742 | return 0; |
724 | } | 743 | } |
@@ -735,24 +754,57 @@ static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter) | |||
735 | 754 | ||
736 | card = adapter->card; | 755 | card = adapter->card; |
737 | 756 | ||
738 | if (card && card->sleep_cookie) { | 757 | if (card && card->sleep_cookie_vbase) { |
739 | dev_kfree_skb_any(card->sleep_cookie); | 758 | pci_free_consistent(card->dev, sizeof(u32), |
740 | card->sleep_cookie = NULL; | 759 | card->sleep_cookie_vbase, |
760 | card->sleep_cookie_pbase); | ||
761 | card->sleep_cookie_vbase = NULL; | ||
741 | } | 762 | } |
742 | 763 | ||
743 | return 0; | 764 | return 0; |
744 | } | 765 | } |
745 | 766 | ||
767 | /* This function flushes the TX buffer descriptor ring | ||
768 | * This function defined as handler is also called while cleaning TXRX | ||
769 | * during disconnect/ bss stop. | ||
770 | */ | ||
771 | static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter) | ||
772 | { | ||
773 | struct pcie_service_card *card = adapter->card; | ||
774 | u32 rdptr; | ||
775 | |||
776 | /* Read the TX ring read pointer set by firmware */ | ||
777 | if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { | ||
778 | dev_err(adapter->dev, | ||
779 | "Flush TXBD: failed to read REG_TXBD_RDPTR\n"); | ||
780 | return -1; | ||
781 | } | ||
782 | |||
783 | if (!mwifiex_pcie_txbd_empty(card, rdptr)) { | ||
784 | card->txbd_flush = 1; | ||
785 | /* write pointer already set at last send | ||
786 | * send dnld-rdy intr again, wait for completion. | ||
787 | */ | ||
788 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | ||
789 | CPU_INTR_DNLD_RDY)) { | ||
790 | dev_err(adapter->dev, | ||
791 | "failed to assert dnld-rdy interrupt.\n"); | ||
792 | return -1; | ||
793 | } | ||
794 | } | ||
795 | return 0; | ||
796 | } | ||
797 | |||
746 | /* | 798 | /* |
747 | * This function sends data buffer to device | 799 | * This function unmaps and frees downloaded data buffer |
748 | */ | 800 | */ |
749 | static int | 801 | static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) |
750 | mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | ||
751 | { | 802 | { |
803 | const u32 num_tx_buffs = MWIFIEX_MAX_TXRX_BD; | ||
804 | struct sk_buff *skb; | ||
805 | dma_addr_t buf_pa; | ||
806 | u32 wrdoneidx, rdptr, unmap_count = 0; | ||
752 | struct pcie_service_card *card = adapter->card; | 807 | struct pcie_service_card *card = adapter->card; |
753 | u32 wrindx, rdptr; | ||
754 | phys_addr_t *buf_pa; | ||
755 | __le16 *tmp; | ||
756 | 808 | ||
757 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) | 809 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) |
758 | mwifiex_pm_wakeup_card(adapter); | 810 | mwifiex_pm_wakeup_card(adapter); |
@@ -760,34 +812,112 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
760 | /* Read the TX ring read pointer set by firmware */ | 812 | /* Read the TX ring read pointer set by firmware */ |
761 | if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { | 813 | if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { |
762 | dev_err(adapter->dev, | 814 | dev_err(adapter->dev, |
763 | "SEND DATA: failed to read REG_TXBD_RDPTR\n"); | 815 | "SEND COMP: failed to read REG_TXBD_RDPTR\n"); |
764 | return -1; | 816 | return -1; |
765 | } | 817 | } |
766 | 818 | ||
767 | wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; | 819 | dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n", |
820 | card->txbd_rdptr, rdptr); | ||
768 | 821 | ||
769 | dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr, | 822 | /* free from previous txbd_rdptr to current txbd_rdptr */ |
770 | card->txbd_wrptr); | 823 | while (((card->txbd_rdptr & MWIFIEX_TXBD_MASK) != |
771 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != | 824 | (rdptr & MWIFIEX_TXBD_MASK)) || |
772 | (rdptr & MWIFIEX_TXBD_MASK)) || | 825 | ((card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != |
773 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != | 826 | (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { |
774 | (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { | 827 | wrdoneidx = card->txbd_rdptr & MWIFIEX_TXBD_MASK; |
775 | struct sk_buff *skb_data; | 828 | |
829 | skb = card->tx_buf_list[wrdoneidx]; | ||
830 | if (skb) { | ||
831 | dev_dbg(adapter->dev, | ||
832 | "SEND COMP: Detach skb %p at txbd_rdidx=%d\n", | ||
833 | skb, wrdoneidx); | ||
834 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
835 | pci_unmap_single(card->dev, buf_pa, skb->len, | ||
836 | PCI_DMA_TODEVICE); | ||
837 | |||
838 | unmap_count++; | ||
839 | |||
840 | if (card->txbd_flush) | ||
841 | mwifiex_write_data_complete(adapter, skb, 0, | ||
842 | -1); | ||
843 | else | ||
844 | mwifiex_write_data_complete(adapter, skb, 0, 0); | ||
845 | } | ||
846 | |||
847 | card->tx_buf_list[wrdoneidx] = NULL; | ||
848 | card->txbd_ring[wrdoneidx]->paddr = 0; | ||
849 | card->rxbd_ring[wrdoneidx]->len = 0; | ||
850 | card->rxbd_ring[wrdoneidx]->flags = 0; | ||
851 | card->txbd_rdptr++; | ||
852 | |||
853 | if ((card->txbd_rdptr & MWIFIEX_TXBD_MASK) == num_tx_buffs) | ||
854 | card->txbd_rdptr = ((card->txbd_rdptr & | ||
855 | MWIFIEX_BD_FLAG_ROLLOVER_IND) ^ | ||
856 | MWIFIEX_BD_FLAG_ROLLOVER_IND); | ||
857 | } | ||
858 | |||
859 | if (unmap_count) | ||
860 | adapter->data_sent = false; | ||
861 | |||
862 | if (card->txbd_flush) { | ||
863 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) == | ||
864 | (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) && | ||
865 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != | ||
866 | (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) | ||
867 | card->txbd_flush = 0; | ||
868 | else | ||
869 | mwifiex_clean_pcie_ring_buf(adapter); | ||
870 | } | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | /* This function sends data buffer to device. First 4 bytes of payload | ||
876 | * are filled with payload length and payload type. Then this payload | ||
877 | * is mapped to PCI device memory. Tx ring pointers are advanced accordingly. | ||
878 | * Download ready interrupt to FW is deffered if Tx ring is not full and | ||
879 | * additional payload can be accomodated. | ||
880 | */ | ||
881 | static int | ||
882 | mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, | ||
883 | struct mwifiex_tx_param *tx_param) | ||
884 | { | ||
885 | struct pcie_service_card *card = adapter->card; | ||
886 | u32 wrindx; | ||
887 | int ret; | ||
888 | dma_addr_t buf_pa; | ||
889 | __le16 *tmp; | ||
890 | |||
891 | if (!(skb->data && skb->len)) { | ||
892 | dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n", | ||
893 | __func__, skb->data, skb->len); | ||
894 | return -1; | ||
895 | } | ||
896 | |||
897 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) | ||
898 | mwifiex_pm_wakeup_card(adapter); | ||
899 | |||
900 | dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", | ||
901 | card->txbd_rdptr, card->txbd_wrptr); | ||
902 | if (mwifiex_pcie_txbd_not_full(card)) { | ||
776 | u8 *payload; | 903 | u8 *payload; |
777 | 904 | ||
778 | adapter->data_sent = true; | 905 | adapter->data_sent = true; |
779 | skb_data = card->tx_buf_list[wrindx]; | 906 | payload = skb->data; |
780 | memcpy(skb_data->data, skb->data, skb->len); | ||
781 | payload = skb_data->data; | ||
782 | tmp = (__le16 *)&payload[0]; | 907 | tmp = (__le16 *)&payload[0]; |
783 | *tmp = cpu_to_le16((u16)skb->len); | 908 | *tmp = cpu_to_le16((u16)skb->len); |
784 | tmp = (__le16 *)&payload[2]; | 909 | tmp = (__le16 *)&payload[2]; |
785 | *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA); | 910 | *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA); |
786 | skb_put(skb_data, MWIFIEX_RX_DATA_BUF_SIZE - skb_data->len); | 911 | |
787 | skb_trim(skb_data, skb->len); | 912 | if (mwifiex_map_pci_memory(adapter, skb, skb->len , |
788 | buf_pa = MWIFIEX_SKB_PACB(skb_data); | 913 | PCI_DMA_TODEVICE)) |
789 | card->txbd_ring[wrindx]->paddr = *buf_pa; | 914 | return -1; |
790 | card->txbd_ring[wrindx]->len = (u16)skb_data->len; | 915 | |
916 | wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; | ||
917 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
918 | card->tx_buf_list[wrindx] = skb; | ||
919 | card->txbd_ring[wrindx]->paddr = buf_pa; | ||
920 | card->txbd_ring[wrindx]->len = (u16)skb->len; | ||
791 | card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC | | 921 | card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC | |
792 | MWIFIEX_BD_FLAG_LAST_DESC; | 922 | MWIFIEX_BD_FLAG_LAST_DESC; |
793 | 923 | ||
@@ -802,19 +932,28 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
802 | card->txbd_wrptr)) { | 932 | card->txbd_wrptr)) { |
803 | dev_err(adapter->dev, | 933 | dev_err(adapter->dev, |
804 | "SEND DATA: failed to write REG_TXBD_WRPTR\n"); | 934 | "SEND DATA: failed to write REG_TXBD_WRPTR\n"); |
805 | return 0; | 935 | ret = -1; |
936 | goto done_unmap; | ||
806 | } | 937 | } |
807 | 938 | if ((mwifiex_pcie_txbd_not_full(card)) && | |
808 | /* Send the TX ready interrupt */ | 939 | tx_param->next_pkt_len) { |
809 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 940 | /* have more packets and TxBD still can hold more */ |
810 | CPU_INTR_DNLD_RDY)) { | 941 | dev_dbg(adapter->dev, |
811 | dev_err(adapter->dev, | 942 | "SEND DATA: delay dnld-rdy interrupt.\n"); |
812 | "SEND DATA: failed to assert door-bell intr\n"); | 943 | adapter->data_sent = false; |
813 | return -1; | 944 | } else { |
945 | /* Send the TX ready interrupt */ | ||
946 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | ||
947 | CPU_INTR_DNLD_RDY)) { | ||
948 | dev_err(adapter->dev, | ||
949 | "SEND DATA: failed to assert dnld-rdy interrupt.\n"); | ||
950 | ret = -1; | ||
951 | goto done_unmap; | ||
952 | } | ||
814 | } | 953 | } |
815 | dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " | 954 | dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " |
816 | "%#x> and sent packet to firmware successfully\n", | 955 | "%#x> and sent packet to firmware successfully\n", |
817 | rdptr, card->txbd_wrptr); | 956 | card->txbd_rdptr, card->txbd_wrptr); |
818 | } else { | 957 | } else { |
819 | dev_dbg(adapter->dev, | 958 | dev_dbg(adapter->dev, |
820 | "info: TX Ring full, can't send packets to fw\n"); | 959 | "info: TX Ring full, can't send packets to fw\n"); |
@@ -827,7 +966,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
827 | return -EBUSY; | 966 | return -EBUSY; |
828 | } | 967 | } |
829 | 968 | ||
830 | return 0; | 969 | return -EINPROGRESS; |
970 | done_unmap: | ||
971 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
972 | pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE); | ||
973 | card->tx_buf_list[wrindx] = NULL; | ||
974 | card->txbd_ring[wrindx]->paddr = 0; | ||
975 | card->txbd_ring[wrindx]->len = 0; | ||
976 | card->txbd_ring[wrindx]->flags = 0; | ||
977 | return ret; | ||
831 | } | 978 | } |
832 | 979 | ||
833 | /* | 980 | /* |
@@ -838,9 +985,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
838 | { | 985 | { |
839 | struct pcie_service_card *card = adapter->card; | 986 | struct pcie_service_card *card = adapter->card; |
840 | u32 wrptr, rd_index; | 987 | u32 wrptr, rd_index; |
988 | dma_addr_t buf_pa; | ||
841 | int ret = 0; | 989 | int ret = 0; |
842 | struct sk_buff *skb_tmp = NULL; | 990 | struct sk_buff *skb_tmp = NULL; |
843 | 991 | ||
992 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) | ||
993 | mwifiex_pm_wakeup_card(adapter); | ||
994 | |||
844 | /* Read the RX ring Write pointer set by firmware */ | 995 | /* Read the RX ring Write pointer set by firmware */ |
845 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { | 996 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { |
846 | dev_err(adapter->dev, | 997 | dev_err(adapter->dev, |
@@ -848,6 +999,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
848 | ret = -1; | 999 | ret = -1; |
849 | goto done; | 1000 | goto done; |
850 | } | 1001 | } |
1002 | card->rxbd_wrptr = wrptr; | ||
851 | 1003 | ||
852 | while (((wrptr & MWIFIEX_RXBD_MASK) != | 1004 | while (((wrptr & MWIFIEX_RXBD_MASK) != |
853 | (card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) || | 1005 | (card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) || |
@@ -855,27 +1007,50 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
855 | (card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { | 1007 | (card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { |
856 | struct sk_buff *skb_data; | 1008 | struct sk_buff *skb_data; |
857 | u16 rx_len; | 1009 | u16 rx_len; |
1010 | __le16 pkt_len; | ||
858 | 1011 | ||
859 | rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK; | 1012 | rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK; |
860 | skb_data = card->rx_buf_list[rd_index]; | 1013 | skb_data = card->rx_buf_list[rd_index]; |
861 | 1014 | ||
1015 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); | ||
1016 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, | ||
1017 | PCI_DMA_FROMDEVICE); | ||
1018 | card->rx_buf_list[rd_index] = NULL; | ||
1019 | |||
862 | /* Get data length from interface header - | 1020 | /* Get data length from interface header - |
863 | first byte is len, second byte is type */ | 1021 | * first 2 bytes for len, next 2 bytes is for type |
864 | rx_len = *((u16 *)skb_data->data); | 1022 | */ |
1023 | pkt_len = *((__le16 *)skb_data->data); | ||
1024 | rx_len = le16_to_cpu(pkt_len); | ||
1025 | skb_put(skb_data, rx_len); | ||
865 | dev_dbg(adapter->dev, | 1026 | dev_dbg(adapter->dev, |
866 | "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", | 1027 | "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", |
867 | card->rxbd_rdptr, wrptr, rx_len); | 1028 | card->rxbd_rdptr, wrptr, rx_len); |
868 | skb_tmp = dev_alloc_skb(rx_len); | 1029 | skb_pull(skb_data, INTF_HEADER_LEN); |
1030 | mwifiex_handle_rx_packet(adapter, skb_data); | ||
1031 | |||
1032 | skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); | ||
869 | if (!skb_tmp) { | 1033 | if (!skb_tmp) { |
870 | dev_dbg(adapter->dev, | 1034 | dev_err(adapter->dev, |
871 | "info: Failed to alloc skb for RX\n"); | 1035 | "Unable to allocate skb.\n"); |
872 | ret = -EBUSY; | 1036 | return -ENOMEM; |
873 | goto done; | ||
874 | } | 1037 | } |
875 | 1038 | ||
876 | skb_put(skb_tmp, rx_len); | 1039 | if (mwifiex_map_pci_memory(adapter, skb_tmp, |
1040 | MWIFIEX_RX_DATA_BUF_SIZE, | ||
1041 | PCI_DMA_FROMDEVICE)) | ||
1042 | return -1; | ||
1043 | |||
1044 | MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); | ||
1045 | |||
1046 | dev_dbg(adapter->dev, | ||
1047 | "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", | ||
1048 | skb_tmp, rd_index); | ||
1049 | card->rx_buf_list[rd_index] = skb_tmp; | ||
1050 | card->rxbd_ring[rd_index]->paddr = buf_pa; | ||
1051 | card->rxbd_ring[rd_index]->len = skb_tmp->len; | ||
1052 | card->rxbd_ring[rd_index]->flags = 0; | ||
877 | 1053 | ||
878 | memcpy(skb_tmp->data, skb_data->data + INTF_HEADER_LEN, rx_len); | ||
879 | if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) == | 1054 | if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) == |
880 | MWIFIEX_MAX_TXRX_BD) { | 1055 | MWIFIEX_MAX_TXRX_BD) { |
881 | card->rxbd_rdptr = ((card->rxbd_rdptr & | 1056 | card->rxbd_rdptr = ((card->rxbd_rdptr & |
@@ -903,12 +1078,10 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
903 | } | 1078 | } |
904 | dev_dbg(adapter->dev, | 1079 | dev_dbg(adapter->dev, |
905 | "info: RECV DATA: Rcvd packet from fw successfully\n"); | 1080 | "info: RECV DATA: Rcvd packet from fw successfully\n"); |
906 | mwifiex_handle_rx_packet(adapter, skb_tmp); | 1081 | card->rxbd_wrptr = wrptr; |
907 | } | 1082 | } |
908 | 1083 | ||
909 | done: | 1084 | done: |
910 | if (ret && skb_tmp) | ||
911 | dev_kfree_skb_any(skb_tmp); | ||
912 | return ret; | 1085 | return ret; |
913 | } | 1086 | } |
914 | 1087 | ||
@@ -918,32 +1091,41 @@ done: | |||
918 | static int | 1091 | static int |
919 | mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | 1092 | mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) |
920 | { | 1093 | { |
921 | phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); | 1094 | dma_addr_t buf_pa; |
1095 | struct pcie_service_card *card = adapter->card; | ||
922 | 1096 | ||
923 | if (!(skb->data && skb->len && *buf_pa)) { | 1097 | if (!(skb->data && skb->len)) { |
924 | dev_err(adapter->dev, | 1098 | dev_err(adapter->dev, |
925 | "Invalid parameter in %s <%p, %#x:%x, %x>\n", | 1099 | "Invalid parameter in %s <%p. len %d>\n", |
926 | __func__, skb->data, skb->len, | 1100 | __func__, skb->data, skb->len); |
927 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); | ||
928 | return -1; | 1101 | return -1; |
929 | } | 1102 | } |
930 | 1103 | ||
1104 | if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE)) | ||
1105 | return -1; | ||
1106 | |||
1107 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
1108 | |||
931 | /* Write the lower 32bits of the physical address to scratch | 1109 | /* Write the lower 32bits of the physical address to scratch |
932 | * register 0 */ | 1110 | * register 0 */ |
933 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { | 1111 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)buf_pa)) { |
934 | dev_err(adapter->dev, | 1112 | dev_err(adapter->dev, |
935 | "%s: failed to write download command to boot code.\n", | 1113 | "%s: failed to write download command to boot code.\n", |
936 | __func__); | 1114 | __func__); |
1115 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, | ||
1116 | PCI_DMA_TODEVICE); | ||
937 | return -1; | 1117 | return -1; |
938 | } | 1118 | } |
939 | 1119 | ||
940 | /* Write the upper 32bits of the physical address to scratch | 1120 | /* Write the upper 32bits of the physical address to scratch |
941 | * register 1 */ | 1121 | * register 1 */ |
942 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, | 1122 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, |
943 | (u32)((u64)*buf_pa >> 32))) { | 1123 | (u32)((u64)buf_pa >> 32))) { |
944 | dev_err(adapter->dev, | 1124 | dev_err(adapter->dev, |
945 | "%s: failed to write download command to boot code.\n", | 1125 | "%s: failed to write download command to boot code.\n", |
946 | __func__); | 1126 | __func__); |
1127 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, | ||
1128 | PCI_DMA_TODEVICE); | ||
947 | return -1; | 1129 | return -1; |
948 | } | 1130 | } |
949 | 1131 | ||
@@ -952,6 +1134,8 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
952 | dev_err(adapter->dev, | 1134 | dev_err(adapter->dev, |
953 | "%s: failed to write command len to scratch reg 2\n", | 1135 | "%s: failed to write command len to scratch reg 2\n", |
954 | __func__); | 1136 | __func__); |
1137 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, | ||
1138 | PCI_DMA_TODEVICE); | ||
955 | return -1; | 1139 | return -1; |
956 | } | 1140 | } |
957 | 1141 | ||
@@ -960,22 +1144,39 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
960 | CPU_INTR_DOOR_BELL)) { | 1144 | CPU_INTR_DOOR_BELL)) { |
961 | dev_err(adapter->dev, | 1145 | dev_err(adapter->dev, |
962 | "%s: failed to assert door-bell intr\n", __func__); | 1146 | "%s: failed to assert door-bell intr\n", __func__); |
1147 | pci_unmap_single(card->dev, buf_pa, | ||
1148 | MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE); | ||
963 | return -1; | 1149 | return -1; |
964 | } | 1150 | } |
965 | 1151 | ||
966 | return 0; | 1152 | return 0; |
967 | } | 1153 | } |
968 | 1154 | ||
969 | /* | 1155 | /* This function init rx port in firmware which in turn enables to receive data |
970 | * This function downloads commands to the device | 1156 | * from device before transmitting any packet. |
1157 | */ | ||
1158 | static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) | ||
1159 | { | ||
1160 | struct pcie_service_card *card = adapter->card; | ||
1161 | |||
1162 | /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ | ||
1163 | if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr | 0)) { | ||
1164 | dev_err(adapter->dev, | ||
1165 | "RECV DATA: failed to write REG_RXBD_RDPTR\n"); | ||
1166 | return -1; | ||
1167 | } | ||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | /* This function downloads commands to the device | ||
971 | */ | 1172 | */ |
972 | static int | 1173 | static int |
973 | mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | 1174 | mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) |
974 | { | 1175 | { |
975 | struct pcie_service_card *card = adapter->card; | 1176 | struct pcie_service_card *card = adapter->card; |
976 | int ret = 0; | 1177 | int ret = 0; |
977 | phys_addr_t *cmd_buf_pa; | 1178 | dma_addr_t cmd_buf_pa, cmdrsp_buf_pa; |
978 | phys_addr_t *cmdrsp_buf_pa; | 1179 | u8 *payload = (u8 *)skb->data; |
979 | 1180 | ||
980 | if (!(skb->data && skb->len)) { | 1181 | if (!(skb->data && skb->len)) { |
981 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", | 1182 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", |
@@ -990,17 +1191,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
990 | return -EBUSY; | 1191 | return -EBUSY; |
991 | } | 1192 | } |
992 | 1193 | ||
993 | /* Make sure a command buffer is available */ | 1194 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) |
994 | if (!card->cmd_buf) { | 1195 | mwifiex_pm_wakeup_card(adapter); |
995 | dev_err(adapter->dev, "Command buffer not available\n"); | ||
996 | return -EBUSY; | ||
997 | } | ||
998 | 1196 | ||
999 | adapter->cmd_sent = true; | 1197 | adapter->cmd_sent = true; |
1000 | /* Copy the given skb in to DMA accessable shared buffer */ | 1198 | |
1001 | skb_put(card->cmd_buf, MWIFIEX_SIZE_OF_CMD_BUFFER - card->cmd_buf->len); | 1199 | *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len); |
1002 | skb_trim(card->cmd_buf, skb->len); | 1200 | *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD); |
1003 | memcpy(card->cmd_buf->data, skb->data, skb->len); | 1201 | |
1202 | if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE)) | ||
1203 | return -1; | ||
1204 | |||
1205 | card->cmd_buf = skb; | ||
1004 | 1206 | ||
1005 | /* To send a command, the driver will: | 1207 | /* To send a command, the driver will: |
1006 | 1. Write the 64bit physical address of the data buffer to | 1208 | 1. Write the 64bit physical address of the data buffer to |
@@ -1013,11 +1215,11 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1013 | */ | 1215 | */ |
1014 | 1216 | ||
1015 | if (card->cmdrsp_buf) { | 1217 | if (card->cmdrsp_buf) { |
1016 | cmdrsp_buf_pa = MWIFIEX_SKB_PACB(card->cmdrsp_buf); | 1218 | MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa); |
1017 | /* Write the lower 32bits of the cmdrsp buffer physical | 1219 | /* Write the lower 32bits of the cmdrsp buffer physical |
1018 | address */ | 1220 | address */ |
1019 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, | 1221 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, |
1020 | (u32)*cmdrsp_buf_pa)) { | 1222 | (u32)cmdrsp_buf_pa)) { |
1021 | dev_err(adapter->dev, | 1223 | dev_err(adapter->dev, |
1022 | "Failed to write download cmd to boot code.\n"); | 1224 | "Failed to write download cmd to boot code.\n"); |
1023 | ret = -1; | 1225 | ret = -1; |
@@ -1026,7 +1228,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1026 | /* Write the upper 32bits of the cmdrsp buffer physical | 1228 | /* Write the upper 32bits of the cmdrsp buffer physical |
1027 | address */ | 1229 | address */ |
1028 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, | 1230 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, |
1029 | (u32)((u64)*cmdrsp_buf_pa >> 32))) { | 1231 | (u32)((u64)cmdrsp_buf_pa >> 32))) { |
1030 | dev_err(adapter->dev, | 1232 | dev_err(adapter->dev, |
1031 | "Failed to write download cmd to boot code.\n"); | 1233 | "Failed to write download cmd to boot code.\n"); |
1032 | ret = -1; | 1234 | ret = -1; |
@@ -1034,9 +1236,9 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1034 | } | 1236 | } |
1035 | } | 1237 | } |
1036 | 1238 | ||
1037 | cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); | 1239 | MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa); |
1038 | /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ | 1240 | /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ |
1039 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) { | 1241 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)cmd_buf_pa)) { |
1040 | dev_err(adapter->dev, | 1242 | dev_err(adapter->dev, |
1041 | "Failed to write download cmd to boot code.\n"); | 1243 | "Failed to write download cmd to boot code.\n"); |
1042 | ret = -1; | 1244 | ret = -1; |
@@ -1044,7 +1246,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1044 | } | 1246 | } |
1045 | /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ | 1247 | /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ |
1046 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, | 1248 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, |
1047 | (u32)((u64)*cmd_buf_pa >> 32))) { | 1249 | (u32)((u64)cmd_buf_pa >> 32))) { |
1048 | dev_err(adapter->dev, | 1250 | dev_err(adapter->dev, |
1049 | "Failed to write download cmd to boot code.\n"); | 1251 | "Failed to write download cmd to boot code.\n"); |
1050 | ret = -1; | 1252 | ret = -1; |
@@ -1083,11 +1285,22 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
1083 | struct pcie_service_card *card = adapter->card; | 1285 | struct pcie_service_card *card = adapter->card; |
1084 | struct sk_buff *skb = card->cmdrsp_buf; | 1286 | struct sk_buff *skb = card->cmdrsp_buf; |
1085 | int count = 0; | 1287 | int count = 0; |
1288 | u16 rx_len; | ||
1289 | __le16 pkt_len; | ||
1290 | dma_addr_t buf_pa; | ||
1086 | 1291 | ||
1087 | dev_dbg(adapter->dev, "info: Rx CMD Response\n"); | 1292 | dev_dbg(adapter->dev, "info: Rx CMD Response\n"); |
1088 | 1293 | ||
1294 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
1295 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, | ||
1296 | PCI_DMA_FROMDEVICE); | ||
1297 | |||
1298 | pkt_len = *((__le16 *)skb->data); | ||
1299 | rx_len = le16_to_cpu(pkt_len); | ||
1300 | skb_trim(skb, rx_len); | ||
1301 | skb_pull(skb, INTF_HEADER_LEN); | ||
1302 | |||
1089 | if (!adapter->curr_cmd) { | 1303 | if (!adapter->curr_cmd) { |
1090 | skb_pull(skb, INTF_HEADER_LEN); | ||
1091 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { | 1304 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { |
1092 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, | 1305 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, |
1093 | skb->len); | 1306 | skb->len); |
@@ -1100,9 +1313,12 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
1100 | } | 1313 | } |
1101 | memcpy(adapter->upld_buf, skb->data, | 1314 | memcpy(adapter->upld_buf, skb->data, |
1102 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); | 1315 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); |
1103 | skb_push(skb, INTF_HEADER_LEN); | 1316 | if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, |
1317 | PCI_DMA_FROMDEVICE)) | ||
1318 | return -1; | ||
1319 | |||
1320 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
1104 | } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { | 1321 | } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { |
1105 | skb_pull(skb, INTF_HEADER_LEN); | ||
1106 | adapter->curr_cmd->resp_skb = skb; | 1322 | adapter->curr_cmd->resp_skb = skb; |
1107 | adapter->cmd_resp_received = true; | 1323 | adapter->cmd_resp_received = true; |
1108 | /* Take the pointer and set it to CMD node and will | 1324 | /* Take the pointer and set it to CMD node and will |
@@ -1136,10 +1352,23 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, | |||
1136 | struct sk_buff *skb) | 1352 | struct sk_buff *skb) |
1137 | { | 1353 | { |
1138 | struct pcie_service_card *card = adapter->card; | 1354 | struct pcie_service_card *card = adapter->card; |
1355 | dma_addr_t buf_pa; | ||
1356 | struct sk_buff *skb_tmp; | ||
1139 | 1357 | ||
1140 | if (skb) { | 1358 | if (skb) { |
1141 | card->cmdrsp_buf = skb; | 1359 | card->cmdrsp_buf = skb; |
1142 | skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); | 1360 | skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); |
1361 | if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, | ||
1362 | PCI_DMA_FROMDEVICE)) | ||
1363 | return -1; | ||
1364 | } | ||
1365 | |||
1366 | skb_tmp = card->cmd_buf; | ||
1367 | if (skb_tmp) { | ||
1368 | MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); | ||
1369 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, | ||
1370 | PCI_DMA_FROMDEVICE); | ||
1371 | card->cmd_buf = NULL; | ||
1143 | } | 1372 | } |
1144 | 1373 | ||
1145 | return 0; | 1374 | return 0; |
@@ -1153,6 +1382,10 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) | |||
1153 | struct pcie_service_card *card = adapter->card; | 1382 | struct pcie_service_card *card = adapter->card; |
1154 | u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; | 1383 | u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; |
1155 | u32 wrptr, event; | 1384 | u32 wrptr, event; |
1385 | dma_addr_t buf_pa; | ||
1386 | |||
1387 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) | ||
1388 | mwifiex_pm_wakeup_card(adapter); | ||
1156 | 1389 | ||
1157 | if (adapter->event_received) { | 1390 | if (adapter->event_received) { |
1158 | dev_dbg(adapter->dev, "info: Event being processed, " | 1391 | dev_dbg(adapter->dev, "info: Event being processed, " |
@@ -1184,6 +1417,10 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) | |||
1184 | 1417 | ||
1185 | dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr); | 1418 | dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr); |
1186 | skb_cmd = card->evt_buf_list[rdptr]; | 1419 | skb_cmd = card->evt_buf_list[rdptr]; |
1420 | MWIFIEX_SKB_PACB(skb_cmd, &buf_pa); | ||
1421 | pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE, | ||
1422 | PCI_DMA_FROMDEVICE); | ||
1423 | |||
1187 | /* Take the pointer and set it to event pointer in adapter | 1424 | /* Take the pointer and set it to event pointer in adapter |
1188 | and will return back after event handling callback */ | 1425 | and will return back after event handling callback */ |
1189 | card->evt_buf_list[rdptr] = NULL; | 1426 | card->evt_buf_list[rdptr] = NULL; |
@@ -1228,7 +1465,7 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1228 | int ret = 0; | 1465 | int ret = 0; |
1229 | u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; | 1466 | u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; |
1230 | u32 wrptr; | 1467 | u32 wrptr; |
1231 | phys_addr_t *buf_pa; | 1468 | dma_addr_t buf_pa; |
1232 | 1469 | ||
1233 | if (!skb) | 1470 | if (!skb) |
1234 | return 0; | 1471 | return 0; |
@@ -1248,9 +1485,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1248 | 1485 | ||
1249 | if (!card->evt_buf_list[rdptr]) { | 1486 | if (!card->evt_buf_list[rdptr]) { |
1250 | skb_push(skb, INTF_HEADER_LEN); | 1487 | skb_push(skb, INTF_HEADER_LEN); |
1488 | if (mwifiex_map_pci_memory(adapter, skb, | ||
1489 | MAX_EVENT_SIZE, | ||
1490 | PCI_DMA_FROMDEVICE)) | ||
1491 | return -1; | ||
1492 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
1251 | card->evt_buf_list[rdptr] = skb; | 1493 | card->evt_buf_list[rdptr] = skb; |
1252 | buf_pa = MWIFIEX_SKB_PACB(skb); | 1494 | MWIFIEX_SKB_PACB(skb, &buf_pa); |
1253 | card->evtbd_ring[rdptr]->paddr = *buf_pa; | 1495 | card->evtbd_ring[rdptr]->paddr = buf_pa; |
1254 | card->evtbd_ring[rdptr]->len = (u16)skb->len; | 1496 | card->evtbd_ring[rdptr]->len = (u16)skb->len; |
1255 | card->evtbd_ring[rdptr]->flags = 0; | 1497 | card->evtbd_ring[rdptr]->flags = 0; |
1256 | skb = NULL; | 1498 | skb = NULL; |
@@ -1299,11 +1541,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1299 | struct sk_buff *skb; | 1541 | struct sk_buff *skb; |
1300 | u32 txlen, tx_blocks = 0, tries, len; | 1542 | u32 txlen, tx_blocks = 0, tries, len; |
1301 | u32 block_retry_cnt = 0; | 1543 | u32 block_retry_cnt = 0; |
1302 | 1544 | dma_addr_t buf_pa; | |
1303 | if (!adapter) { | 1545 | struct pcie_service_card *card = adapter->card; |
1304 | pr_err("adapter structure is not valid\n"); | ||
1305 | return -1; | ||
1306 | } | ||
1307 | 1546 | ||
1308 | if (!firmware || !firmware_len) { | 1547 | if (!firmware || !firmware_len) { |
1309 | dev_err(adapter->dev, | 1548 | dev_err(adapter->dev, |
@@ -1325,7 +1564,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1325 | ret = -ENOMEM; | 1564 | ret = -ENOMEM; |
1326 | goto done; | 1565 | goto done; |
1327 | } | 1566 | } |
1328 | mwifiex_update_sk_buff_pa(skb); | ||
1329 | 1567 | ||
1330 | /* Perform firmware data transfer */ | 1568 | /* Perform firmware data transfer */ |
1331 | do { | 1569 | do { |
@@ -1400,6 +1638,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1400 | ret = -1; | 1638 | ret = -1; |
1401 | goto done; | 1639 | goto done; |
1402 | } | 1640 | } |
1641 | |||
1642 | MWIFIEX_SKB_PACB(skb, &buf_pa); | ||
1643 | |||
1403 | /* Wait for the command done interrupt */ | 1644 | /* Wait for the command done interrupt */ |
1404 | do { | 1645 | do { |
1405 | if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, | 1646 | if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, |
@@ -1407,11 +1648,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1407 | dev_err(adapter->dev, "%s: Failed to read " | 1648 | dev_err(adapter->dev, "%s: Failed to read " |
1408 | "interrupt status during fw dnld.\n", | 1649 | "interrupt status during fw dnld.\n", |
1409 | __func__); | 1650 | __func__); |
1651 | pci_unmap_single(card->dev, buf_pa, skb->len, | ||
1652 | PCI_DMA_TODEVICE); | ||
1410 | ret = -1; | 1653 | ret = -1; |
1411 | goto done; | 1654 | goto done; |
1412 | } | 1655 | } |
1413 | } while ((ireg_intr & CPU_INTR_DOOR_BELL) == | 1656 | } while ((ireg_intr & CPU_INTR_DOOR_BELL) == |
1414 | CPU_INTR_DOOR_BELL); | 1657 | CPU_INTR_DOOR_BELL); |
1658 | |||
1659 | pci_unmap_single(card->dev, buf_pa, skb->len, | ||
1660 | PCI_DMA_TODEVICE); | ||
1661 | |||
1415 | offset += txlen; | 1662 | offset += txlen; |
1416 | } while (true); | 1663 | } while (true); |
1417 | 1664 | ||
@@ -1594,39 +1841,40 @@ exit: | |||
1594 | static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | 1841 | static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) |
1595 | { | 1842 | { |
1596 | int ret; | 1843 | int ret; |
1597 | u32 pcie_ireg = 0; | 1844 | u32 pcie_ireg; |
1598 | unsigned long flags; | 1845 | unsigned long flags; |
1599 | 1846 | ||
1600 | spin_lock_irqsave(&adapter->int_lock, flags); | 1847 | spin_lock_irqsave(&adapter->int_lock, flags); |
1601 | /* Clear out unused interrupts */ | 1848 | /* Clear out unused interrupts */ |
1602 | adapter->int_status &= HOST_INTR_MASK; | 1849 | pcie_ireg = adapter->int_status; |
1850 | adapter->int_status = 0; | ||
1603 | spin_unlock_irqrestore(&adapter->int_lock, flags); | 1851 | spin_unlock_irqrestore(&adapter->int_lock, flags); |
1604 | 1852 | ||
1605 | while (adapter->int_status & HOST_INTR_MASK) { | 1853 | while (pcie_ireg & HOST_INTR_MASK) { |
1606 | if (adapter->int_status & HOST_INTR_DNLD_DONE) { | 1854 | if (pcie_ireg & HOST_INTR_DNLD_DONE) { |
1607 | adapter->int_status &= ~HOST_INTR_DNLD_DONE; | 1855 | pcie_ireg &= ~HOST_INTR_DNLD_DONE; |
1608 | if (adapter->data_sent) { | 1856 | dev_dbg(adapter->dev, "info: TX DNLD Done\n"); |
1609 | dev_dbg(adapter->dev, "info: DATA sent intr\n"); | 1857 | ret = mwifiex_pcie_send_data_complete(adapter); |
1610 | adapter->data_sent = false; | 1858 | if (ret) |
1611 | } | 1859 | return ret; |
1612 | } | 1860 | } |
1613 | if (adapter->int_status & HOST_INTR_UPLD_RDY) { | 1861 | if (pcie_ireg & HOST_INTR_UPLD_RDY) { |
1614 | adapter->int_status &= ~HOST_INTR_UPLD_RDY; | 1862 | pcie_ireg &= ~HOST_INTR_UPLD_RDY; |
1615 | dev_dbg(adapter->dev, "info: Rx DATA\n"); | 1863 | dev_dbg(adapter->dev, "info: Rx DATA\n"); |
1616 | ret = mwifiex_pcie_process_recv_data(adapter); | 1864 | ret = mwifiex_pcie_process_recv_data(adapter); |
1617 | if (ret) | 1865 | if (ret) |
1618 | return ret; | 1866 | return ret; |
1619 | } | 1867 | } |
1620 | if (adapter->int_status & HOST_INTR_EVENT_RDY) { | 1868 | if (pcie_ireg & HOST_INTR_EVENT_RDY) { |
1621 | adapter->int_status &= ~HOST_INTR_EVENT_RDY; | 1869 | pcie_ireg &= ~HOST_INTR_EVENT_RDY; |
1622 | dev_dbg(adapter->dev, "info: Rx EVENT\n"); | 1870 | dev_dbg(adapter->dev, "info: Rx EVENT\n"); |
1623 | ret = mwifiex_pcie_process_event_ready(adapter); | 1871 | ret = mwifiex_pcie_process_event_ready(adapter); |
1624 | if (ret) | 1872 | if (ret) |
1625 | return ret; | 1873 | return ret; |
1626 | } | 1874 | } |
1627 | 1875 | ||
1628 | if (adapter->int_status & HOST_INTR_CMD_DONE) { | 1876 | if (pcie_ireg & HOST_INTR_CMD_DONE) { |
1629 | adapter->int_status &= ~HOST_INTR_CMD_DONE; | 1877 | pcie_ireg &= ~HOST_INTR_CMD_DONE; |
1630 | if (adapter->cmd_sent) { | 1878 | if (adapter->cmd_sent) { |
1631 | dev_dbg(adapter->dev, | 1879 | dev_dbg(adapter->dev, |
1632 | "info: CMD sent Interrupt\n"); | 1880 | "info: CMD sent Interrupt\n"); |
@@ -1654,8 +1902,6 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1654 | "Write register failed\n"); | 1902 | "Write register failed\n"); |
1655 | return -1; | 1903 | return -1; |
1656 | } | 1904 | } |
1657 | adapter->int_status |= pcie_ireg; | ||
1658 | adapter->int_status &= HOST_INTR_MASK; | ||
1659 | } | 1905 | } |
1660 | 1906 | ||
1661 | } | 1907 | } |
@@ -1687,7 +1933,7 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type, | |||
1687 | } | 1933 | } |
1688 | 1934 | ||
1689 | if (type == MWIFIEX_TYPE_DATA) | 1935 | if (type == MWIFIEX_TYPE_DATA) |
1690 | return mwifiex_pcie_send_data(adapter, skb); | 1936 | return mwifiex_pcie_send_data(adapter, skb, tx_param); |
1691 | else if (type == MWIFIEX_TYPE_CMD) | 1937 | else if (type == MWIFIEX_TYPE_CMD) |
1692 | return mwifiex_pcie_send_cmd(adapter, skb); | 1938 | return mwifiex_pcie_send_cmd(adapter, skb); |
1693 | 1939 | ||
@@ -1814,15 +2060,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) | |||
1814 | struct pcie_service_card *card = adapter->card; | 2060 | struct pcie_service_card *card = adapter->card; |
1815 | struct pci_dev *pdev = card->dev; | 2061 | struct pci_dev *pdev = card->dev; |
1816 | 2062 | ||
1817 | mwifiex_pcie_delete_sleep_cookie_buf(adapter); | ||
1818 | mwifiex_pcie_delete_cmdrsp_buf(adapter); | ||
1819 | mwifiex_pcie_delete_evtbd_ring(adapter); | ||
1820 | mwifiex_pcie_delete_rxbd_ring(adapter); | ||
1821 | mwifiex_pcie_delete_txbd_ring(adapter); | ||
1822 | card->cmdrsp_buf = NULL; | ||
1823 | |||
1824 | dev_dbg(adapter->dev, "Clearing driver ready signature\n"); | ||
1825 | if (user_rmmod) { | 2063 | if (user_rmmod) { |
2064 | dev_dbg(adapter->dev, "Clearing driver ready signature\n"); | ||
1826 | if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) | 2065 | if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) |
1827 | dev_err(adapter->dev, | 2066 | dev_err(adapter->dev, |
1828 | "Failed to write driver not-ready signature\n"); | 2067 | "Failed to write driver not-ready signature\n"); |
@@ -1879,6 +2118,13 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) | |||
1879 | if (card) { | 2118 | if (card) { |
1880 | dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__); | 2119 | dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__); |
1881 | free_irq(card->dev->irq, card->dev); | 2120 | free_irq(card->dev->irq, card->dev); |
2121 | |||
2122 | mwifiex_pcie_delete_sleep_cookie_buf(adapter); | ||
2123 | mwifiex_pcie_delete_cmdrsp_buf(adapter); | ||
2124 | mwifiex_pcie_delete_evtbd_ring(adapter); | ||
2125 | mwifiex_pcie_delete_rxbd_ring(adapter); | ||
2126 | mwifiex_pcie_delete_txbd_ring(adapter); | ||
2127 | card->cmdrsp_buf = NULL; | ||
1882 | } | 2128 | } |
1883 | } | 2129 | } |
1884 | 2130 | ||
@@ -1900,6 +2146,8 @@ static struct mwifiex_if_ops pcie_ops = { | |||
1900 | .event_complete = mwifiex_pcie_event_complete, | 2146 | .event_complete = mwifiex_pcie_event_complete, |
1901 | .update_mp_end_port = NULL, | 2147 | .update_mp_end_port = NULL, |
1902 | .cleanup_mpa_buf = NULL, | 2148 | .cleanup_mpa_buf = NULL, |
2149 | .init_fw_port = mwifiex_pcie_init_fw_port, | ||
2150 | .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, | ||
1903 | }; | 2151 | }; |
1904 | 2152 | ||
1905 | /* | 2153 | /* |
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 2f218f9a3fd3..37eeb2ca6b29 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h | |||
@@ -114,11 +114,12 @@ struct pcie_service_card { | |||
114 | struct pci_dev *dev; | 114 | struct pci_dev *dev; |
115 | struct mwifiex_adapter *adapter; | 115 | struct mwifiex_adapter *adapter; |
116 | 116 | ||
117 | u8 txbd_flush; | ||
117 | u32 txbd_wrptr; | 118 | u32 txbd_wrptr; |
118 | u32 txbd_rdptr; | 119 | u32 txbd_rdptr; |
119 | u32 txbd_ring_size; | 120 | u32 txbd_ring_size; |
120 | u8 *txbd_ring_vbase; | 121 | u8 *txbd_ring_vbase; |
121 | phys_addr_t txbd_ring_pbase; | 122 | dma_addr_t txbd_ring_pbase; |
122 | struct mwifiex_pcie_buf_desc *txbd_ring[MWIFIEX_MAX_TXRX_BD]; | 123 | struct mwifiex_pcie_buf_desc *txbd_ring[MWIFIEX_MAX_TXRX_BD]; |
123 | struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD]; | 124 | struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD]; |
124 | 125 | ||
@@ -126,7 +127,7 @@ struct pcie_service_card { | |||
126 | u32 rxbd_rdptr; | 127 | u32 rxbd_rdptr; |
127 | u32 rxbd_ring_size; | 128 | u32 rxbd_ring_size; |
128 | u8 *rxbd_ring_vbase; | 129 | u8 *rxbd_ring_vbase; |
129 | phys_addr_t rxbd_ring_pbase; | 130 | dma_addr_t rxbd_ring_pbase; |
130 | struct mwifiex_pcie_buf_desc *rxbd_ring[MWIFIEX_MAX_TXRX_BD]; | 131 | struct mwifiex_pcie_buf_desc *rxbd_ring[MWIFIEX_MAX_TXRX_BD]; |
131 | struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD]; | 132 | struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD]; |
132 | 133 | ||
@@ -134,15 +135,39 @@ struct pcie_service_card { | |||
134 | u32 evtbd_rdptr; | 135 | u32 evtbd_rdptr; |
135 | u32 evtbd_ring_size; | 136 | u32 evtbd_ring_size; |
136 | u8 *evtbd_ring_vbase; | 137 | u8 *evtbd_ring_vbase; |
137 | phys_addr_t evtbd_ring_pbase; | 138 | dma_addr_t evtbd_ring_pbase; |
138 | struct mwifiex_pcie_buf_desc *evtbd_ring[MWIFIEX_MAX_EVT_BD]; | 139 | struct mwifiex_pcie_buf_desc *evtbd_ring[MWIFIEX_MAX_EVT_BD]; |
139 | struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD]; | 140 | struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD]; |
140 | 141 | ||
141 | struct sk_buff *cmd_buf; | 142 | struct sk_buff *cmd_buf; |
142 | struct sk_buff *cmdrsp_buf; | 143 | struct sk_buff *cmdrsp_buf; |
143 | struct sk_buff *sleep_cookie; | 144 | u8 *sleep_cookie_vbase; |
145 | dma_addr_t sleep_cookie_pbase; | ||
144 | void __iomem *pci_mmap; | 146 | void __iomem *pci_mmap; |
145 | void __iomem *pci_mmap1; | 147 | void __iomem *pci_mmap1; |
146 | }; | 148 | }; |
147 | 149 | ||
150 | static inline int | ||
151 | mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr) | ||
152 | { | ||
153 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) == | ||
154 | (rdptr & MWIFIEX_TXBD_MASK)) && | ||
155 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != | ||
156 | (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) | ||
157 | return 1; | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static inline int | ||
163 | mwifiex_pcie_txbd_not_full(struct pcie_service_card *card) | ||
164 | { | ||
165 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != | ||
166 | (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) || | ||
167 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != | ||
168 | (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) | ||
169 | return 1; | ||
170 | |||
171 | return 0; | ||
172 | } | ||
148 | #endif /* _MWIFIEX_PCIE_H */ | 173 | #endif /* _MWIFIEX_PCIE_H */ |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 5d87195390f8..c4607859d59d 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -931,7 +931,6 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, | |||
931 | struct host_cmd_ds_pcie_details *host_spec = | 931 | struct host_cmd_ds_pcie_details *host_spec = |
932 | &cmd->params.pcie_host_spec; | 932 | &cmd->params.pcie_host_spec; |
933 | struct pcie_service_card *card = priv->adapter->card; | 933 | struct pcie_service_card *card = priv->adapter->card; |
934 | phys_addr_t *buf_pa; | ||
935 | 934 | ||
936 | cmd->command = cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS); | 935 | cmd->command = cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS); |
937 | cmd->size = cpu_to_le16(sizeof(struct | 936 | cmd->size = cpu_to_le16(sizeof(struct |
@@ -953,10 +952,11 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, | |||
953 | host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase); | 952 | host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase); |
954 | host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32); | 953 | host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32); |
955 | host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; | 954 | host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; |
956 | if (card->sleep_cookie) { | 955 | if (card->sleep_cookie_vbase) { |
957 | buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); | 956 | host_spec->sleep_cookie_addr_lo = |
958 | host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; | 957 | (u32)(card->sleep_cookie_pbase); |
959 | host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32); | 958 | host_spec->sleep_cookie_addr_hi = |
959 | (u32)(((u64)(card->sleep_cookie_pbase)) >> 32); | ||
960 | dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n", | 960 | dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n", |
961 | host_spec->sleep_cookie_addr_lo); | 961 | host_spec->sleep_cookie_addr_lo); |
962 | } | 962 | } |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 60e88b58039d..f542bb8ccbc8 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -283,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
283 | if (ret) | 283 | if (ret) |
284 | goto done; | 284 | goto done; |
285 | 285 | ||
286 | if (bss_desc) { | ||
287 | u8 config_bands = 0; | ||
288 | |||
289 | if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band) | ||
290 | == HostCmd_SCAN_RADIO_TYPE_BG) | ||
291 | config_bands = BAND_B | BAND_G | BAND_GN; | ||
292 | else | ||
293 | config_bands = BAND_A | BAND_AN; | ||
294 | |||
295 | if (!((config_bands | adapter->fw_bands) & | ||
296 | ~adapter->fw_bands)) | ||
297 | adapter->config_bands = config_bands; | ||
298 | } | ||
299 | |||
286 | ret = mwifiex_check_network_compatibility(priv, bss_desc); | 300 | ret = mwifiex_check_network_compatibility(priv, bss_desc); |
287 | if (ret) | 301 | if (ret) |
288 | goto done; | 302 | goto done; |
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 8c80024c30ff..296faec14365 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c | |||
@@ -117,14 +117,16 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | |||
117 | dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); | 117 | dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); |
118 | break; | 118 | break; |
119 | case -1: | 119 | case -1: |
120 | adapter->data_sent = false; | 120 | if (adapter->iface_type != MWIFIEX_PCIE) |
121 | adapter->data_sent = false; | ||
121 | dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", | 122 | dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", |
122 | ret); | 123 | ret); |
123 | adapter->dbg.num_tx_host_to_card_failure++; | 124 | adapter->dbg.num_tx_host_to_card_failure++; |
124 | mwifiex_write_data_complete(adapter, skb, 0, ret); | 125 | mwifiex_write_data_complete(adapter, skb, 0, ret); |
125 | break; | 126 | break; |
126 | case -EINPROGRESS: | 127 | case -EINPROGRESS: |
127 | adapter->data_sent = false; | 128 | if (adapter->iface_type != MWIFIEX_PCIE) |
129 | adapter->data_sent = false; | ||
128 | break; | 130 | break; |
129 | case 0: | 131 | case 0: |
130 | mwifiex_write_data_complete(adapter, skb, 0, ret); | 132 | mwifiex_write_data_complete(adapter, skb, 0, ret); |
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 8dd72240f162..6e76a15a8950 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c | |||
@@ -219,6 +219,7 @@ void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config) | |||
219 | config->rts_threshold = 0x7FFF; | 219 | config->rts_threshold = 0x7FFF; |
220 | config->frag_threshold = 0x7FFF; | 220 | config->frag_threshold = 0x7FFF; |
221 | config->retry_limit = 0x7F; | 221 | config->retry_limit = 0x7F; |
222 | config->qos_info = 0xFF; | ||
222 | } | 223 | } |
223 | 224 | ||
224 | /* This function parses BSS related parameters from structure | 225 | /* This function parses BSS related parameters from structure |
@@ -297,6 +298,38 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size) | |||
297 | return; | 298 | return; |
298 | } | 299 | } |
299 | 300 | ||
301 | /* This function parses WMM related parameters from cfg80211_ap_settings | ||
302 | * structure and updates bss_config structure. | ||
303 | */ | ||
304 | void | ||
305 | mwifiex_set_wmm_params(struct mwifiex_private *priv, | ||
306 | struct mwifiex_uap_bss_param *bss_cfg, | ||
307 | struct cfg80211_ap_settings *params) | ||
308 | { | ||
309 | const u8 *vendor_ie; | ||
310 | struct ieee_types_header *wmm_ie; | ||
311 | u8 wmm_oui[] = {0x00, 0x50, 0xf2, 0x02}; | ||
312 | |||
313 | vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, | ||
314 | WLAN_OUI_TYPE_MICROSOFT_WMM, | ||
315 | params->beacon.tail, | ||
316 | params->beacon.tail_len); | ||
317 | if (vendor_ie) { | ||
318 | wmm_ie = (struct ieee_types_header *)vendor_ie; | ||
319 | memcpy(&bss_cfg->wmm_info, wmm_ie + 1, | ||
320 | sizeof(bss_cfg->wmm_info)); | ||
321 | priv->wmm_enabled = 1; | ||
322 | } else { | ||
323 | memset(&bss_cfg->wmm_info, 0, sizeof(bss_cfg->wmm_info)); | ||
324 | memcpy(&bss_cfg->wmm_info.oui, wmm_oui, sizeof(wmm_oui)); | ||
325 | bss_cfg->wmm_info.subtype = MWIFIEX_WMM_SUBTYPE; | ||
326 | bss_cfg->wmm_info.version = MWIFIEX_WMM_VERSION; | ||
327 | priv->wmm_enabled = 0; | ||
328 | } | ||
329 | |||
330 | bss_cfg->qos_info = 0x00; | ||
331 | return; | ||
332 | } | ||
300 | /* This function parses BSS related parameters from structure | 333 | /* This function parses BSS related parameters from structure |
301 | * and prepares TLVs specific to WEP encryption. | 334 | * and prepares TLVs specific to WEP encryption. |
302 | * These TLVs are appended to command buffer. | 335 | * These TLVs are appended to command buffer. |
@@ -354,6 +387,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) | |||
354 | struct host_cmd_tlv_rates *tlv_rates; | 387 | struct host_cmd_tlv_rates *tlv_rates; |
355 | struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer; | 388 | struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer; |
356 | struct mwifiex_ie_types_htcap *htcap; | 389 | struct mwifiex_ie_types_htcap *htcap; |
390 | struct mwifiex_ie_types_wmmcap *wmm_cap; | ||
357 | struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; | 391 | struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; |
358 | int i; | 392 | int i; |
359 | u16 cmd_size = *param_size; | 393 | u16 cmd_size = *param_size; |
@@ -507,6 +541,16 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) | |||
507 | tlv += sizeof(struct mwifiex_ie_types_htcap); | 541 | tlv += sizeof(struct mwifiex_ie_types_htcap); |
508 | } | 542 | } |
509 | 543 | ||
544 | if (bss_cfg->wmm_info.qos_info != 0xFF) { | ||
545 | wmm_cap = (struct mwifiex_ie_types_wmmcap *)tlv; | ||
546 | wmm_cap->header.type = cpu_to_le16(WLAN_EID_VENDOR_SPECIFIC); | ||
547 | wmm_cap->header.len = cpu_to_le16(sizeof(wmm_cap->wmm_info)); | ||
548 | memcpy(&wmm_cap->wmm_info, &bss_cfg->wmm_info, | ||
549 | sizeof(wmm_cap->wmm_info)); | ||
550 | cmd_size += sizeof(struct mwifiex_ie_types_wmmcap); | ||
551 | tlv += sizeof(struct mwifiex_ie_types_wmmcap); | ||
552 | } | ||
553 | |||
510 | if (bss_cfg->sta_ao_timer) { | 554 | if (bss_cfg->sta_ao_timer) { |
511 | ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv; | 555 | ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv; |
512 | ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER); | 556 | ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER); |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 63ac9f2d11ae..5d4a10a8a005 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
@@ -786,21 +786,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | |||
786 | return 0; | 786 | return 0; |
787 | } | 787 | } |
788 | 788 | ||
789 | /* This function reads one block of firmware data. */ | ||
790 | static int mwifiex_get_fw_data(struct mwifiex_adapter *adapter, | ||
791 | u32 offset, u32 len, u8 *buf) | ||
792 | { | ||
793 | if (!buf || !len) | ||
794 | return -1; | ||
795 | |||
796 | if (offset + len > adapter->firmware->size) | ||
797 | return -1; | ||
798 | |||
799 | memcpy(buf, adapter->firmware->data + offset, len); | ||
800 | |||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | 789 | static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, |
805 | struct mwifiex_fw_image *fw) | 790 | struct mwifiex_fw_image *fw) |
806 | { | 791 | { |
@@ -836,23 +821,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
836 | dlen = 0; | 821 | dlen = 0; |
837 | } else { | 822 | } else { |
838 | /* copy the header of the fw_data to get the length */ | 823 | /* copy the header of the fw_data to get the length */ |
839 | if (firmware) | 824 | memcpy(&fwdata->fw_hdr, &firmware[tlen], |
840 | memcpy(&fwdata->fw_hdr, &firmware[tlen], | 825 | sizeof(struct fw_header)); |
841 | sizeof(struct fw_header)); | ||
842 | else | ||
843 | mwifiex_get_fw_data(adapter, tlen, | ||
844 | sizeof(struct fw_header), | ||
845 | (u8 *)&fwdata->fw_hdr); | ||
846 | 826 | ||
847 | dlen = le32_to_cpu(fwdata->fw_hdr.data_len); | 827 | dlen = le32_to_cpu(fwdata->fw_hdr.data_len); |
848 | dnld_cmd = le32_to_cpu(fwdata->fw_hdr.dnld_cmd); | 828 | dnld_cmd = le32_to_cpu(fwdata->fw_hdr.dnld_cmd); |
849 | tlen += sizeof(struct fw_header); | 829 | tlen += sizeof(struct fw_header); |
850 | 830 | ||
851 | if (firmware) | 831 | memcpy(fwdata->data, &firmware[tlen], dlen); |
852 | memcpy(fwdata->data, &firmware[tlen], dlen); | ||
853 | else | ||
854 | mwifiex_get_fw_data(adapter, tlen, dlen, | ||
855 | (u8 *)fwdata->data); | ||
856 | 832 | ||
857 | fwdata->seq_num = cpu_to_le32(fw_seqnum); | 833 | fwdata->seq_num = cpu_to_le32(fw_seqnum); |
858 | tlen += dlen; | 834 | tlen += dlen; |
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h index f6d36b9654a0..cb2d0582bd36 100644 --- a/drivers/net/wireless/mwifiex/util.h +++ b/drivers/net/wireless/mwifiex/util.h | |||
@@ -22,16 +22,16 @@ | |||
22 | 22 | ||
23 | static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) | 23 | static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) |
24 | { | 24 | { |
25 | return (struct mwifiex_rxinfo *)(skb->cb + sizeof(phys_addr_t)); | 25 | return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t)); |
26 | } | 26 | } |
27 | 27 | ||
28 | static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb) | 28 | static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb) |
29 | { | 29 | { |
30 | return (struct mwifiex_txinfo *)(skb->cb + sizeof(phys_addr_t)); | 30 | return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t)); |
31 | } | 31 | } |
32 | 32 | ||
33 | static inline phys_addr_t *MWIFIEX_SKB_PACB(struct sk_buff *skb) | 33 | static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb, dma_addr_t *buf_pa) |
34 | { | 34 | { |
35 | return (phys_addr_t *)skb->cb; | 35 | memcpy(buf_pa, skb->cb, sizeof(dma_addr_t)); |
36 | } | 36 | } |
37 | #endif /* !_MWIFIEX_UTIL_H_ */ | 37 | #endif /* !_MWIFIEX_UTIL_H_ */ |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 818f871ae987..135d96df2063 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -568,6 +568,8 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) | |||
568 | mwifiex_wmm_delete_all_ralist(priv); | 568 | mwifiex_wmm_delete_all_ralist(priv); |
569 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); | 569 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); |
570 | 570 | ||
571 | if (priv->adapter->if_ops.clean_pcie_ring) | ||
572 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); | ||
571 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 573 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
572 | } | 574 | } |
573 | 575 | ||
@@ -1206,13 +1208,15 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, | |||
1206 | ra_list_flags); | 1208 | ra_list_flags); |
1207 | break; | 1209 | break; |
1208 | case -1: | 1210 | case -1: |
1209 | adapter->data_sent = false; | 1211 | if (adapter->iface_type != MWIFIEX_PCIE) |
1212 | adapter->data_sent = false; | ||
1210 | dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); | 1213 | dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); |
1211 | adapter->dbg.num_tx_host_to_card_failure++; | 1214 | adapter->dbg.num_tx_host_to_card_failure++; |
1212 | mwifiex_write_data_complete(adapter, skb, 0, ret); | 1215 | mwifiex_write_data_complete(adapter, skb, 0, ret); |
1213 | break; | 1216 | break; |
1214 | case -EINPROGRESS: | 1217 | case -EINPROGRESS: |
1215 | adapter->data_sent = false; | 1218 | if (adapter->iface_type != MWIFIEX_PCIE) |
1219 | adapter->data_sent = false; | ||
1216 | default: | 1220 | default: |
1217 | break; | 1221 | break; |
1218 | } | 1222 | } |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 83564d36e801..224cf917744a 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -101,6 +101,18 @@ MODULE_PARM_DESC(ap_mode_default, | |||
101 | #define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES) | 101 | #define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES) |
102 | #define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues) | 102 | #define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues) |
103 | 103 | ||
104 | /* txpriorities are mapped with hw queues. | ||
105 | * Each hw queue has a txpriority. | ||
106 | */ | ||
107 | #define TOTAL_HW_TX_QUEUES 8 | ||
108 | |||
109 | /* Each HW queue can have one AMPDU stream. | ||
110 | * But, because one of the hw queue is reserved, | ||
111 | * maximum AMPDU queues that can be created are | ||
112 | * one short of total tx queues. | ||
113 | */ | ||
114 | #define MWL8K_NUM_AMPDU_STREAMS (TOTAL_HW_TX_QUEUES - 1) | ||
115 | |||
104 | struct rxd_ops { | 116 | struct rxd_ops { |
105 | int rxd_size; | 117 | int rxd_size; |
106 | void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); | 118 | void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); |
@@ -160,7 +172,6 @@ struct mwl8k_ampdu_stream { | |||
160 | u8 tid; | 172 | u8 tid; |
161 | u8 state; | 173 | u8 state; |
162 | u8 idx; | 174 | u8 idx; |
163 | u8 txq_idx; /* index of this stream in priv->txq */ | ||
164 | }; | 175 | }; |
165 | 176 | ||
166 | struct mwl8k_priv { | 177 | struct mwl8k_priv { |
@@ -202,6 +213,8 @@ struct mwl8k_priv { | |||
202 | int fw_mutex_depth; | 213 | int fw_mutex_depth; |
203 | struct completion *hostcmd_wait; | 214 | struct completion *hostcmd_wait; |
204 | 215 | ||
216 | atomic_t watchdog_event_pending; | ||
217 | |||
205 | /* lock held over TX and TX reap */ | 218 | /* lock held over TX and TX reap */ |
206 | spinlock_t tx_lock; | 219 | spinlock_t tx_lock; |
207 | 220 | ||
@@ -1516,6 +1529,9 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) | |||
1516 | return -EBUSY; | 1529 | return -EBUSY; |
1517 | } | 1530 | } |
1518 | 1531 | ||
1532 | if (atomic_read(&priv->watchdog_event_pending)) | ||
1533 | return 0; | ||
1534 | |||
1519 | /* | 1535 | /* |
1520 | * The TX queues are stopped at this point, so this test | 1536 | * The TX queues are stopped at this point, so this test |
1521 | * doesn't need to take ->tx_lock. | 1537 | * doesn't need to take ->tx_lock. |
@@ -1537,6 +1553,14 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) | |||
1537 | spin_unlock_bh(&priv->tx_lock); | 1553 | spin_unlock_bh(&priv->tx_lock); |
1538 | timeout = wait_for_completion_timeout(&tx_wait, | 1554 | timeout = wait_for_completion_timeout(&tx_wait, |
1539 | msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS)); | 1555 | msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS)); |
1556 | |||
1557 | if (atomic_read(&priv->watchdog_event_pending)) { | ||
1558 | spin_lock_bh(&priv->tx_lock); | ||
1559 | priv->tx_wait = NULL; | ||
1560 | spin_unlock_bh(&priv->tx_lock); | ||
1561 | return 0; | ||
1562 | } | ||
1563 | |||
1540 | spin_lock_bh(&priv->tx_lock); | 1564 | spin_lock_bh(&priv->tx_lock); |
1541 | 1565 | ||
1542 | if (timeout) { | 1566 | if (timeout) { |
@@ -1564,6 +1588,7 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) | |||
1564 | 1588 | ||
1565 | rc = -ETIMEDOUT; | 1589 | rc = -ETIMEDOUT; |
1566 | } | 1590 | } |
1591 | priv->tx_wait = NULL; | ||
1567 | spin_unlock_bh(&priv->tx_lock); | 1592 | spin_unlock_bh(&priv->tx_lock); |
1568 | 1593 | ||
1569 | return rc; | 1594 | return rc; |
@@ -1734,14 +1759,13 @@ mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) | |||
1734 | struct mwl8k_priv *priv = hw->priv; | 1759 | struct mwl8k_priv *priv = hw->priv; |
1735 | int i; | 1760 | int i; |
1736 | 1761 | ||
1737 | for (i = 0; i < priv->num_ampdu_queues; i++) { | 1762 | for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) { |
1738 | stream = &priv->ampdu[i]; | 1763 | stream = &priv->ampdu[i]; |
1739 | if (stream->state == AMPDU_NO_STREAM) { | 1764 | if (stream->state == AMPDU_NO_STREAM) { |
1740 | stream->sta = sta; | 1765 | stream->sta = sta; |
1741 | stream->state = AMPDU_STREAM_NEW; | 1766 | stream->state = AMPDU_STREAM_NEW; |
1742 | stream->tid = tid; | 1767 | stream->tid = tid; |
1743 | stream->idx = i; | 1768 | stream->idx = i; |
1744 | stream->txq_idx = MWL8K_TX_WMM_QUEUES + i; | ||
1745 | wiphy_debug(hw->wiphy, "Added a new stream for %pM %d", | 1769 | wiphy_debug(hw->wiphy, "Added a new stream for %pM %d", |
1746 | sta->addr, tid); | 1770 | sta->addr, tid); |
1747 | return stream; | 1771 | return stream; |
@@ -1782,7 +1806,7 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) | |||
1782 | struct mwl8k_priv *priv = hw->priv; | 1806 | struct mwl8k_priv *priv = hw->priv; |
1783 | int i; | 1807 | int i; |
1784 | 1808 | ||
1785 | for (i = 0 ; i < priv->num_ampdu_queues; i++) { | 1809 | for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) { |
1786 | struct mwl8k_ampdu_stream *stream; | 1810 | struct mwl8k_ampdu_stream *stream; |
1787 | stream = &priv->ampdu[i]; | 1811 | stream = &priv->ampdu[i]; |
1788 | if (stream->state == AMPDU_NO_STREAM) | 1812 | if (stream->state == AMPDU_NO_STREAM) |
@@ -1829,6 +1853,13 @@ static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) | |||
1829 | tx_stats->pkts++; | 1853 | tx_stats->pkts++; |
1830 | } | 1854 | } |
1831 | 1855 | ||
1856 | /* The hardware ampdu queues start from 5. | ||
1857 | * txpriorities for ampdu queues are | ||
1858 | * 5 6 7 0 1 2 3 4 ie., queue 5 is highest | ||
1859 | * and queue 3 is lowest (queue 4 is reserved) | ||
1860 | */ | ||
1861 | #define BA_QUEUE 5 | ||
1862 | |||
1832 | static void | 1863 | static void |
1833 | mwl8k_txq_xmit(struct ieee80211_hw *hw, | 1864 | mwl8k_txq_xmit(struct ieee80211_hw *hw, |
1834 | int index, | 1865 | int index, |
@@ -1928,8 +1959,13 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, | |||
1928 | stream = mwl8k_lookup_stream(hw, sta->addr, tid); | 1959 | stream = mwl8k_lookup_stream(hw, sta->addr, tid); |
1929 | if (stream != NULL) { | 1960 | if (stream != NULL) { |
1930 | if (stream->state == AMPDU_STREAM_ACTIVE) { | 1961 | if (stream->state == AMPDU_STREAM_ACTIVE) { |
1931 | txpriority = stream->txq_idx; | 1962 | WARN_ON(!(qos & MWL8K_QOS_ACK_POLICY_BLOCKACK)); |
1932 | index = stream->txq_idx; | 1963 | txpriority = (BA_QUEUE + stream->idx) % |
1964 | TOTAL_HW_TX_QUEUES; | ||
1965 | if (stream->idx <= 1) | ||
1966 | index = stream->idx + | ||
1967 | MWL8K_TX_WMM_QUEUES; | ||
1968 | |||
1933 | } else if (stream->state == AMPDU_STREAM_NEW) { | 1969 | } else if (stream->state == AMPDU_STREAM_NEW) { |
1934 | /* We get here if the driver sends us packets | 1970 | /* We get here if the driver sends us packets |
1935 | * after we've initiated a stream, but before | 1971 | * after we've initiated a stream, but before |
@@ -1971,6 +2007,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, | |||
1971 | } | 2007 | } |
1972 | } | 2008 | } |
1973 | spin_unlock(&priv->stream_lock); | 2009 | spin_unlock(&priv->stream_lock); |
2010 | } else { | ||
2011 | qos &= ~MWL8K_QOS_ACK_POLICY_MASK; | ||
2012 | qos |= MWL8K_QOS_ACK_POLICY_NORMAL; | ||
1974 | } | 2013 | } |
1975 | 2014 | ||
1976 | dma = pci_map_single(priv->pdev, skb->data, | 2015 | dma = pci_map_single(priv->pdev, skb->data, |
@@ -3578,7 +3617,11 @@ static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap) | |||
3578 | return rc; | 3617 | return rc; |
3579 | } | 3618 | } |
3580 | 3619 | ||
3581 | #define INVALID_BA 0xAA | 3620 | #define MWL8K_WMM_QUEUE_NUMBER 3 |
3621 | |||
3622 | static void mwl8k_destroy_ba(struct ieee80211_hw *hw, | ||
3623 | u8 idx); | ||
3624 | |||
3582 | static void mwl8k_watchdog_ba_events(struct work_struct *work) | 3625 | static void mwl8k_watchdog_ba_events(struct work_struct *work) |
3583 | { | 3626 | { |
3584 | int rc; | 3627 | int rc; |
@@ -3586,24 +3629,41 @@ static void mwl8k_watchdog_ba_events(struct work_struct *work) | |||
3586 | struct mwl8k_ampdu_stream *streams; | 3629 | struct mwl8k_ampdu_stream *streams; |
3587 | struct mwl8k_priv *priv = | 3630 | struct mwl8k_priv *priv = |
3588 | container_of(work, struct mwl8k_priv, watchdog_ba_handle); | 3631 | container_of(work, struct mwl8k_priv, watchdog_ba_handle); |
3632 | struct ieee80211_hw *hw = priv->hw; | ||
3633 | int i; | ||
3634 | u32 status = 0; | ||
3635 | |||
3636 | mwl8k_fw_lock(hw); | ||
3589 | 3637 | ||
3590 | rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap); | 3638 | rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap); |
3591 | if (rc) | 3639 | if (rc) |
3592 | return; | 3640 | goto done; |
3593 | 3641 | ||
3594 | if (bitmap == INVALID_BA) | 3642 | spin_lock(&priv->stream_lock); |
3595 | return; | ||
3596 | 3643 | ||
3597 | /* the bitmap is the hw queue number. Map it to the ampdu queue. */ | 3644 | /* the bitmap is the hw queue number. Map it to the ampdu queue. */ |
3598 | stream_index = bitmap - MWL8K_TX_WMM_QUEUES; | 3645 | for (i = 0; i < TOTAL_HW_TX_QUEUES; i++) { |
3599 | 3646 | if (bitmap & (1 << i)) { | |
3600 | BUG_ON(stream_index >= priv->num_ampdu_queues); | 3647 | stream_index = (i + MWL8K_WMM_QUEUE_NUMBER) % |
3601 | 3648 | TOTAL_HW_TX_QUEUES; | |
3602 | streams = &priv->ampdu[stream_index]; | 3649 | streams = &priv->ampdu[stream_index]; |
3603 | 3650 | if (streams->state == AMPDU_STREAM_ACTIVE) { | |
3604 | if (streams->state == AMPDU_STREAM_ACTIVE) | 3651 | ieee80211_stop_tx_ba_session(streams->sta, |
3605 | ieee80211_stop_tx_ba_session(streams->sta, streams->tid); | 3652 | streams->tid); |
3653 | spin_unlock(&priv->stream_lock); | ||
3654 | mwl8k_destroy_ba(hw, stream_index); | ||
3655 | spin_lock(&priv->stream_lock); | ||
3656 | } | ||
3657 | } | ||
3658 | } | ||
3606 | 3659 | ||
3660 | spin_unlock(&priv->stream_lock); | ||
3661 | done: | ||
3662 | atomic_dec(&priv->watchdog_event_pending); | ||
3663 | status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | ||
3664 | iowrite32((status | MWL8K_A2H_INT_BA_WATCHDOG), | ||
3665 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | ||
3666 | mwl8k_fw_unlock(hw); | ||
3607 | return; | 3667 | return; |
3608 | } | 3668 | } |
3609 | 3669 | ||
@@ -3763,7 +3823,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, | |||
3763 | } | 3823 | } |
3764 | 3824 | ||
3765 | static void mwl8k_destroy_ba(struct ieee80211_hw *hw, | 3825 | static void mwl8k_destroy_ba(struct ieee80211_hw *hw, |
3766 | struct mwl8k_ampdu_stream *stream) | 3826 | u8 idx) |
3767 | { | 3827 | { |
3768 | struct mwl8k_cmd_bastream *cmd; | 3828 | struct mwl8k_cmd_bastream *cmd; |
3769 | 3829 | ||
@@ -3775,10 +3835,10 @@ static void mwl8k_destroy_ba(struct ieee80211_hw *hw, | |||
3775 | cmd->header.length = cpu_to_le16(sizeof(*cmd)); | 3835 | cmd->header.length = cpu_to_le16(sizeof(*cmd)); |
3776 | cmd->action = cpu_to_le32(MWL8K_BA_DESTROY); | 3836 | cmd->action = cpu_to_le32(MWL8K_BA_DESTROY); |
3777 | 3837 | ||
3778 | cmd->destroy_params.ba_context = cpu_to_le32(stream->idx); | 3838 | cmd->destroy_params.ba_context = cpu_to_le32(idx); |
3779 | mwl8k_post_cmd(hw, &cmd->header); | 3839 | mwl8k_post_cmd(hw, &cmd->header); |
3780 | 3840 | ||
3781 | wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx); | 3841 | wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", idx); |
3782 | 3842 | ||
3783 | kfree(cmd); | 3843 | kfree(cmd); |
3784 | } | 3844 | } |
@@ -3875,7 +3935,30 @@ static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw, | |||
3875 | struct ieee80211_vif *vif, u8 *addr) | 3935 | struct ieee80211_vif *vif, u8 *addr) |
3876 | { | 3936 | { |
3877 | struct mwl8k_cmd_set_new_stn *cmd; | 3937 | struct mwl8k_cmd_set_new_stn *cmd; |
3878 | int rc; | 3938 | struct mwl8k_priv *priv = hw->priv; |
3939 | int rc, i; | ||
3940 | u8 idx; | ||
3941 | |||
3942 | spin_lock(&priv->stream_lock); | ||
3943 | /* Destroy any active ampdu streams for this sta */ | ||
3944 | for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) { | ||
3945 | struct mwl8k_ampdu_stream *s; | ||
3946 | s = &priv->ampdu[i]; | ||
3947 | if (s->state != AMPDU_NO_STREAM) { | ||
3948 | if (memcmp(s->sta->addr, addr, ETH_ALEN) == 0) { | ||
3949 | if (s->state == AMPDU_STREAM_ACTIVE) { | ||
3950 | idx = s->idx; | ||
3951 | spin_unlock(&priv->stream_lock); | ||
3952 | mwl8k_destroy_ba(hw, idx); | ||
3953 | spin_lock(&priv->stream_lock); | ||
3954 | } else if (s->state == AMPDU_STREAM_NEW) { | ||
3955 | mwl8k_remove_stream(hw, s); | ||
3956 | } | ||
3957 | } | ||
3958 | } | ||
3959 | } | ||
3960 | |||
3961 | spin_unlock(&priv->stream_lock); | ||
3879 | 3962 | ||
3880 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 3963 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
3881 | if (cmd == NULL) | 3964 | if (cmd == NULL) |
@@ -4303,6 +4386,10 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id) | |||
4303 | } | 4386 | } |
4304 | 4387 | ||
4305 | if (status & MWL8K_A2H_INT_BA_WATCHDOG) { | 4388 | if (status & MWL8K_A2H_INT_BA_WATCHDOG) { |
4389 | iowrite32(~MWL8K_A2H_INT_BA_WATCHDOG, | ||
4390 | priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); | ||
4391 | |||
4392 | atomic_inc(&priv->watchdog_event_pending); | ||
4306 | status &= ~MWL8K_A2H_INT_BA_WATCHDOG; | 4393 | status &= ~MWL8K_A2H_INT_BA_WATCHDOG; |
4307 | ieee80211_queue_work(hw, &priv->watchdog_ba_handle); | 4394 | ieee80211_queue_work(hw, &priv->watchdog_ba_handle); |
4308 | } | 4395 | } |
@@ -4446,6 +4533,8 @@ static int mwl8k_start(struct ieee80211_hw *hw) | |||
4446 | priv->irq = -1; | 4533 | priv->irq = -1; |
4447 | tasklet_disable(&priv->poll_tx_task); | 4534 | tasklet_disable(&priv->poll_tx_task); |
4448 | tasklet_disable(&priv->poll_rx_task); | 4535 | tasklet_disable(&priv->poll_rx_task); |
4536 | } else { | ||
4537 | ieee80211_wake_queues(hw); | ||
4449 | } | 4538 | } |
4450 | 4539 | ||
4451 | return rc; | 4540 | return rc; |
@@ -5094,7 +5183,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5094 | int i, rc = 0; | 5183 | int i, rc = 0; |
5095 | struct mwl8k_priv *priv = hw->priv; | 5184 | struct mwl8k_priv *priv = hw->priv; |
5096 | struct mwl8k_ampdu_stream *stream; | 5185 | struct mwl8k_ampdu_stream *stream; |
5097 | u8 *addr = sta->addr; | 5186 | u8 *addr = sta->addr, idx; |
5098 | struct mwl8k_sta *sta_info = MWL8K_STA(sta); | 5187 | struct mwl8k_sta *sta_info = MWL8K_STA(sta); |
5099 | 5188 | ||
5100 | if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) | 5189 | if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) |
@@ -5172,11 +5261,14 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5172 | } | 5261 | } |
5173 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); | 5262 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); |
5174 | break; | 5263 | break; |
5175 | case IEEE80211_AMPDU_TX_STOP: | 5264 | case IEEE80211_AMPDU_TX_STOP_CONT: |
5265 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
5266 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
5176 | if (stream) { | 5267 | if (stream) { |
5177 | if (stream->state == AMPDU_STREAM_ACTIVE) { | 5268 | if (stream->state == AMPDU_STREAM_ACTIVE) { |
5269 | idx = stream->idx; | ||
5178 | spin_unlock(&priv->stream_lock); | 5270 | spin_unlock(&priv->stream_lock); |
5179 | mwl8k_destroy_ba(hw, stream); | 5271 | mwl8k_destroy_ba(hw, idx); |
5180 | spin_lock(&priv->stream_lock); | 5272 | spin_lock(&priv->stream_lock); |
5181 | } | 5273 | } |
5182 | mwl8k_remove_stream(hw, stream); | 5274 | mwl8k_remove_stream(hw, stream); |
@@ -5192,8 +5284,9 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5192 | if (!rc) | 5284 | if (!rc) |
5193 | stream->state = AMPDU_STREAM_ACTIVE; | 5285 | stream->state = AMPDU_STREAM_ACTIVE; |
5194 | else { | 5286 | else { |
5287 | idx = stream->idx; | ||
5195 | spin_unlock(&priv->stream_lock); | 5288 | spin_unlock(&priv->stream_lock); |
5196 | mwl8k_destroy_ba(hw, stream); | 5289 | mwl8k_destroy_ba(hw, idx); |
5197 | spin_lock(&priv->stream_lock); | 5290 | spin_lock(&priv->stream_lock); |
5198 | wiphy_debug(hw->wiphy, | 5291 | wiphy_debug(hw->wiphy, |
5199 | "Failed adding stream for sta %pM tid %d\n", | 5292 | "Failed adding stream for sta %pM tid %d\n", |
@@ -5256,7 +5349,7 @@ enum { | |||
5256 | MWL8366, | 5349 | MWL8366, |
5257 | }; | 5350 | }; |
5258 | 5351 | ||
5259 | #define MWL8K_8366_AP_FW_API 2 | 5352 | #define MWL8K_8366_AP_FW_API 3 |
5260 | #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" | 5353 | #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" |
5261 | #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) | 5354 | #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) |
5262 | 5355 | ||
@@ -5464,6 +5557,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) | |||
5464 | if (priv->rxd_ops == NULL) { | 5557 | if (priv->rxd_ops == NULL) { |
5465 | wiphy_err(hw->wiphy, | 5558 | wiphy_err(hw->wiphy, |
5466 | "Driver does not have AP firmware image support for this hardware\n"); | 5559 | "Driver does not have AP firmware image support for this hardware\n"); |
5560 | rc = -ENOENT; | ||
5467 | goto err_stop_firmware; | 5561 | goto err_stop_firmware; |
5468 | } | 5562 | } |
5469 | } else { | 5563 | } else { |
@@ -5473,6 +5567,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) | |||
5473 | priv->sniffer_enabled = false; | 5567 | priv->sniffer_enabled = false; |
5474 | priv->wmm_enabled = false; | 5568 | priv->wmm_enabled = false; |
5475 | priv->pending_tx_pkts = 0; | 5569 | priv->pending_tx_pkts = 0; |
5570 | atomic_set(&priv->watchdog_event_pending, 0); | ||
5476 | 5571 | ||
5477 | rc = mwl8k_rxq_init(hw, 0); | 5572 | rc = mwl8k_rxq_init(hw, 0); |
5478 | if (rc) | 5573 | if (rc) |
@@ -5809,6 +5904,7 @@ static int mwl8k_probe(struct pci_dev *pdev, | |||
5809 | priv->sram = pci_iomap(pdev, 0, 0x10000); | 5904 | priv->sram = pci_iomap(pdev, 0, 0x10000); |
5810 | if (priv->sram == NULL) { | 5905 | if (priv->sram == NULL) { |
5811 | wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); | 5906 | wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); |
5907 | rc = -EIO; | ||
5812 | goto err_iounmap; | 5908 | goto err_iounmap; |
5813 | } | 5909 | } |
5814 | 5910 | ||
@@ -5821,6 +5917,7 @@ static int mwl8k_probe(struct pci_dev *pdev, | |||
5821 | priv->regs = pci_iomap(pdev, 2, 0x10000); | 5917 | priv->regs = pci_iomap(pdev, 2, 0x10000); |
5822 | if (priv->regs == NULL) { | 5918 | if (priv->regs == NULL) { |
5823 | wiphy_err(hw->wiphy, "Cannot map device registers\n"); | 5919 | wiphy_err(hw->wiphy, "Cannot map device registers\n"); |
5920 | rc = -EIO; | ||
5824 | goto err_iounmap; | 5921 | goto err_iounmap; |
5825 | } | 5922 | } |
5826 | } | 5923 | } |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 933e5d941937..57e3af8ebb4b 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -559,6 +559,7 @@ static int p54p_probe(struct pci_dev *pdev, | |||
559 | mem_len = pci_resource_len(pdev, 0); | 559 | mem_len = pci_resource_len(pdev, 0); |
560 | if (mem_len < sizeof(struct p54p_csr)) { | 560 | if (mem_len < sizeof(struct p54p_csr)) { |
561 | dev_err(&pdev->dev, "Too short PCI resources\n"); | 561 | dev_err(&pdev->dev, "Too short PCI resources\n"); |
562 | err = -ENODEV; | ||
562 | goto err_disable_dev; | 563 | goto err_disable_dev; |
563 | } | 564 | } |
564 | 565 | ||
@@ -568,8 +569,10 @@ static int p54p_probe(struct pci_dev *pdev, | |||
568 | goto err_disable_dev; | 569 | goto err_disable_dev; |
569 | } | 570 | } |
570 | 571 | ||
571 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) || | 572 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
572 | pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { | 573 | if (!err) |
574 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
575 | if (err) { | ||
573 | dev_err(&pdev->dev, "No suitable DMA available\n"); | 576 | dev_err(&pdev->dev, "No suitable DMA available\n"); |
574 | goto err_free_reg; | 577 | goto err_free_reg; |
575 | } | 578 | } |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 4e44b1af119a..1c22b81e6ef3 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -1503,6 +1503,7 @@ static int prism54_get_auth(struct net_device *ndev, | |||
1503 | case DOT11_AUTH_BOTH: | 1503 | case DOT11_AUTH_BOTH: |
1504 | case DOT11_AUTH_SK: | 1504 | case DOT11_AUTH_SK: |
1505 | param->value = IW_AUTH_ALG_SHARED_KEY; | 1505 | param->value = IW_AUTH_ALG_SHARED_KEY; |
1506 | break; | ||
1506 | case DOT11_AUTH_NONE: | 1507 | case DOT11_AUTH_NONE: |
1507 | default: | 1508 | default: |
1508 | param->value = 0; | 1509 | param->value = 0; |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 598ca1cafb95..e7cf37f550d1 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -1107,12 +1107,15 @@ static int ray_get_essid(struct net_device *dev, struct iw_request_info *info, | |||
1107 | union iwreq_data *wrqu, char *extra) | 1107 | union iwreq_data *wrqu, char *extra) |
1108 | { | 1108 | { |
1109 | ray_dev_t *local = netdev_priv(dev); | 1109 | ray_dev_t *local = netdev_priv(dev); |
1110 | UCHAR tmp[IW_ESSID_MAX_SIZE + 1]; | ||
1110 | 1111 | ||
1111 | /* Get the essid that was set */ | 1112 | /* Get the essid that was set */ |
1112 | memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); | 1113 | memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); |
1114 | memcpy(tmp, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); | ||
1115 | tmp[IW_ESSID_MAX_SIZE] = '\0'; | ||
1113 | 1116 | ||
1114 | /* Push it out ! */ | 1117 | /* Push it out ! */ |
1115 | wrqu->essid.length = strlen(extra); | 1118 | wrqu->essid.length = strlen(tmp); |
1116 | wrqu->essid.flags = 1; /* active */ | 1119 | wrqu->essid.flags = 1; /* active */ |
1117 | 1120 | ||
1118 | return 0; | 1121 | return 0; |
@@ -1842,6 +1845,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) | |||
1842 | UCHAR tmp; | 1845 | UCHAR tmp; |
1843 | UCHAR cmd; | 1846 | UCHAR cmd; |
1844 | UCHAR status; | 1847 | UCHAR status; |
1848 | UCHAR memtmp[ESSID_SIZE + 1]; | ||
1849 | |||
1845 | 1850 | ||
1846 | if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */ | 1851 | if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */ |
1847 | return IRQ_NONE; | 1852 | return IRQ_NONE; |
@@ -1901,17 +1906,21 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) | |||
1901 | break; | 1906 | break; |
1902 | case CCS_START_NETWORK: | 1907 | case CCS_START_NETWORK: |
1903 | case CCS_JOIN_NETWORK: | 1908 | case CCS_JOIN_NETWORK: |
1909 | memcpy(memtmp, local->sparm.b4.a_current_ess_id, | ||
1910 | ESSID_SIZE); | ||
1911 | memtmp[ESSID_SIZE] = '\0'; | ||
1912 | |||
1904 | if (status == CCS_COMMAND_COMPLETE) { | 1913 | if (status == CCS_COMMAND_COMPLETE) { |
1905 | if (readb | 1914 | if (readb |
1906 | (&pccs->var.start_network.net_initiated) == | 1915 | (&pccs->var.start_network.net_initiated) == |
1907 | 1) { | 1916 | 1) { |
1908 | dev_dbg(&link->dev, | 1917 | dev_dbg(&link->dev, |
1909 | "ray_cs interrupt network \"%s\" started\n", | 1918 | "ray_cs interrupt network \"%s\" started\n", |
1910 | local->sparm.b4.a_current_ess_id); | 1919 | memtmp); |
1911 | } else { | 1920 | } else { |
1912 | dev_dbg(&link->dev, | 1921 | dev_dbg(&link->dev, |
1913 | "ray_cs interrupt network \"%s\" joined\n", | 1922 | "ray_cs interrupt network \"%s\" joined\n", |
1914 | local->sparm.b4.a_current_ess_id); | 1923 | memtmp); |
1915 | } | 1924 | } |
1916 | memcpy_fromio(&local->bss_id, | 1925 | memcpy_fromio(&local->bss_id, |
1917 | pccs->var.start_network.bssid, | 1926 | pccs->var.start_network.bssid, |
@@ -1939,12 +1948,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) | |||
1939 | if (status == CCS_START_NETWORK) { | 1948 | if (status == CCS_START_NETWORK) { |
1940 | dev_dbg(&link->dev, | 1949 | dev_dbg(&link->dev, |
1941 | "ray_cs interrupt network \"%s\" start failed\n", | 1950 | "ray_cs interrupt network \"%s\" start failed\n", |
1942 | local->sparm.b4.a_current_ess_id); | 1951 | memtmp); |
1943 | local->timer.function = start_net; | 1952 | local->timer.function = start_net; |
1944 | } else { | 1953 | } else { |
1945 | dev_dbg(&link->dev, | 1954 | dev_dbg(&link->dev, |
1946 | "ray_cs interrupt network \"%s\" join failed\n", | 1955 | "ray_cs interrupt network \"%s\" join failed\n", |
1947 | local->sparm.b4.a_current_ess_id); | 1956 | memtmp); |
1948 | local->timer.function = join_net; | 1957 | local->timer.function = join_net; |
1949 | } | 1958 | } |
1950 | add_timer(&local->timer); | 1959 | add_timer(&local->timer); |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 197b4466a5d2..a5c694f23d33 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1296,8 +1296,7 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, | |||
1296 | !(filter_flags & FIF_CONTROL)); | 1296 | !(filter_flags & FIF_CONTROL)); |
1297 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PSPOLL, | 1297 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PSPOLL, |
1298 | !(filter_flags & FIF_PSPOLL)); | 1298 | !(filter_flags & FIF_PSPOLL)); |
1299 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BA, | 1299 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BA, 0); |
1300 | !(filter_flags & FIF_CONTROL)); | ||
1301 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BAR, | 1300 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BAR, |
1302 | !(filter_flags & FIF_CONTROL)); | 1301 | !(filter_flags & FIF_CONTROL)); |
1303 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CNTL, | 1302 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CNTL, |
@@ -3866,6 +3865,400 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
3866 | return rfcsr24; | 3865 | return rfcsr24; |
3867 | } | 3866 | } |
3868 | 3867 | ||
3868 | static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) | ||
3869 | { | ||
3870 | rt2800_rfcsr_write(rt2x00dev, 0, 0x50); | ||
3871 | rt2800_rfcsr_write(rt2x00dev, 1, 0x01); | ||
3872 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); | ||
3873 | rt2800_rfcsr_write(rt2x00dev, 3, 0x75); | ||
3874 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | ||
3875 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); | ||
3876 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); | ||
3877 | rt2800_rfcsr_write(rt2x00dev, 7, 0x50); | ||
3878 | rt2800_rfcsr_write(rt2x00dev, 8, 0x39); | ||
3879 | rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); | ||
3880 | rt2800_rfcsr_write(rt2x00dev, 10, 0x60); | ||
3881 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | ||
3882 | rt2800_rfcsr_write(rt2x00dev, 12, 0x75); | ||
3883 | rt2800_rfcsr_write(rt2x00dev, 13, 0x75); | ||
3884 | rt2800_rfcsr_write(rt2x00dev, 14, 0x90); | ||
3885 | rt2800_rfcsr_write(rt2x00dev, 15, 0x58); | ||
3886 | rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); | ||
3887 | rt2800_rfcsr_write(rt2x00dev, 17, 0x92); | ||
3888 | rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); | ||
3889 | rt2800_rfcsr_write(rt2x00dev, 19, 0x02); | ||
3890 | rt2800_rfcsr_write(rt2x00dev, 20, 0xba); | ||
3891 | rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); | ||
3892 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
3893 | rt2800_rfcsr_write(rt2x00dev, 23, 0x31); | ||
3894 | rt2800_rfcsr_write(rt2x00dev, 24, 0x08); | ||
3895 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | ||
3896 | rt2800_rfcsr_write(rt2x00dev, 26, 0x25); | ||
3897 | rt2800_rfcsr_write(rt2x00dev, 27, 0x23); | ||
3898 | rt2800_rfcsr_write(rt2x00dev, 28, 0x13); | ||
3899 | rt2800_rfcsr_write(rt2x00dev, 29, 0x83); | ||
3900 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | ||
3901 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); | ||
3902 | } | ||
3903 | |||
3904 | static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) | ||
3905 | { | ||
3906 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | ||
3907 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); | ||
3908 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); | ||
3909 | rt2800_rfcsr_write(rt2x00dev, 7, 0x60); | ||
3910 | rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); | ||
3911 | rt2800_rfcsr_write(rt2x00dev, 10, 0x41); | ||
3912 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | ||
3913 | rt2800_rfcsr_write(rt2x00dev, 12, 0x7b); | ||
3914 | rt2800_rfcsr_write(rt2x00dev, 14, 0x90); | ||
3915 | rt2800_rfcsr_write(rt2x00dev, 15, 0x58); | ||
3916 | rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); | ||
3917 | rt2800_rfcsr_write(rt2x00dev, 17, 0x92); | ||
3918 | rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); | ||
3919 | rt2800_rfcsr_write(rt2x00dev, 19, 0x02); | ||
3920 | rt2800_rfcsr_write(rt2x00dev, 20, 0xba); | ||
3921 | rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); | ||
3922 | rt2800_rfcsr_write(rt2x00dev, 24, 0x16); | ||
3923 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | ||
3924 | rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); | ||
3925 | } | ||
3926 | |||
3927 | static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) | ||
3928 | { | ||
3929 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | ||
3930 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
3931 | rt2800_rfcsr_write(rt2x00dev, 3, 0x08); | ||
3932 | rt2800_rfcsr_write(rt2x00dev, 4, 0x00); | ||
3933 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); | ||
3934 | rt2800_rfcsr_write(rt2x00dev, 8, 0xf3); | ||
3935 | rt2800_rfcsr_write(rt2x00dev, 9, 0x02); | ||
3936 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
3937 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
3938 | rt2800_rfcsr_write(rt2x00dev, 12, 0x46); | ||
3939 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
3940 | rt2800_rfcsr_write(rt2x00dev, 18, 0x02); | ||
3941 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
3942 | rt2800_rfcsr_write(rt2x00dev, 25, 0x83); | ||
3943 | rt2800_rfcsr_write(rt2x00dev, 26, 0x82); | ||
3944 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
3945 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
3946 | rt2800_rfcsr_write(rt2x00dev, 30, 0x10); | ||
3947 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
3948 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
3949 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
3950 | rt2800_rfcsr_write(rt2x00dev, 34, 0x05); | ||
3951 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
3952 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
3953 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | ||
3954 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
3955 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); | ||
3956 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
3957 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); | ||
3958 | rt2800_rfcsr_write(rt2x00dev, 43, 0x7b); | ||
3959 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
3960 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
3961 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
3962 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); | ||
3963 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
3964 | rt2800_rfcsr_write(rt2x00dev, 49, 0x98); | ||
3965 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); | ||
3966 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); | ||
3967 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); | ||
3968 | rt2800_rfcsr_write(rt2x00dev, 55, 0x43); | ||
3969 | rt2800_rfcsr_write(rt2x00dev, 56, 0x02); | ||
3970 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); | ||
3971 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); | ||
3972 | rt2800_rfcsr_write(rt2x00dev, 59, 0x09); | ||
3973 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
3974 | rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); | ||
3975 | } | ||
3976 | |||
3977 | static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) | ||
3978 | { | ||
3979 | rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); | ||
3980 | rt2800_rfcsr_write(rt2x00dev, 1, 0x23); | ||
3981 | rt2800_rfcsr_write(rt2x00dev, 2, 0x50); | ||
3982 | rt2800_rfcsr_write(rt2x00dev, 3, 0x18); | ||
3983 | rt2800_rfcsr_write(rt2x00dev, 4, 0x00); | ||
3984 | rt2800_rfcsr_write(rt2x00dev, 5, 0x00); | ||
3985 | rt2800_rfcsr_write(rt2x00dev, 6, 0x33); | ||
3986 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | ||
3987 | rt2800_rfcsr_write(rt2x00dev, 8, 0xf1); | ||
3988 | rt2800_rfcsr_write(rt2x00dev, 9, 0x02); | ||
3989 | rt2800_rfcsr_write(rt2x00dev, 10, 0xd2); | ||
3990 | rt2800_rfcsr_write(rt2x00dev, 11, 0x42); | ||
3991 | rt2800_rfcsr_write(rt2x00dev, 12, 0x1c); | ||
3992 | rt2800_rfcsr_write(rt2x00dev, 13, 0x00); | ||
3993 | rt2800_rfcsr_write(rt2x00dev, 14, 0x5a); | ||
3994 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | ||
3995 | rt2800_rfcsr_write(rt2x00dev, 16, 0x01); | ||
3996 | rt2800_rfcsr_write(rt2x00dev, 18, 0x45); | ||
3997 | rt2800_rfcsr_write(rt2x00dev, 19, 0x02); | ||
3998 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | ||
3999 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); | ||
4000 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
4001 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); | ||
4002 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); | ||
4003 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | ||
4004 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); | ||
4005 | rt2800_rfcsr_write(rt2x00dev, 27, 0x03); | ||
4006 | rt2800_rfcsr_write(rt2x00dev, 28, 0x03); | ||
4007 | rt2800_rfcsr_write(rt2x00dev, 29, 0x00); | ||
4008 | rt2800_rfcsr_write(rt2x00dev, 30, 0x10); | ||
4009 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
4010 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
4011 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
4012 | rt2800_rfcsr_write(rt2x00dev, 34, 0x01); | ||
4013 | rt2800_rfcsr_write(rt2x00dev, 35, 0x03); | ||
4014 | rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); | ||
4015 | rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); | ||
4016 | rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); | ||
4017 | rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); | ||
4018 | rt2800_rfcsr_write(rt2x00dev, 40, 0x33); | ||
4019 | rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); | ||
4020 | rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); | ||
4021 | rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); | ||
4022 | rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); | ||
4023 | rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); | ||
4024 | rt2800_rfcsr_write(rt2x00dev, 46, 0xdd); | ||
4025 | rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); | ||
4026 | rt2800_rfcsr_write(rt2x00dev, 48, 0x14); | ||
4027 | rt2800_rfcsr_write(rt2x00dev, 49, 0x00); | ||
4028 | rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); | ||
4029 | rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); | ||
4030 | rt2800_rfcsr_write(rt2x00dev, 52, 0x00); | ||
4031 | rt2800_rfcsr_write(rt2x00dev, 53, 0x52); | ||
4032 | rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); | ||
4033 | rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); | ||
4034 | rt2800_rfcsr_write(rt2x00dev, 56, 0x00); | ||
4035 | rt2800_rfcsr_write(rt2x00dev, 57, 0x52); | ||
4036 | rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); | ||
4037 | rt2800_rfcsr_write(rt2x00dev, 59, 0x00); | ||
4038 | rt2800_rfcsr_write(rt2x00dev, 60, 0x00); | ||
4039 | rt2800_rfcsr_write(rt2x00dev, 61, 0x00); | ||
4040 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | ||
4041 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | ||
4042 | } | ||
4043 | |||
4044 | static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev) | ||
4045 | { | ||
4046 | rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); | ||
4047 | rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); | ||
4048 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); | ||
4049 | rt2800_rfcsr_write(rt2x00dev, 3, 0x62); | ||
4050 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | ||
4051 | rt2800_rfcsr_write(rt2x00dev, 5, 0x8b); | ||
4052 | rt2800_rfcsr_write(rt2x00dev, 6, 0x42); | ||
4053 | rt2800_rfcsr_write(rt2x00dev, 7, 0x34); | ||
4054 | rt2800_rfcsr_write(rt2x00dev, 8, 0x00); | ||
4055 | rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); | ||
4056 | rt2800_rfcsr_write(rt2x00dev, 10, 0x61); | ||
4057 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | ||
4058 | rt2800_rfcsr_write(rt2x00dev, 12, 0x3b); | ||
4059 | rt2800_rfcsr_write(rt2x00dev, 13, 0xe0); | ||
4060 | rt2800_rfcsr_write(rt2x00dev, 14, 0x90); | ||
4061 | rt2800_rfcsr_write(rt2x00dev, 15, 0x53); | ||
4062 | rt2800_rfcsr_write(rt2x00dev, 16, 0xe0); | ||
4063 | rt2800_rfcsr_write(rt2x00dev, 17, 0x94); | ||
4064 | rt2800_rfcsr_write(rt2x00dev, 18, 0x5c); | ||
4065 | rt2800_rfcsr_write(rt2x00dev, 19, 0x4a); | ||
4066 | rt2800_rfcsr_write(rt2x00dev, 20, 0xb2); | ||
4067 | rt2800_rfcsr_write(rt2x00dev, 21, 0xf6); | ||
4068 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
4069 | rt2800_rfcsr_write(rt2x00dev, 23, 0x14); | ||
4070 | rt2800_rfcsr_write(rt2x00dev, 24, 0x08); | ||
4071 | rt2800_rfcsr_write(rt2x00dev, 25, 0x3d); | ||
4072 | rt2800_rfcsr_write(rt2x00dev, 26, 0x85); | ||
4073 | rt2800_rfcsr_write(rt2x00dev, 27, 0x00); | ||
4074 | rt2800_rfcsr_write(rt2x00dev, 28, 0x41); | ||
4075 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); | ||
4076 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); | ||
4077 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); | ||
4078 | } | ||
4079 | |||
4080 | static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev) | ||
4081 | { | ||
4082 | rt2800_rfcsr_write(rt2x00dev, 0, 0x70); | ||
4083 | rt2800_rfcsr_write(rt2x00dev, 1, 0x81); | ||
4084 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); | ||
4085 | rt2800_rfcsr_write(rt2x00dev, 3, 0x02); | ||
4086 | rt2800_rfcsr_write(rt2x00dev, 4, 0x4c); | ||
4087 | rt2800_rfcsr_write(rt2x00dev, 5, 0x05); | ||
4088 | rt2800_rfcsr_write(rt2x00dev, 6, 0x4a); | ||
4089 | rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); | ||
4090 | rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); | ||
4091 | rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); | ||
4092 | rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); | ||
4093 | rt2800_rfcsr_write(rt2x00dev, 12, 0x70); | ||
4094 | rt2800_rfcsr_write(rt2x00dev, 13, 0x65); | ||
4095 | rt2800_rfcsr_write(rt2x00dev, 14, 0xa0); | ||
4096 | rt2800_rfcsr_write(rt2x00dev, 15, 0x53); | ||
4097 | rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); | ||
4098 | rt2800_rfcsr_write(rt2x00dev, 17, 0x23); | ||
4099 | rt2800_rfcsr_write(rt2x00dev, 18, 0xac); | ||
4100 | rt2800_rfcsr_write(rt2x00dev, 19, 0x93); | ||
4101 | rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); | ||
4102 | rt2800_rfcsr_write(rt2x00dev, 21, 0xd0); | ||
4103 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
4104 | rt2800_rfcsr_write(rt2x00dev, 23, 0x3c); | ||
4105 | rt2800_rfcsr_write(rt2x00dev, 24, 0x16); | ||
4106 | rt2800_rfcsr_write(rt2x00dev, 25, 0x15); | ||
4107 | rt2800_rfcsr_write(rt2x00dev, 26, 0x85); | ||
4108 | rt2800_rfcsr_write(rt2x00dev, 27, 0x00); | ||
4109 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
4110 | rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); | ||
4111 | rt2800_rfcsr_write(rt2x00dev, 30, 0x09); | ||
4112 | rt2800_rfcsr_write(rt2x00dev, 31, 0x10); | ||
4113 | } | ||
4114 | |||
4115 | static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) | ||
4116 | { | ||
4117 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | ||
4118 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
4119 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | ||
4120 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | ||
4121 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4122 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); | ||
4123 | else | ||
4124 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); | ||
4125 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | ||
4126 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
4127 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
4128 | rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); | ||
4129 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
4130 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | ||
4131 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | ||
4132 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | ||
4133 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | ||
4134 | rt2800_rfcsr_write(rt2x00dev, 19, 0x00); | ||
4135 | |||
4136 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | ||
4137 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); | ||
4138 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
4139 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); | ||
4140 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); | ||
4141 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4142 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | ||
4143 | else | ||
4144 | rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); | ||
4145 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); | ||
4146 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
4147 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
4148 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
4149 | |||
4150 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | ||
4151 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
4152 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
4153 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
4154 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | ||
4155 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
4156 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
4157 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | ||
4158 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | ||
4159 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
4160 | |||
4161 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4162 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); | ||
4163 | else | ||
4164 | rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); | ||
4165 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
4166 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); | ||
4167 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); | ||
4168 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
4169 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
4170 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4171 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
4172 | else | ||
4173 | rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); | ||
4174 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); | ||
4175 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
4176 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); | ||
4177 | |||
4178 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); | ||
4179 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4180 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); | ||
4181 | else | ||
4182 | rt2800_rfcsr_write(rt2x00dev, 53, 0x84); | ||
4183 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); | ||
4184 | rt2800_rfcsr_write(rt2x00dev, 55, 0x44); | ||
4185 | rt2800_rfcsr_write(rt2x00dev, 56, 0x22); | ||
4186 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); | ||
4187 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); | ||
4188 | rt2800_rfcsr_write(rt2x00dev, 59, 0x63); | ||
4189 | |||
4190 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
4191 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4192 | rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); | ||
4193 | else | ||
4194 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); | ||
4195 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | ||
4196 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | ||
4197 | } | ||
4198 | |||
4199 | static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) | ||
4200 | { | ||
4201 | rt2800_rfcsr_write(rt2x00dev, 1, 0x17); | ||
4202 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
4203 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | ||
4204 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | ||
4205 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); | ||
4206 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | ||
4207 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
4208 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
4209 | rt2800_rfcsr_write(rt2x00dev, 12, 0x46); | ||
4210 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
4211 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | ||
4212 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | ||
4213 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | ||
4214 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | ||
4215 | rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); | ||
4216 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | ||
4217 | rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); | ||
4218 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
4219 | rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); | ||
4220 | rt2800_rfcsr_write(rt2x00dev, 24, 0x44); | ||
4221 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | ||
4222 | rt2800_rfcsr_write(rt2x00dev, 26, 0x82); | ||
4223 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
4224 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
4225 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
4226 | rt2800_rfcsr_write(rt2x00dev, 30, 0x10); | ||
4227 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
4228 | rt2800_rfcsr_write(rt2x00dev, 32, 0x20); | ||
4229 | rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); | ||
4230 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | ||
4231 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
4232 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
4233 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | ||
4234 | rt2800_rfcsr_write(rt2x00dev, 38, 0x89); | ||
4235 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
4236 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); | ||
4237 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
4238 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); | ||
4239 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); | ||
4240 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
4241 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
4242 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
4243 | rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); | ||
4244 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
4245 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); | ||
4246 | rt2800_rfcsr_write(rt2x00dev, 50, 0x94); | ||
4247 | rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); | ||
4248 | rt2800_rfcsr_write(rt2x00dev, 52, 0x48); | ||
4249 | rt2800_rfcsr_write(rt2x00dev, 53, 0x44); | ||
4250 | rt2800_rfcsr_write(rt2x00dev, 54, 0x38); | ||
4251 | rt2800_rfcsr_write(rt2x00dev, 55, 0x43); | ||
4252 | rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); | ||
4253 | rt2800_rfcsr_write(rt2x00dev, 57, 0x00); | ||
4254 | rt2800_rfcsr_write(rt2x00dev, 58, 0x39); | ||
4255 | rt2800_rfcsr_write(rt2x00dev, 59, 0x07); | ||
4256 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
4257 | rt2800_rfcsr_write(rt2x00dev, 61, 0x91); | ||
4258 | rt2800_rfcsr_write(rt2x00dev, 62, 0x39); | ||
4259 | rt2800_rfcsr_write(rt2x00dev, 63, 0x07); | ||
4260 | } | ||
4261 | |||
3869 | static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | 4262 | static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) |
3870 | { | 4263 | { |
3871 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; | 4264 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; |
@@ -3889,6 +4282,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
3889 | /* | 4282 | /* |
3890 | * Init RF calibration. | 4283 | * Init RF calibration. |
3891 | */ | 4284 | */ |
4285 | |||
3892 | if (rt2x00_rt(rt2x00dev, RT3290) || | 4286 | if (rt2x00_rt(rt2x00dev, RT3290) || |
3893 | rt2x00_rt(rt2x00dev, RT5390) || | 4287 | rt2x00_rt(rt2x00dev, RT5390) || |
3894 | rt2x00_rt(rt2x00dev, RT5392)) { | 4288 | rt2x00_rt(rt2x00dev, RT5392)) { |
@@ -3907,379 +4301,35 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
3907 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 4301 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); |
3908 | } | 4302 | } |
3909 | 4303 | ||
3910 | if (rt2x00_rt(rt2x00dev, RT3070) || | 4304 | if (rt2800_is_305x_soc(rt2x00dev)) { |
3911 | rt2x00_rt(rt2x00dev, RT3071) || | 4305 | rt2800_init_rfcsr_305x_soc(rt2x00dev); |
3912 | rt2x00_rt(rt2x00dev, RT3090)) { | ||
3913 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | ||
3914 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); | ||
3915 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); | ||
3916 | rt2800_rfcsr_write(rt2x00dev, 7, 0x60); | ||
3917 | rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); | ||
3918 | rt2800_rfcsr_write(rt2x00dev, 10, 0x41); | ||
3919 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | ||
3920 | rt2800_rfcsr_write(rt2x00dev, 12, 0x7b); | ||
3921 | rt2800_rfcsr_write(rt2x00dev, 14, 0x90); | ||
3922 | rt2800_rfcsr_write(rt2x00dev, 15, 0x58); | ||
3923 | rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); | ||
3924 | rt2800_rfcsr_write(rt2x00dev, 17, 0x92); | ||
3925 | rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); | ||
3926 | rt2800_rfcsr_write(rt2x00dev, 19, 0x02); | ||
3927 | rt2800_rfcsr_write(rt2x00dev, 20, 0xba); | ||
3928 | rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); | ||
3929 | rt2800_rfcsr_write(rt2x00dev, 24, 0x16); | ||
3930 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | ||
3931 | rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); | ||
3932 | } else if (rt2x00_rt(rt2x00dev, RT3290)) { | ||
3933 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | ||
3934 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
3935 | rt2800_rfcsr_write(rt2x00dev, 3, 0x08); | ||
3936 | rt2800_rfcsr_write(rt2x00dev, 4, 0x00); | ||
3937 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); | ||
3938 | rt2800_rfcsr_write(rt2x00dev, 8, 0xf3); | ||
3939 | rt2800_rfcsr_write(rt2x00dev, 9, 0x02); | ||
3940 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
3941 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
3942 | rt2800_rfcsr_write(rt2x00dev, 12, 0x46); | ||
3943 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
3944 | rt2800_rfcsr_write(rt2x00dev, 18, 0x02); | ||
3945 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
3946 | rt2800_rfcsr_write(rt2x00dev, 25, 0x83); | ||
3947 | rt2800_rfcsr_write(rt2x00dev, 26, 0x82); | ||
3948 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
3949 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
3950 | rt2800_rfcsr_write(rt2x00dev, 30, 0x10); | ||
3951 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
3952 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
3953 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
3954 | rt2800_rfcsr_write(rt2x00dev, 34, 0x05); | ||
3955 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
3956 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
3957 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | ||
3958 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
3959 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); | ||
3960 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
3961 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); | ||
3962 | rt2800_rfcsr_write(rt2x00dev, 43, 0x7b); | ||
3963 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
3964 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
3965 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
3966 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); | ||
3967 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
3968 | rt2800_rfcsr_write(rt2x00dev, 49, 0x98); | ||
3969 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); | ||
3970 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); | ||
3971 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); | ||
3972 | rt2800_rfcsr_write(rt2x00dev, 55, 0x43); | ||
3973 | rt2800_rfcsr_write(rt2x00dev, 56, 0x02); | ||
3974 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); | ||
3975 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); | ||
3976 | rt2800_rfcsr_write(rt2x00dev, 59, 0x09); | ||
3977 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
3978 | rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); | ||
3979 | } else if (rt2x00_rt(rt2x00dev, RT3390)) { | ||
3980 | rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); | ||
3981 | rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); | ||
3982 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); | ||
3983 | rt2800_rfcsr_write(rt2x00dev, 3, 0x62); | ||
3984 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | ||
3985 | rt2800_rfcsr_write(rt2x00dev, 5, 0x8b); | ||
3986 | rt2800_rfcsr_write(rt2x00dev, 6, 0x42); | ||
3987 | rt2800_rfcsr_write(rt2x00dev, 7, 0x34); | ||
3988 | rt2800_rfcsr_write(rt2x00dev, 8, 0x00); | ||
3989 | rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); | ||
3990 | rt2800_rfcsr_write(rt2x00dev, 10, 0x61); | ||
3991 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | ||
3992 | rt2800_rfcsr_write(rt2x00dev, 12, 0x3b); | ||
3993 | rt2800_rfcsr_write(rt2x00dev, 13, 0xe0); | ||
3994 | rt2800_rfcsr_write(rt2x00dev, 14, 0x90); | ||
3995 | rt2800_rfcsr_write(rt2x00dev, 15, 0x53); | ||
3996 | rt2800_rfcsr_write(rt2x00dev, 16, 0xe0); | ||
3997 | rt2800_rfcsr_write(rt2x00dev, 17, 0x94); | ||
3998 | rt2800_rfcsr_write(rt2x00dev, 18, 0x5c); | ||
3999 | rt2800_rfcsr_write(rt2x00dev, 19, 0x4a); | ||
4000 | rt2800_rfcsr_write(rt2x00dev, 20, 0xb2); | ||
4001 | rt2800_rfcsr_write(rt2x00dev, 21, 0xf6); | ||
4002 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
4003 | rt2800_rfcsr_write(rt2x00dev, 23, 0x14); | ||
4004 | rt2800_rfcsr_write(rt2x00dev, 24, 0x08); | ||
4005 | rt2800_rfcsr_write(rt2x00dev, 25, 0x3d); | ||
4006 | rt2800_rfcsr_write(rt2x00dev, 26, 0x85); | ||
4007 | rt2800_rfcsr_write(rt2x00dev, 27, 0x00); | ||
4008 | rt2800_rfcsr_write(rt2x00dev, 28, 0x41); | ||
4009 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); | ||
4010 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); | ||
4011 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); | ||
4012 | } else if (rt2x00_rt(rt2x00dev, RT3572)) { | ||
4013 | rt2800_rfcsr_write(rt2x00dev, 0, 0x70); | ||
4014 | rt2800_rfcsr_write(rt2x00dev, 1, 0x81); | ||
4015 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); | ||
4016 | rt2800_rfcsr_write(rt2x00dev, 3, 0x02); | ||
4017 | rt2800_rfcsr_write(rt2x00dev, 4, 0x4c); | ||
4018 | rt2800_rfcsr_write(rt2x00dev, 5, 0x05); | ||
4019 | rt2800_rfcsr_write(rt2x00dev, 6, 0x4a); | ||
4020 | rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); | ||
4021 | rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); | ||
4022 | rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); | ||
4023 | rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); | ||
4024 | rt2800_rfcsr_write(rt2x00dev, 12, 0x70); | ||
4025 | rt2800_rfcsr_write(rt2x00dev, 13, 0x65); | ||
4026 | rt2800_rfcsr_write(rt2x00dev, 14, 0xa0); | ||
4027 | rt2800_rfcsr_write(rt2x00dev, 15, 0x53); | ||
4028 | rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); | ||
4029 | rt2800_rfcsr_write(rt2x00dev, 17, 0x23); | ||
4030 | rt2800_rfcsr_write(rt2x00dev, 18, 0xac); | ||
4031 | rt2800_rfcsr_write(rt2x00dev, 19, 0x93); | ||
4032 | rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); | ||
4033 | rt2800_rfcsr_write(rt2x00dev, 21, 0xd0); | ||
4034 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
4035 | rt2800_rfcsr_write(rt2x00dev, 23, 0x3c); | ||
4036 | rt2800_rfcsr_write(rt2x00dev, 24, 0x16); | ||
4037 | rt2800_rfcsr_write(rt2x00dev, 25, 0x15); | ||
4038 | rt2800_rfcsr_write(rt2x00dev, 26, 0x85); | ||
4039 | rt2800_rfcsr_write(rt2x00dev, 27, 0x00); | ||
4040 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
4041 | rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); | ||
4042 | rt2800_rfcsr_write(rt2x00dev, 30, 0x09); | ||
4043 | rt2800_rfcsr_write(rt2x00dev, 31, 0x10); | ||
4044 | } else if (rt2800_is_305x_soc(rt2x00dev)) { | ||
4045 | rt2800_rfcsr_write(rt2x00dev, 0, 0x50); | ||
4046 | rt2800_rfcsr_write(rt2x00dev, 1, 0x01); | ||
4047 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); | ||
4048 | rt2800_rfcsr_write(rt2x00dev, 3, 0x75); | ||
4049 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | ||
4050 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); | ||
4051 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); | ||
4052 | rt2800_rfcsr_write(rt2x00dev, 7, 0x50); | ||
4053 | rt2800_rfcsr_write(rt2x00dev, 8, 0x39); | ||
4054 | rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); | ||
4055 | rt2800_rfcsr_write(rt2x00dev, 10, 0x60); | ||
4056 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | ||
4057 | rt2800_rfcsr_write(rt2x00dev, 12, 0x75); | ||
4058 | rt2800_rfcsr_write(rt2x00dev, 13, 0x75); | ||
4059 | rt2800_rfcsr_write(rt2x00dev, 14, 0x90); | ||
4060 | rt2800_rfcsr_write(rt2x00dev, 15, 0x58); | ||
4061 | rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); | ||
4062 | rt2800_rfcsr_write(rt2x00dev, 17, 0x92); | ||
4063 | rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); | ||
4064 | rt2800_rfcsr_write(rt2x00dev, 19, 0x02); | ||
4065 | rt2800_rfcsr_write(rt2x00dev, 20, 0xba); | ||
4066 | rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); | ||
4067 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
4068 | rt2800_rfcsr_write(rt2x00dev, 23, 0x31); | ||
4069 | rt2800_rfcsr_write(rt2x00dev, 24, 0x08); | ||
4070 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | ||
4071 | rt2800_rfcsr_write(rt2x00dev, 26, 0x25); | ||
4072 | rt2800_rfcsr_write(rt2x00dev, 27, 0x23); | ||
4073 | rt2800_rfcsr_write(rt2x00dev, 28, 0x13); | ||
4074 | rt2800_rfcsr_write(rt2x00dev, 29, 0x83); | ||
4075 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | ||
4076 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); | ||
4077 | return 0; | 4306 | return 0; |
4078 | } else if (rt2x00_rt(rt2x00dev, RT3352)) { | 4307 | } |
4079 | rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); | 4308 | |
4080 | rt2800_rfcsr_write(rt2x00dev, 1, 0x23); | 4309 | switch (rt2x00dev->chip.rt) { |
4081 | rt2800_rfcsr_write(rt2x00dev, 2, 0x50); | 4310 | case RT3070: |
4082 | rt2800_rfcsr_write(rt2x00dev, 3, 0x18); | 4311 | case RT3071: |
4083 | rt2800_rfcsr_write(rt2x00dev, 4, 0x00); | 4312 | case RT3090: |
4084 | rt2800_rfcsr_write(rt2x00dev, 5, 0x00); | 4313 | rt2800_init_rfcsr_30xx(rt2x00dev); |
4085 | rt2800_rfcsr_write(rt2x00dev, 6, 0x33); | 4314 | break; |
4086 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | 4315 | case RT3290: |
4087 | rt2800_rfcsr_write(rt2x00dev, 8, 0xf1); | 4316 | rt2800_init_rfcsr_3290(rt2x00dev); |
4088 | rt2800_rfcsr_write(rt2x00dev, 9, 0x02); | 4317 | break; |
4089 | rt2800_rfcsr_write(rt2x00dev, 10, 0xd2); | 4318 | case RT3352: |
4090 | rt2800_rfcsr_write(rt2x00dev, 11, 0x42); | 4319 | rt2800_init_rfcsr_3352(rt2x00dev); |
4091 | rt2800_rfcsr_write(rt2x00dev, 12, 0x1c); | 4320 | break; |
4092 | rt2800_rfcsr_write(rt2x00dev, 13, 0x00); | 4321 | case RT3390: |
4093 | rt2800_rfcsr_write(rt2x00dev, 14, 0x5a); | 4322 | rt2800_init_rfcsr_3390(rt2x00dev); |
4094 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | 4323 | break; |
4095 | rt2800_rfcsr_write(rt2x00dev, 16, 0x01); | 4324 | case RT3572: |
4096 | rt2800_rfcsr_write(rt2x00dev, 18, 0x45); | 4325 | rt2800_init_rfcsr_3572(rt2x00dev); |
4097 | rt2800_rfcsr_write(rt2x00dev, 19, 0x02); | 4326 | break; |
4098 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | 4327 | case RT5390: |
4099 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); | 4328 | rt2800_init_rfcsr_5390(rt2x00dev); |
4100 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | 4329 | break; |
4101 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); | 4330 | case RT5392: |
4102 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); | 4331 | rt2800_init_rfcsr_5392(rt2x00dev); |
4103 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | 4332 | break; |
4104 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); | ||
4105 | rt2800_rfcsr_write(rt2x00dev, 27, 0x03); | ||
4106 | rt2800_rfcsr_write(rt2x00dev, 28, 0x03); | ||
4107 | rt2800_rfcsr_write(rt2x00dev, 29, 0x00); | ||
4108 | rt2800_rfcsr_write(rt2x00dev, 30, 0x10); | ||
4109 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
4110 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
4111 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
4112 | rt2800_rfcsr_write(rt2x00dev, 34, 0x01); | ||
4113 | rt2800_rfcsr_write(rt2x00dev, 35, 0x03); | ||
4114 | rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); | ||
4115 | rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); | ||
4116 | rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); | ||
4117 | rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); | ||
4118 | rt2800_rfcsr_write(rt2x00dev, 40, 0x33); | ||
4119 | rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); | ||
4120 | rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); | ||
4121 | rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); | ||
4122 | rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); | ||
4123 | rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); | ||
4124 | rt2800_rfcsr_write(rt2x00dev, 46, 0xdd); | ||
4125 | rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); | ||
4126 | rt2800_rfcsr_write(rt2x00dev, 48, 0x14); | ||
4127 | rt2800_rfcsr_write(rt2x00dev, 49, 0x00); | ||
4128 | rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); | ||
4129 | rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); | ||
4130 | rt2800_rfcsr_write(rt2x00dev, 52, 0x00); | ||
4131 | rt2800_rfcsr_write(rt2x00dev, 53, 0x52); | ||
4132 | rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); | ||
4133 | rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); | ||
4134 | rt2800_rfcsr_write(rt2x00dev, 56, 0x00); | ||
4135 | rt2800_rfcsr_write(rt2x00dev, 57, 0x52); | ||
4136 | rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); | ||
4137 | rt2800_rfcsr_write(rt2x00dev, 59, 0x00); | ||
4138 | rt2800_rfcsr_write(rt2x00dev, 60, 0x00); | ||
4139 | rt2800_rfcsr_write(rt2x00dev, 61, 0x00); | ||
4140 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | ||
4141 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | ||
4142 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
4143 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | ||
4144 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
4145 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | ||
4146 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | ||
4147 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4148 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); | ||
4149 | else | ||
4150 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); | ||
4151 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | ||
4152 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
4153 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
4154 | rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); | ||
4155 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
4156 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | ||
4157 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | ||
4158 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | ||
4159 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | ||
4160 | rt2800_rfcsr_write(rt2x00dev, 19, 0x00); | ||
4161 | |||
4162 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | ||
4163 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); | ||
4164 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
4165 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); | ||
4166 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); | ||
4167 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4168 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | ||
4169 | else | ||
4170 | rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); | ||
4171 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); | ||
4172 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
4173 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
4174 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
4175 | |||
4176 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | ||
4177 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
4178 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
4179 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
4180 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | ||
4181 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
4182 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
4183 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | ||
4184 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | ||
4185 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
4186 | |||
4187 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4188 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); | ||
4189 | else | ||
4190 | rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); | ||
4191 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
4192 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); | ||
4193 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); | ||
4194 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
4195 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
4196 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4197 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
4198 | else | ||
4199 | rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); | ||
4200 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); | ||
4201 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
4202 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); | ||
4203 | |||
4204 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); | ||
4205 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4206 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); | ||
4207 | else | ||
4208 | rt2800_rfcsr_write(rt2x00dev, 53, 0x84); | ||
4209 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); | ||
4210 | rt2800_rfcsr_write(rt2x00dev, 55, 0x44); | ||
4211 | rt2800_rfcsr_write(rt2x00dev, 56, 0x22); | ||
4212 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); | ||
4213 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); | ||
4214 | rt2800_rfcsr_write(rt2x00dev, 59, 0x63); | ||
4215 | |||
4216 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
4217 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
4218 | rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); | ||
4219 | else | ||
4220 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); | ||
4221 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | ||
4222 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | ||
4223 | } else if (rt2x00_rt(rt2x00dev, RT5392)) { | ||
4224 | rt2800_rfcsr_write(rt2x00dev, 1, 0x17); | ||
4225 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
4226 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | ||
4227 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | ||
4228 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); | ||
4229 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | ||
4230 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
4231 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
4232 | rt2800_rfcsr_write(rt2x00dev, 12, 0x46); | ||
4233 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
4234 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | ||
4235 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | ||
4236 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | ||
4237 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | ||
4238 | rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); | ||
4239 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | ||
4240 | rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); | ||
4241 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
4242 | rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); | ||
4243 | rt2800_rfcsr_write(rt2x00dev, 24, 0x44); | ||
4244 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | ||
4245 | rt2800_rfcsr_write(rt2x00dev, 26, 0x82); | ||
4246 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
4247 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
4248 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
4249 | rt2800_rfcsr_write(rt2x00dev, 30, 0x10); | ||
4250 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
4251 | rt2800_rfcsr_write(rt2x00dev, 32, 0x20); | ||
4252 | rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); | ||
4253 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | ||
4254 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
4255 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
4256 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | ||
4257 | rt2800_rfcsr_write(rt2x00dev, 38, 0x89); | ||
4258 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
4259 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); | ||
4260 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
4261 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); | ||
4262 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); | ||
4263 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
4264 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
4265 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
4266 | rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); | ||
4267 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
4268 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); | ||
4269 | rt2800_rfcsr_write(rt2x00dev, 50, 0x94); | ||
4270 | rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); | ||
4271 | rt2800_rfcsr_write(rt2x00dev, 52, 0x48); | ||
4272 | rt2800_rfcsr_write(rt2x00dev, 53, 0x44); | ||
4273 | rt2800_rfcsr_write(rt2x00dev, 54, 0x38); | ||
4274 | rt2800_rfcsr_write(rt2x00dev, 55, 0x43); | ||
4275 | rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); | ||
4276 | rt2800_rfcsr_write(rt2x00dev, 57, 0x00); | ||
4277 | rt2800_rfcsr_write(rt2x00dev, 58, 0x39); | ||
4278 | rt2800_rfcsr_write(rt2x00dev, 59, 0x07); | ||
4279 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
4280 | rt2800_rfcsr_write(rt2x00dev, 61, 0x91); | ||
4281 | rt2800_rfcsr_write(rt2x00dev, 62, 0x39); | ||
4282 | rt2800_rfcsr_write(rt2x00dev, 63, 0x07); | ||
4283 | } | 4333 | } |
4284 | 4334 | ||
4285 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | 4335 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { |
@@ -4620,12 +4670,14 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) | |||
4620 | mutex_unlock(&rt2x00dev->csr_mutex); | 4670 | mutex_unlock(&rt2x00dev->csr_mutex); |
4621 | } | 4671 | } |
4622 | 4672 | ||
4623 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) | 4673 | int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) |
4624 | { | 4674 | { |
4625 | unsigned int i; | 4675 | unsigned int i; |
4626 | 4676 | ||
4627 | for (i = 0; i < EEPROM_SIZE / sizeof(u16); i += 8) | 4677 | for (i = 0; i < EEPROM_SIZE / sizeof(u16); i += 8) |
4628 | rt2800_efuse_read(rt2x00dev, i); | 4678 | rt2800_efuse_read(rt2x00dev, i); |
4679 | |||
4680 | return 0; | ||
4629 | } | 4681 | } |
4630 | EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); | 4682 | EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); |
4631 | 4683 | ||
@@ -4635,11 +4687,14 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
4635 | u16 word; | 4687 | u16 word; |
4636 | u8 *mac; | 4688 | u8 *mac; |
4637 | u8 default_lna_gain; | 4689 | u8 default_lna_gain; |
4690 | int retval; | ||
4638 | 4691 | ||
4639 | /* | 4692 | /* |
4640 | * Read the EEPROM. | 4693 | * Read the EEPROM. |
4641 | */ | 4694 | */ |
4642 | rt2800_read_eeprom(rt2x00dev); | 4695 | retval = rt2800_read_eeprom(rt2x00dev); |
4696 | if (retval) | ||
4697 | return retval; | ||
4643 | 4698 | ||
4644 | /* | 4699 | /* |
4645 | * Start validation of the data that has been read. | 4700 | * Start validation of the data that has been read. |
@@ -5090,8 +5145,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
5090 | IEEE80211_HW_SUPPORTS_PS | | 5145 | IEEE80211_HW_SUPPORTS_PS | |
5091 | IEEE80211_HW_PS_NULLFUNC_STACK | | 5146 | IEEE80211_HW_PS_NULLFUNC_STACK | |
5092 | IEEE80211_HW_AMPDU_AGGREGATION | | 5147 | IEEE80211_HW_AMPDU_AGGREGATION | |
5093 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 5148 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; |
5094 | IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL; | ||
5095 | 5149 | ||
5096 | /* | 5150 | /* |
5097 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices | 5151 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices |
@@ -5484,7 +5538,9 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5484 | case IEEE80211_AMPDU_TX_START: | 5538 | case IEEE80211_AMPDU_TX_START: |
5485 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 5539 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
5486 | break; | 5540 | break; |
5487 | case IEEE80211_AMPDU_TX_STOP: | 5541 | case IEEE80211_AMPDU_TX_STOP_CONT: |
5542 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
5543 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
5488 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 5544 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
5489 | break; | 5545 | break; |
5490 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 5546 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index a128ceadcb3e..6ec739466db4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -43,7 +43,7 @@ struct rt2800_ops { | |||
43 | const unsigned int offset, | 43 | const unsigned int offset, |
44 | const struct rt2x00_field32 field, u32 *reg); | 44 | const struct rt2x00_field32 field, u32 *reg); |
45 | 45 | ||
46 | void (*read_eeprom)(struct rt2x00_dev *rt2x00dev); | 46 | int (*read_eeprom)(struct rt2x00_dev *rt2x00dev); |
47 | bool (*hwcrypt_disabled)(struct rt2x00_dev *rt2x00dev); | 47 | bool (*hwcrypt_disabled)(struct rt2x00_dev *rt2x00dev); |
48 | 48 | ||
49 | int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, | 49 | int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, |
@@ -117,11 +117,11 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
117 | return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg); | 117 | return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg); |
118 | } | 118 | } |
119 | 119 | ||
120 | static inline void rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev) | 120 | static inline int rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev) |
121 | { | 121 | { |
122 | const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; | 122 | const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; |
123 | 123 | ||
124 | rt2800ops->read_eeprom(rt2x00dev); | 124 | return rt2800ops->read_eeprom(rt2x00dev); |
125 | } | 125 | } |
126 | 126 | ||
127 | static inline bool rt2800_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) | 127 | static inline bool rt2800_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) |
@@ -207,7 +207,7 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); | |||
207 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); | 207 | void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); |
208 | 208 | ||
209 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); | 209 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); |
210 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); | 210 | int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); |
211 | 211 | ||
212 | int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev); | 212 | int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev); |
213 | 213 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 9224d874bf24..0e8d1705e368 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -90,17 +90,22 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) | |||
90 | } | 90 | } |
91 | 91 | ||
92 | #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) | 92 | #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) |
93 | static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) | 93 | static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) |
94 | { | 94 | { |
95 | void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); | 95 | void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); |
96 | 96 | ||
97 | if (!base_addr) | ||
98 | return -ENOMEM; | ||
99 | |||
97 | memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); | 100 | memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); |
98 | 101 | ||
99 | iounmap(base_addr); | 102 | iounmap(base_addr); |
103 | return 0; | ||
100 | } | 104 | } |
101 | #else | 105 | #else |
102 | static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) | 106 | static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) |
103 | { | 107 | { |
108 | return -ENOMEM; | ||
104 | } | 109 | } |
105 | #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ | 110 | #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ |
106 | 111 | ||
@@ -135,7 +140,7 @@ static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | |||
135 | rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); | 140 | rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); |
136 | } | 141 | } |
137 | 142 | ||
138 | static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | 143 | static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) |
139 | { | 144 | { |
140 | struct eeprom_93cx6 eeprom; | 145 | struct eeprom_93cx6 eeprom; |
141 | u32 reg; | 146 | u32 reg; |
@@ -164,6 +169,8 @@ static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | |||
164 | 169 | ||
165 | eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, | 170 | eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, |
166 | EEPROM_SIZE / sizeof(u16)); | 171 | EEPROM_SIZE / sizeof(u16)); |
172 | |||
173 | return 0; | ||
167 | } | 174 | } |
168 | 175 | ||
169 | static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) | 176 | static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) |
@@ -171,13 +178,14 @@ static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) | |||
171 | return rt2800_efuse_detect(rt2x00dev); | 178 | return rt2800_efuse_detect(rt2x00dev); |
172 | } | 179 | } |
173 | 180 | ||
174 | static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) | 181 | static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) |
175 | { | 182 | { |
176 | rt2800_read_eeprom_efuse(rt2x00dev); | 183 | return rt2800_read_eeprom_efuse(rt2x00dev); |
177 | } | 184 | } |
178 | #else | 185 | #else |
179 | static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | 186 | static inline int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) |
180 | { | 187 | { |
188 | return -EOPNOTSUPP; | ||
181 | } | 189 | } |
182 | 190 | ||
183 | static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) | 191 | static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) |
@@ -185,8 +193,9 @@ static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) | |||
185 | return 0; | 193 | return 0; |
186 | } | 194 | } |
187 | 195 | ||
188 | static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) | 196 | static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) |
189 | { | 197 | { |
198 | return -EOPNOTSUPP; | ||
190 | } | 199 | } |
191 | #endif /* CONFIG_PCI */ | 200 | #endif /* CONFIG_PCI */ |
192 | 201 | ||
@@ -970,14 +979,18 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
970 | /* | 979 | /* |
971 | * Device probe functions. | 980 | * Device probe functions. |
972 | */ | 981 | */ |
973 | static void rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev) | 982 | static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev) |
974 | { | 983 | { |
984 | int retval; | ||
985 | |||
975 | if (rt2x00_is_soc(rt2x00dev)) | 986 | if (rt2x00_is_soc(rt2x00dev)) |
976 | rt2800pci_read_eeprom_soc(rt2x00dev); | 987 | retval = rt2800pci_read_eeprom_soc(rt2x00dev); |
977 | else if (rt2800pci_efuse_detect(rt2x00dev)) | 988 | else if (rt2800pci_efuse_detect(rt2x00dev)) |
978 | rt2800pci_read_eeprom_efuse(rt2x00dev); | 989 | retval = rt2800pci_read_eeprom_efuse(rt2x00dev); |
979 | else | 990 | else |
980 | rt2800pci_read_eeprom_pci(rt2x00dev); | 991 | retval = rt2800pci_read_eeprom_pci(rt2x00dev); |
992 | |||
993 | return retval; | ||
981 | } | 994 | } |
982 | 995 | ||
983 | static const struct ieee80211_ops rt2800pci_mac80211_ops = { | 996 | static const struct ieee80211_ops rt2800pci_mac80211_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5c149b58ab46..4721cada1591 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -735,13 +735,17 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
735 | /* | 735 | /* |
736 | * Device probe functions. | 736 | * Device probe functions. |
737 | */ | 737 | */ |
738 | static void rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) | 738 | static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) |
739 | { | 739 | { |
740 | int retval; | ||
741 | |||
740 | if (rt2800_efuse_detect(rt2x00dev)) | 742 | if (rt2800_efuse_detect(rt2x00dev)) |
741 | rt2800_read_eeprom_efuse(rt2x00dev); | 743 | retval = rt2800_read_eeprom_efuse(rt2x00dev); |
742 | else | 744 | else |
743 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, | 745 | retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, |
744 | EEPROM_SIZE); | 746 | EEPROM_SIZE); |
747 | |||
748 | return retval; | ||
745 | } | 749 | } |
746 | 750 | ||
747 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 751 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 0751b35ef6dc..b52512b8ac5f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1016,6 +1016,26 @@ struct rt2x00_dev { | |||
1016 | * Protect the interrupt mask register. | 1016 | * Protect the interrupt mask register. |
1017 | */ | 1017 | */ |
1018 | spinlock_t irqmask_lock; | 1018 | spinlock_t irqmask_lock; |
1019 | |||
1020 | /* | ||
1021 | * List of BlockAckReq TX entries that need driver BlockAck processing. | ||
1022 | */ | ||
1023 | struct list_head bar_list; | ||
1024 | spinlock_t bar_list_lock; | ||
1025 | }; | ||
1026 | |||
1027 | struct rt2x00_bar_list_entry { | ||
1028 | struct list_head list; | ||
1029 | struct rcu_head head; | ||
1030 | |||
1031 | struct queue_entry *entry; | ||
1032 | int block_acked; | ||
1033 | |||
1034 | /* Relevant parts of the IEEE80211 BAR header */ | ||
1035 | __u8 ra[6]; | ||
1036 | __u8 ta[6]; | ||
1037 | __le16 control; | ||
1038 | __le16 start_seq_num; | ||
1019 | }; | 1039 | }; |
1020 | 1040 | ||
1021 | /* | 1041 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 44f8b3f3cbed..b40a53857498 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -271,6 +271,50 @@ void rt2x00lib_dmadone(struct queue_entry *entry) | |||
271 | } | 271 | } |
272 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); | 272 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); |
273 | 273 | ||
274 | static inline int rt2x00lib_txdone_bar_status(struct queue_entry *entry) | ||
275 | { | ||
276 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
277 | struct ieee80211_bar *bar = (void *) entry->skb->data; | ||
278 | struct rt2x00_bar_list_entry *bar_entry; | ||
279 | int ret; | ||
280 | |||
281 | if (likely(!ieee80211_is_back_req(bar->frame_control))) | ||
282 | return 0; | ||
283 | |||
284 | /* | ||
285 | * Unlike all other frames, the status report for BARs does | ||
286 | * not directly come from the hardware as it is incapable of | ||
287 | * matching a BA to a previously send BAR. The hardware will | ||
288 | * report all BARs as if they weren't acked at all. | ||
289 | * | ||
290 | * Instead the RX-path will scan for incoming BAs and set the | ||
291 | * block_acked flag if it sees one that was likely caused by | ||
292 | * a BAR from us. | ||
293 | * | ||
294 | * Remove remaining BARs here and return their status for | ||
295 | * TX done processing. | ||
296 | */ | ||
297 | ret = 0; | ||
298 | rcu_read_lock(); | ||
299 | list_for_each_entry_rcu(bar_entry, &rt2x00dev->bar_list, list) { | ||
300 | if (bar_entry->entry != entry) | ||
301 | continue; | ||
302 | |||
303 | spin_lock_bh(&rt2x00dev->bar_list_lock); | ||
304 | /* Return whether this BAR was blockacked or not */ | ||
305 | ret = bar_entry->block_acked; | ||
306 | /* Remove the BAR from our checklist */ | ||
307 | list_del_rcu(&bar_entry->list); | ||
308 | spin_unlock_bh(&rt2x00dev->bar_list_lock); | ||
309 | kfree_rcu(bar_entry, head); | ||
310 | |||
311 | break; | ||
312 | } | ||
313 | rcu_read_unlock(); | ||
314 | |||
315 | return ret; | ||
316 | } | ||
317 | |||
274 | void rt2x00lib_txdone(struct queue_entry *entry, | 318 | void rt2x00lib_txdone(struct queue_entry *entry, |
275 | struct txdone_entry_desc *txdesc) | 319 | struct txdone_entry_desc *txdesc) |
276 | { | 320 | { |
@@ -324,9 +368,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
324 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb); | 368 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb); |
325 | 369 | ||
326 | /* | 370 | /* |
327 | * Determine if the frame has been successfully transmitted. | 371 | * Determine if the frame has been successfully transmitted and |
372 | * remove BARs from our check list while checking for their | ||
373 | * TX status. | ||
328 | */ | 374 | */ |
329 | success = | 375 | success = |
376 | rt2x00lib_txdone_bar_status(entry) || | ||
330 | test_bit(TXDONE_SUCCESS, &txdesc->flags) || | 377 | test_bit(TXDONE_SUCCESS, &txdesc->flags) || |
331 | test_bit(TXDONE_UNKNOWN, &txdesc->flags); | 378 | test_bit(TXDONE_UNKNOWN, &txdesc->flags); |
332 | 379 | ||
@@ -491,6 +538,50 @@ static void rt2x00lib_sleep(struct work_struct *work) | |||
491 | IEEE80211_CONF_CHANGE_PS); | 538 | IEEE80211_CONF_CHANGE_PS); |
492 | } | 539 | } |
493 | 540 | ||
541 | static void rt2x00lib_rxdone_check_ba(struct rt2x00_dev *rt2x00dev, | ||
542 | struct sk_buff *skb, | ||
543 | struct rxdone_entry_desc *rxdesc) | ||
544 | { | ||
545 | struct rt2x00_bar_list_entry *entry; | ||
546 | struct ieee80211_bar *ba = (void *)skb->data; | ||
547 | |||
548 | if (likely(!ieee80211_is_back(ba->frame_control))) | ||
549 | return; | ||
550 | |||
551 | if (rxdesc->size < sizeof(*ba) + FCS_LEN) | ||
552 | return; | ||
553 | |||
554 | rcu_read_lock(); | ||
555 | list_for_each_entry_rcu(entry, &rt2x00dev->bar_list, list) { | ||
556 | |||
557 | if (ba->start_seq_num != entry->start_seq_num) | ||
558 | continue; | ||
559 | |||
560 | #define TID_CHECK(a, b) ( \ | ||
561 | ((a) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK)) == \ | ||
562 | ((b) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK))) \ | ||
563 | |||
564 | if (!TID_CHECK(ba->control, entry->control)) | ||
565 | continue; | ||
566 | |||
567 | #undef TID_CHECK | ||
568 | |||
569 | if (compare_ether_addr(ba->ra, entry->ta)) | ||
570 | continue; | ||
571 | |||
572 | if (compare_ether_addr(ba->ta, entry->ra)) | ||
573 | continue; | ||
574 | |||
575 | /* Mark BAR since we received the according BA */ | ||
576 | spin_lock_bh(&rt2x00dev->bar_list_lock); | ||
577 | entry->block_acked = 1; | ||
578 | spin_unlock_bh(&rt2x00dev->bar_list_lock); | ||
579 | break; | ||
580 | } | ||
581 | rcu_read_unlock(); | ||
582 | |||
583 | } | ||
584 | |||
494 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, | 585 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, |
495 | struct sk_buff *skb, | 586 | struct sk_buff *skb, |
496 | struct rxdone_entry_desc *rxdesc) | 587 | struct rxdone_entry_desc *rxdesc) |
@@ -674,6 +765,12 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) | |||
674 | rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc); | 765 | rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc); |
675 | 766 | ||
676 | /* | 767 | /* |
768 | * Check for incoming BlockAcks to match to the BlockAckReqs | ||
769 | * we've send out. | ||
770 | */ | ||
771 | rt2x00lib_rxdone_check_ba(rt2x00dev, entry->skb, &rxdesc); | ||
772 | |||
773 | /* | ||
677 | * Update extra components | 774 | * Update extra components |
678 | */ | 775 | */ |
679 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); | 776 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); |
@@ -1183,6 +1280,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1183 | 1280 | ||
1184 | spin_lock_init(&rt2x00dev->irqmask_lock); | 1281 | spin_lock_init(&rt2x00dev->irqmask_lock); |
1185 | mutex_init(&rt2x00dev->csr_mutex); | 1282 | mutex_init(&rt2x00dev->csr_mutex); |
1283 | INIT_LIST_HEAD(&rt2x00dev->bar_list); | ||
1284 | spin_lock_init(&rt2x00dev->bar_list_lock); | ||
1186 | 1285 | ||
1187 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); | 1286 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); |
1188 | 1287 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index e488b944a034..f35d85a71bbc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -582,6 +582,48 @@ static void rt2x00queue_kick_tx_queue(struct data_queue *queue, | |||
582 | queue->rt2x00dev->ops->lib->kick_queue(queue); | 582 | queue->rt2x00dev->ops->lib->kick_queue(queue); |
583 | } | 583 | } |
584 | 584 | ||
585 | static void rt2x00queue_bar_check(struct queue_entry *entry) | ||
586 | { | ||
587 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
588 | struct ieee80211_bar *bar = (void *) (entry->skb->data + | ||
589 | rt2x00dev->ops->extra_tx_headroom); | ||
590 | struct rt2x00_bar_list_entry *bar_entry; | ||
591 | |||
592 | if (likely(!ieee80211_is_back_req(bar->frame_control))) | ||
593 | return; | ||
594 | |||
595 | bar_entry = kmalloc(sizeof(*bar_entry), GFP_ATOMIC); | ||
596 | |||
597 | /* | ||
598 | * If the alloc fails we still send the BAR out but just don't track | ||
599 | * it in our bar list. And as a result we will report it to mac80211 | ||
600 | * back as failed. | ||
601 | */ | ||
602 | if (!bar_entry) | ||
603 | return; | ||
604 | |||
605 | bar_entry->entry = entry; | ||
606 | bar_entry->block_acked = 0; | ||
607 | |||
608 | /* | ||
609 | * Copy the relevant parts of the 802.11 BAR into out check list | ||
610 | * such that we can use RCU for less-overhead in the RX path since | ||
611 | * sending BARs and processing the according BlockAck should be | ||
612 | * the exception. | ||
613 | */ | ||
614 | memcpy(bar_entry->ra, bar->ra, sizeof(bar->ra)); | ||
615 | memcpy(bar_entry->ta, bar->ta, sizeof(bar->ta)); | ||
616 | bar_entry->control = bar->control; | ||
617 | bar_entry->start_seq_num = bar->start_seq_num; | ||
618 | |||
619 | /* | ||
620 | * Insert BAR into our BAR check list. | ||
621 | */ | ||
622 | spin_lock_bh(&rt2x00dev->bar_list_lock); | ||
623 | list_add_tail_rcu(&bar_entry->list, &rt2x00dev->bar_list); | ||
624 | spin_unlock_bh(&rt2x00dev->bar_list_lock); | ||
625 | } | ||
626 | |||
585 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | 627 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, |
586 | bool local) | 628 | bool local) |
587 | { | 629 | { |
@@ -680,6 +722,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
680 | goto out; | 722 | goto out; |
681 | } | 723 | } |
682 | 724 | ||
725 | /* | ||
726 | * Put BlockAckReqs into our check list for driver BA processing. | ||
727 | */ | ||
728 | rt2x00queue_bar_check(entry); | ||
729 | |||
683 | set_bit(ENTRY_DATA_PENDING, &entry->flags); | 730 | set_bit(ENTRY_DATA_PENDING, &entry->flags); |
684 | 731 | ||
685 | rt2x00queue_index_inc(entry, Q_INDEX); | 732 | rt2x00queue_index_inc(entry, Q_INDEX); |
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 21b1bbb93a7e..b80bc4612581 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig | |||
@@ -57,12 +57,12 @@ config RTL8192CU | |||
57 | 57 | ||
58 | config RTLWIFI | 58 | config RTLWIFI |
59 | tristate | 59 | tristate |
60 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE | 60 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE |
61 | default m | 61 | default m |
62 | 62 | ||
63 | config RTLWIFI_DEBUG | 63 | config RTLWIFI_DEBUG |
64 | bool "Additional debugging output" | 64 | bool "Additional debugging output" |
65 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE | 65 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE |
66 | default y | 66 | default y |
67 | 67 | ||
68 | config RTL8192C_COMMON | 68 | config RTL8192C_COMMON |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index be33aa14c8af..d3ce9fbef00e 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -879,7 +879,9 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, | |||
879 | "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); | 879 | "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); |
880 | return rtl_tx_agg_start(hw, sta, tid, ssn); | 880 | return rtl_tx_agg_start(hw, sta, tid, ssn); |
881 | break; | 881 | break; |
882 | case IEEE80211_AMPDU_TX_STOP: | 882 | case IEEE80211_AMPDU_TX_STOP_CONT: |
883 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
884 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
883 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 885 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
884 | "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); | 886 | "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); |
885 | return rtl_tx_agg_stop(hw, sta, tid); | 887 | return rtl_tx_agg_stop(hw, sta, tid); |
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index c1608cddc529..d7d0d4948b01 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c | |||
@@ -158,8 +158,6 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, | |||
158 | const struct ieee80211_reg_rule *reg_rule; | 158 | const struct ieee80211_reg_rule *reg_rule; |
159 | struct ieee80211_channel *ch; | 159 | struct ieee80211_channel *ch; |
160 | unsigned int i; | 160 | unsigned int i; |
161 | u32 bandwidth = 0; | ||
162 | int r; | ||
163 | 161 | ||
164 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 162 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
165 | 163 | ||
@@ -174,9 +172,8 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, | |||
174 | (ch->flags & IEEE80211_CHAN_RADAR)) | 172 | (ch->flags & IEEE80211_CHAN_RADAR)) |
175 | continue; | 173 | continue; |
176 | if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { | 174 | if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { |
177 | r = freq_reg_info(wiphy, ch->center_freq, | 175 | reg_rule = freq_reg_info(wiphy, ch->center_freq); |
178 | bandwidth, ®_rule); | 176 | if (IS_ERR(reg_rule)) |
179 | if (r) | ||
180 | continue; | 177 | continue; |
181 | 178 | ||
182 | /* | 179 | /* |
@@ -211,8 +208,6 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, | |||
211 | struct ieee80211_supported_band *sband; | 208 | struct ieee80211_supported_band *sband; |
212 | struct ieee80211_channel *ch; | 209 | struct ieee80211_channel *ch; |
213 | const struct ieee80211_reg_rule *reg_rule; | 210 | const struct ieee80211_reg_rule *reg_rule; |
214 | u32 bandwidth = 0; | ||
215 | int r; | ||
216 | 211 | ||
217 | if (!wiphy->bands[IEEE80211_BAND_2GHZ]) | 212 | if (!wiphy->bands[IEEE80211_BAND_2GHZ]) |
218 | return; | 213 | return; |
@@ -240,16 +235,16 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, | |||
240 | */ | 235 | */ |
241 | 236 | ||
242 | ch = &sband->channels[11]; /* CH 12 */ | 237 | ch = &sband->channels[11]; /* CH 12 */ |
243 | r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); | 238 | reg_rule = freq_reg_info(wiphy, ch->center_freq); |
244 | if (!r) { | 239 | if (!IS_ERR(reg_rule)) { |
245 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) | 240 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) |
246 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 241 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
247 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | 242 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; |
248 | } | 243 | } |
249 | 244 | ||
250 | ch = &sband->channels[12]; /* CH 13 */ | 245 | ch = &sband->channels[12]; /* CH 13 */ |
251 | r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); | 246 | reg_rule = freq_reg_info(wiphy, ch->center_freq); |
252 | if (!r) { | 247 | if (!IS_ERR(reg_rule)) { |
253 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) | 248 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) |
254 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 249 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
255 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | 250 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; |
@@ -303,9 +298,9 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, | |||
303 | return; | 298 | return; |
304 | } | 299 | } |
305 | 300 | ||
306 | static int _rtl_reg_notifier_apply(struct wiphy *wiphy, | 301 | static void _rtl_reg_notifier_apply(struct wiphy *wiphy, |
307 | struct regulatory_request *request, | 302 | struct regulatory_request *request, |
308 | struct rtl_regulatory *reg) | 303 | struct rtl_regulatory *reg) |
309 | { | 304 | { |
310 | /* We always apply this */ | 305 | /* We always apply this */ |
311 | _rtl_reg_apply_radar_flags(wiphy); | 306 | _rtl_reg_apply_radar_flags(wiphy); |
@@ -319,8 +314,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy, | |||
319 | _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); | 314 | _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); |
320 | break; | 315 | break; |
321 | } | 316 | } |
322 | |||
323 | return 0; | ||
324 | } | 317 | } |
325 | 318 | ||
326 | static const struct ieee80211_regdomain *_rtl_regdomain_select( | 319 | static const struct ieee80211_regdomain *_rtl_regdomain_select( |
@@ -353,9 +346,9 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select( | |||
353 | 346 | ||
354 | static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, | 347 | static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, |
355 | struct wiphy *wiphy, | 348 | struct wiphy *wiphy, |
356 | int (*reg_notifier) (struct wiphy *wiphy, | 349 | void (*reg_notifier) (struct wiphy *wiphy, |
357 | struct regulatory_request * | 350 | struct regulatory_request * |
358 | request)) | 351 | request)) |
359 | { | 352 | { |
360 | const struct ieee80211_regdomain *regd; | 353 | const struct ieee80211_regdomain *regd; |
361 | 354 | ||
@@ -384,7 +377,7 @@ static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) | |||
384 | } | 377 | } |
385 | 378 | ||
386 | int rtl_regd_init(struct ieee80211_hw *hw, | 379 | int rtl_regd_init(struct ieee80211_hw *hw, |
387 | int (*reg_notifier) (struct wiphy *wiphy, | 380 | void (*reg_notifier) (struct wiphy *wiphy, |
388 | struct regulatory_request *request)) | 381 | struct regulatory_request *request)) |
389 | { | 382 | { |
390 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 383 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -426,12 +419,12 @@ int rtl_regd_init(struct ieee80211_hw *hw, | |||
426 | return 0; | 419 | return 0; |
427 | } | 420 | } |
428 | 421 | ||
429 | int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) | 422 | void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) |
430 | { | 423 | { |
431 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 424 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
432 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 425 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
433 | 426 | ||
434 | RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); | 427 | RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); |
435 | 428 | ||
436 | return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); | 429 | _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); |
437 | } | 430 | } |
diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h index 70ef2f418a44..4e1f4f00e6e9 100644 --- a/drivers/net/wireless/rtlwifi/regd.h +++ b/drivers/net/wireless/rtlwifi/regd.h | |||
@@ -55,7 +55,7 @@ enum country_code_type_t { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | int rtl_regd_init(struct ieee80211_hw *hw, | 57 | int rtl_regd_init(struct ieee80211_hw *hw, |
58 | int (*reg_notifier) (struct wiphy *wiphy, | 58 | void (*reg_notifier) (struct wiphy *wiphy, |
59 | struct regulatory_request *request)); | 59 | struct regulatory_request *request)); |
60 | int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); | 60 | void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); |
61 | #endif | 61 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index a0fbf284420e..cdb570ffb4b5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c | |||
@@ -452,7 +452,7 @@ static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
452 | u8 *praddr; | 452 | u8 *praddr; |
453 | u16 type, cfc; | 453 | u16 type, cfc; |
454 | __le16 fc; | 454 | __le16 fc; |
455 | bool packet_matchbssid, packet_toself, packet_beacon; | 455 | bool packet_matchbssid, packet_toself, packet_beacon = false; |
456 | 456 | ||
457 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; | 457 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; |
458 | hdr = (struct ieee80211_hdr *)tmp_buf; | 458 | hdr = (struct ieee80211_hdr *)tmp_buf; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 206561d7282f..f8431a3c2c9d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
@@ -480,7 +480,7 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
480 | u8 *praddr; | 480 | u8 *praddr; |
481 | __le16 fc; | 481 | __le16 fc; |
482 | u16 type, cfc; | 482 | u16 type, cfc; |
483 | bool packet_matchbssid, packet_toself, packet_beacon; | 483 | bool packet_matchbssid, packet_toself, packet_beacon = false; |
484 | 484 | ||
485 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; | 485 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; |
486 | 486 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c index a313be8c21d2..ce8ad12bce5b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c | |||
@@ -247,7 +247,7 @@ static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
247 | u8 *psaddr; | 247 | u8 *psaddr; |
248 | __le16 fc; | 248 | __le16 fc; |
249 | u16 type; | 249 | u16 type; |
250 | bool packet_matchbssid, packet_toself, packet_beacon; | 250 | bool packet_matchbssid, packet_toself, packet_beacon = false; |
251 | 251 | ||
252 | tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; | 252 | tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; |
253 | 253 | ||
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index ea9d8e011bc9..ce6e62a37e14 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -89,8 +89,8 @@ static int wl12xx_set_authorized(struct wl1271 *wl, | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int wl1271_reg_notify(struct wiphy *wiphy, | 92 | static void wl1271_reg_notify(struct wiphy *wiphy, |
93 | struct regulatory_request *request) | 93 | struct regulatory_request *request) |
94 | { | 94 | { |
95 | struct ieee80211_supported_band *band; | 95 | struct ieee80211_supported_band *band; |
96 | struct ieee80211_channel *ch; | 96 | struct ieee80211_channel *ch; |
@@ -107,8 +107,6 @@ static int wl1271_reg_notify(struct wiphy *wiphy, | |||
107 | IEEE80211_CHAN_PASSIVE_SCAN; | 107 | IEEE80211_CHAN_PASSIVE_SCAN; |
108 | 108 | ||
109 | } | 109 | } |
110 | |||
111 | return 0; | ||
112 | } | 110 | } |
113 | 111 | ||
114 | static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 112 | static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
@@ -4575,7 +4573,9 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, | |||
4575 | * Falling break here on purpose for all TX APDU commands. | 4573 | * Falling break here on purpose for all TX APDU commands. |
4576 | */ | 4574 | */ |
4577 | case IEEE80211_AMPDU_TX_START: | 4575 | case IEEE80211_AMPDU_TX_START: |
4578 | case IEEE80211_AMPDU_TX_STOP: | 4576 | case IEEE80211_AMPDU_TX_STOP_CONT: |
4577 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | ||
4578 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | ||
4579 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 4579 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
4580 | ret = -EINVAL; | 4580 | ret = -EINVAL; |
4581 | break; | 4581 | break; |