diff options
Diffstat (limited to 'drivers/net')
44 files changed, 666 insertions, 489 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 88279e325dca..157337febc2b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
@@ -203,7 +203,7 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
203 | i); | 203 | i); |
204 | 204 | ||
205 | ath_dbg(common, ATH_DBG_CALIBRATE, | 205 | ath_dbg(common, ATH_DBG_CALIBRATE, |
206 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | 206 | "Original: Chn %d iq_corr_meas = 0x%08x\n", |
207 | i, ah->totalIqCorrMeas[i]); | 207 | i, ah->totalIqCorrMeas[i]); |
208 | 208 | ||
209 | iqCorrNeg = 0; | 209 | iqCorrNeg = 0; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index ddeba8693fab..23b3a6c57800 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -226,7 +226,7 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
226 | i); | 226 | i); |
227 | 227 | ||
228 | ath_dbg(common, ATH_DBG_CALIBRATE, | 228 | ath_dbg(common, ATH_DBG_CALIBRATE, |
229 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | 229 | "Original: Chn %d iq_corr_meas = 0x%08x\n", |
230 | i, ah->totalIqCorrMeas[i]); | 230 | i, ah->totalIqCorrMeas[i]); |
231 | 231 | ||
232 | iqCorrNeg = 0; | 232 | iqCorrNeg = 0; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 259a6f312afb..dc2054f0378e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -41,24 +41,24 @@ static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = { | |||
41 | 41 | ||
42 | static const u32 ar9462_2p0_baseband_postamble[][5] = { | 42 | static const u32 ar9462_2p0_baseband_postamble[][5] = { |
43 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 43 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
44 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | 44 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, |
45 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, | 45 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae}, |
46 | {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x5ac640de}, | 46 | {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, |
47 | {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x0796be89}, | 47 | {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81}, |
48 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | 48 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, |
49 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | 49 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, |
50 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, | 50 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, |
51 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, | 51 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, |
52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, | 52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, |
53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | 53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, |
54 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x92c84d2e}, | 54 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, |
55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, | 55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x33795d5e}, |
56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, |
59 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | 59 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, |
60 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c782}, | 60 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, |
61 | {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, | 61 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, |
62 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, | 62 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, |
63 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | 63 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, |
64 | {0x0000a204, 0x013187c0, 0x013187c4, 0x013187c4, 0x013187c0}, | 64 | {0x0000a204, 0x013187c0, 0x013187c4, 0x013187c4, 0x013187c0}, |
@@ -81,6 +81,15 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
81 | {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, | 81 | {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, |
82 | {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, | 82 | {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, |
83 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 83 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
84 | {0x0000a3a4, 0x00000010, 0x00000010, 0x00000000, 0x00000000}, | ||
85 | {0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}, | ||
86 | {0x0000a3ac, 0xaaaaaa00, 0xaaaaaa30, 0xaaaaaa00, 0xaaaaaa00}, | ||
87 | {0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
88 | {0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce}, | ||
89 | {0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
90 | {0x0000a428, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce}, | ||
91 | {0x0000a42c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
92 | {0x0000a430, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce}, | ||
84 | {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | 93 | {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, |
85 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, | 94 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, |
86 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 95 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
@@ -1107,11 +1116,11 @@ static const u32 ar9462_2p0_baseband_core[][2] = { | |||
1107 | {0x00009e30, 0x06336f77}, | 1116 | {0x00009e30, 0x06336f77}, |
1108 | {0x00009e34, 0x6af6532f}, | 1117 | {0x00009e34, 0x6af6532f}, |
1109 | {0x00009e38, 0x0cc80c00}, | 1118 | {0x00009e38, 0x0cc80c00}, |
1110 | {0x00009e40, 0x0d261820}, | 1119 | {0x00009e40, 0x15262820}, |
1111 | {0x00009e4c, 0x00001004}, | 1120 | {0x00009e4c, 0x00001004}, |
1112 | {0x00009e50, 0x00ff03f1}, | 1121 | {0x00009e50, 0x00ff03f1}, |
1113 | {0x00009e54, 0xe4c355c7}, | 1122 | {0x00009e54, 0xe4c555c2}, |
1114 | {0x00009e58, 0xfd897735}, | 1123 | {0x00009e58, 0xfd857722}, |
1115 | {0x00009e5c, 0xe9198724}, | 1124 | {0x00009e5c, 0xe9198724}, |
1116 | {0x00009fc0, 0x803e4788}, | 1125 | {0x00009fc0, 0x803e4788}, |
1117 | {0x00009fc4, 0x0001efb5}, | 1126 | {0x00009fc4, 0x0001efb5}, |
@@ -1142,9 +1151,6 @@ static const u32 ar9462_2p0_baseband_core[][2] = { | |||
1142 | {0x0000a398, 0x001f0e0f}, | 1151 | {0x0000a398, 0x001f0e0f}, |
1143 | {0x0000a39c, 0x0075393f}, | 1152 | {0x0000a39c, 0x0075393f}, |
1144 | {0x0000a3a0, 0xb79f6427}, | 1153 | {0x0000a3a0, 0xb79f6427}, |
1145 | {0x0000a3a4, 0x00000000}, | ||
1146 | {0x0000a3a8, 0xaaaaaaaa}, | ||
1147 | {0x0000a3ac, 0x3c466478}, | ||
1148 | {0x0000a3c0, 0x20202020}, | 1154 | {0x0000a3c0, 0x20202020}, |
1149 | {0x0000a3c4, 0x22222220}, | 1155 | {0x0000a3c4, 0x22222220}, |
1150 | {0x0000a3c8, 0x20200020}, | 1156 | {0x0000a3c8, 0x20200020}, |
@@ -1167,12 +1173,6 @@ static const u32 ar9462_2p0_baseband_core[][2] = { | |||
1167 | {0x0000a40c, 0x00820820}, | 1173 | {0x0000a40c, 0x00820820}, |
1168 | {0x0000a414, 0x1ce739ce}, | 1174 | {0x0000a414, 0x1ce739ce}, |
1169 | {0x0000a418, 0x2d001dce}, | 1175 | {0x0000a418, 0x2d001dce}, |
1170 | {0x0000a41c, 0x1ce739ce}, | ||
1171 | {0x0000a420, 0x000001ce}, | ||
1172 | {0x0000a424, 0x1ce739ce}, | ||
1173 | {0x0000a428, 0x000001ce}, | ||
1174 | {0x0000a42c, 0x1ce739ce}, | ||
1175 | {0x0000a430, 0x1ce739ce}, | ||
1176 | {0x0000a434, 0x00000000}, | 1176 | {0x0000a434, 0x00000000}, |
1177 | {0x0000a438, 0x00001801}, | 1177 | {0x0000a438, 0x00001801}, |
1178 | {0x0000a43c, 0x00100000}, | 1178 | {0x0000a43c, 0x00100000}, |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 0b9a0e8a4958..f8ce4ea6f65c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -808,7 +808,8 @@ void ath9k_htc_ani_work(struct work_struct *work) | |||
808 | } | 808 | } |
809 | 809 | ||
810 | /* Verify whether we must check ANI */ | 810 | /* Verify whether we must check ANI */ |
811 | if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { | 811 | if (ah->config.enable_ani && |
812 | (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { | ||
812 | aniflag = true; | 813 | aniflag = true; |
813 | common->ani.checkani_timer = timestamp; | 814 | common->ani.checkani_timer = timestamp; |
814 | } | 815 | } |
@@ -838,7 +839,7 @@ set_timer: | |||
838 | * short calibration and long calibration. | 839 | * short calibration and long calibration. |
839 | */ | 840 | */ |
840 | cal_interval = ATH_LONG_CALINTERVAL; | 841 | cal_interval = ATH_LONG_CALINTERVAL; |
841 | if (priv->ah->config.enable_ani) | 842 | if (ah->config.enable_ani) |
842 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); | 843 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); |
843 | if (!common->ani.caldone) | 844 | if (!common->ani.caldone) |
844 | cal_interval = min(cal_interval, (u32)short_cal_interval); | 845 | cal_interval = min(cal_interval, (u32)short_cal_interval); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6ceb2e188080..7f8fc65f2cb4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -504,7 +504,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
504 | return ecode; | 504 | return ecode; |
505 | } | 505 | } |
506 | 506 | ||
507 | if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { | 507 | if (ah->config.enable_ani) { |
508 | ath9k_hw_ani_setup(ah); | 508 | ath9k_hw_ani_setup(ah); |
509 | ath9k_hw_ani_init(ah); | 509 | ath9k_hw_ani_init(ah); |
510 | } | 510 | } |
@@ -610,6 +610,10 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
610 | if (!AR_SREV_9300_20_OR_LATER(ah)) | 610 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
611 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; | 611 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; |
612 | 612 | ||
613 | /* disable ANI for 9340 */ | ||
614 | if (AR_SREV_9340(ah)) | ||
615 | ah->config.enable_ani = false; | ||
616 | |||
613 | ath9k_hw_init_mode_regs(ah); | 617 | ath9k_hw_init_mode_regs(ah); |
614 | 618 | ||
615 | if (!ah->is_pciexpress) | 619 | if (!ah->is_pciexpress) |
@@ -1967,7 +1971,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | |||
1967 | } | 1971 | } |
1968 | 1972 | ||
1969 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ | 1973 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ |
1970 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | 1974 | if (AR_SREV_9300_20_OR_LATER(ah)) |
1975 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | ||
1971 | } | 1976 | } |
1972 | 1977 | ||
1973 | /* | 1978 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c9c3b1889965..36968c046119 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -1110,7 +1110,6 @@ bool ath9k_hw_disable(struct ath_hw *ah); | |||
1110 | void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test); | 1110 | void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test); |
1111 | void ath9k_hw_setopmode(struct ath_hw *ah); | 1111 | void ath9k_hw_setopmode(struct ath_hw *ah); |
1112 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); | 1112 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); |
1113 | void ath9k_hw_setbssidmask(struct ath_hw *ah); | ||
1114 | void ath9k_hw_write_associd(struct ath_hw *ah); | 1113 | void ath9k_hw_write_associd(struct ath_hw *ah); |
1115 | u32 ath9k_hw_gettsf32(struct ath_hw *ah); | 1114 | u32 ath9k_hw_gettsf32(struct ath_hw *ah); |
1116 | u64 ath9k_hw_gettsf64(struct ath_hw *ah); | 1115 | u64 ath9k_hw_gettsf64(struct ath_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e9711e2b48c6..41b72faca77f 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -258,6 +258,8 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
258 | 258 | ||
259 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) | 259 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) |
260 | max_streams = 1; | 260 | max_streams = 1; |
261 | else if (AR_SREV_9462(ah)) | ||
262 | max_streams = 2; | ||
261 | else if (AR_SREV_9300_20_OR_LATER(ah)) | 263 | else if (AR_SREV_9300_20_OR_LATER(ah)) |
262 | max_streams = 3; | 264 | max_streams = 3; |
263 | else | 265 | else |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index fd59c1f25c43..5007297c9447 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -118,7 +118,7 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
118 | if (--sc->ps_usecount != 0) | 118 | if (--sc->ps_usecount != 0) |
119 | goto unlock; | 119 | goto unlock; |
120 | 120 | ||
121 | if (sc->ps_idle) | 121 | if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) |
122 | mode = ATH9K_PM_FULL_SLEEP; | 122 | mode = ATH9K_PM_FULL_SLEEP; |
123 | else if (sc->ps_enabled && | 123 | else if (sc->ps_enabled && |
124 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | | 124 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
@@ -332,7 +332,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
332 | hchan = ah->curchan; | 332 | hchan = ah->curchan; |
333 | } | 333 | } |
334 | 334 | ||
335 | if (fastcc && !ath9k_hw_check_alive(ah)) | 335 | if (fastcc && (ah->chip_fullsleep || |
336 | !ath9k_hw_check_alive(ah))) | ||
336 | fastcc = false; | 337 | fastcc = false; |
337 | 338 | ||
338 | if (!ath_prepare_reset(sc, retry_tx, flush)) | 339 | if (!ath_prepare_reset(sc, retry_tx, flush)) |
@@ -561,7 +562,6 @@ void ath_ani_calibrate(unsigned long data) | |||
561 | /* Long calibration runs independently of short calibration. */ | 562 | /* Long calibration runs independently of short calibration. */ |
562 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { | 563 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { |
563 | longcal = true; | 564 | longcal = true; |
564 | ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | ||
565 | common->ani.longcal_timer = timestamp; | 565 | common->ani.longcal_timer = timestamp; |
566 | } | 566 | } |
567 | 567 | ||
@@ -569,8 +569,6 @@ void ath_ani_calibrate(unsigned long data) | |||
569 | if (!common->ani.caldone) { | 569 | if (!common->ani.caldone) { |
570 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { | 570 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { |
571 | shortcal = true; | 571 | shortcal = true; |
572 | ath_dbg(common, ATH_DBG_ANI, | ||
573 | "shortcal @%lu\n", jiffies); | ||
574 | common->ani.shortcal_timer = timestamp; | 572 | common->ani.shortcal_timer = timestamp; |
575 | common->ani.resetcal_timer = timestamp; | 573 | common->ani.resetcal_timer = timestamp; |
576 | } | 574 | } |
@@ -584,8 +582,9 @@ void ath_ani_calibrate(unsigned long data) | |||
584 | } | 582 | } |
585 | 583 | ||
586 | /* Verify whether we must check ANI */ | 584 | /* Verify whether we must check ANI */ |
587 | if ((timestamp - common->ani.checkani_timer) >= | 585 | if (sc->sc_ah->config.enable_ani |
588 | ah->config.ani_poll_interval) { | 586 | && (timestamp - common->ani.checkani_timer) >= |
587 | ah->config.ani_poll_interval) { | ||
589 | aniflag = true; | 588 | aniflag = true; |
590 | common->ani.checkani_timer = timestamp; | 589 | common->ani.checkani_timer = timestamp; |
591 | } | 590 | } |
@@ -605,6 +604,11 @@ void ath_ani_calibrate(unsigned long data) | |||
605 | ah->rxchainmask, longcal); | 604 | ah->rxchainmask, longcal); |
606 | } | 605 | } |
607 | 606 | ||
607 | ath_dbg(common, ATH_DBG_ANI, | ||
608 | "Calibration @%lu finished: %s %s %s, caldone: %s\n", jiffies, | ||
609 | longcal ? "long" : "", shortcal ? "short" : "", | ||
610 | aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); | ||
611 | |||
608 | ath9k_ps_restore(sc); | 612 | ath9k_ps_restore(sc); |
609 | 613 | ||
610 | set_timer: | 614 | set_timer: |
@@ -886,82 +890,6 @@ chip_reset: | |||
886 | #undef SCHED_INTR | 890 | #undef SCHED_INTR |
887 | } | 891 | } |
888 | 892 | ||
889 | static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
890 | { | ||
891 | struct ath_hw *ah = sc->sc_ah; | ||
892 | struct ath_common *common = ath9k_hw_common(ah); | ||
893 | struct ieee80211_channel *channel = hw->conf.channel; | ||
894 | int r; | ||
895 | |||
896 | ath9k_ps_wakeup(sc); | ||
897 | spin_lock_bh(&sc->sc_pcu_lock); | ||
898 | atomic_set(&ah->intr_ref_cnt, -1); | ||
899 | |||
900 | ath9k_hw_configpcipowersave(ah, false); | ||
901 | |||
902 | if (!ah->curchan) | ||
903 | ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah); | ||
904 | |||
905 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | ||
906 | if (r) { | ||
907 | ath_err(common, | ||
908 | "Unable to reset channel (%u MHz), reset status %d\n", | ||
909 | channel->center_freq, r); | ||
910 | } | ||
911 | |||
912 | ath_complete_reset(sc, true); | ||
913 | |||
914 | /* Enable LED */ | ||
915 | ath9k_hw_cfg_output(ah, ah->led_pin, | ||
916 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
917 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); | ||
918 | |||
919 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
920 | |||
921 | ath9k_ps_restore(sc); | ||
922 | } | ||
923 | |||
924 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
925 | { | ||
926 | struct ath_hw *ah = sc->sc_ah; | ||
927 | struct ieee80211_channel *channel = hw->conf.channel; | ||
928 | int r; | ||
929 | |||
930 | ath9k_ps_wakeup(sc); | ||
931 | |||
932 | ath_cancel_work(sc); | ||
933 | |||
934 | spin_lock_bh(&sc->sc_pcu_lock); | ||
935 | |||
936 | /* | ||
937 | * Keep the LED on when the radio is disabled | ||
938 | * during idle unassociated state. | ||
939 | */ | ||
940 | if (!sc->ps_idle) { | ||
941 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); | ||
942 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); | ||
943 | } | ||
944 | |||
945 | ath_prepare_reset(sc, false, true); | ||
946 | |||
947 | if (!ah->curchan) | ||
948 | ah->curchan = ath9k_cmn_get_curchannel(hw, ah); | ||
949 | |||
950 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | ||
951 | if (r) { | ||
952 | ath_err(ath9k_hw_common(sc->sc_ah), | ||
953 | "Unable to reset channel (%u MHz), reset status %d\n", | ||
954 | channel->center_freq, r); | ||
955 | } | ||
956 | |||
957 | ath9k_hw_phy_disable(ah); | ||
958 | |||
959 | ath9k_hw_configpcipowersave(ah, true); | ||
960 | |||
961 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
962 | ath9k_ps_restore(sc); | ||
963 | } | ||
964 | |||
965 | static int ath_reset(struct ath_softc *sc, bool retry_tx) | 893 | static int ath_reset(struct ath_softc *sc, bool retry_tx) |
966 | { | 894 | { |
967 | int r; | 895 | int r; |
@@ -1097,6 +1025,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1097 | * and then setup of the interrupt mask. | 1025 | * and then setup of the interrupt mask. |
1098 | */ | 1026 | */ |
1099 | spin_lock_bh(&sc->sc_pcu_lock); | 1027 | spin_lock_bh(&sc->sc_pcu_lock); |
1028 | |||
1029 | atomic_set(&ah->intr_ref_cnt, -1); | ||
1030 | |||
1100 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); | 1031 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
1101 | if (r) { | 1032 | if (r) { |
1102 | ath_err(common, | 1033 | ath_err(common, |
@@ -1138,6 +1069,18 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1138 | goto mutex_unlock; | 1069 | goto mutex_unlock; |
1139 | } | 1070 | } |
1140 | 1071 | ||
1072 | if (ah->led_pin >= 0) { | ||
1073 | ath9k_hw_cfg_output(ah, ah->led_pin, | ||
1074 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1075 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); | ||
1076 | } | ||
1077 | |||
1078 | /* | ||
1079 | * Reset key cache to sane defaults (all entries cleared) instead of | ||
1080 | * semi-random values after suspend/resume. | ||
1081 | */ | ||
1082 | ath9k_cmn_init_crypto(sc->sc_ah); | ||
1083 | |||
1141 | spin_unlock_bh(&sc->sc_pcu_lock); | 1084 | spin_unlock_bh(&sc->sc_pcu_lock); |
1142 | 1085 | ||
1143 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && | 1086 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && |
@@ -1183,6 +1126,13 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1183 | } | 1126 | } |
1184 | } | 1127 | } |
1185 | 1128 | ||
1129 | /* | ||
1130 | * Cannot tx while the hardware is in full sleep, it first needs a full | ||
1131 | * chip reset to recover from that | ||
1132 | */ | ||
1133 | if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) | ||
1134 | goto exit; | ||
1135 | |||
1186 | if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) { | 1136 | if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) { |
1187 | /* | 1137 | /* |
1188 | * We are using PS-Poll and mac80211 can request TX while in | 1138 | * We are using PS-Poll and mac80211 can request TX while in |
@@ -1229,6 +1179,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1229 | struct ath_softc *sc = hw->priv; | 1179 | struct ath_softc *sc = hw->priv; |
1230 | struct ath_hw *ah = sc->sc_ah; | 1180 | struct ath_hw *ah = sc->sc_ah; |
1231 | struct ath_common *common = ath9k_hw_common(ah); | 1181 | struct ath_common *common = ath9k_hw_common(ah); |
1182 | bool prev_idle; | ||
1232 | 1183 | ||
1233 | mutex_lock(&sc->mutex); | 1184 | mutex_lock(&sc->mutex); |
1234 | 1185 | ||
@@ -1259,35 +1210,45 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1259 | * before setting the invalid flag. */ | 1210 | * before setting the invalid flag. */ |
1260 | ath9k_hw_disable_interrupts(ah); | 1211 | ath9k_hw_disable_interrupts(ah); |
1261 | 1212 | ||
1262 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 1213 | spin_unlock_bh(&sc->sc_pcu_lock); |
1263 | ath_drain_all_txq(sc, false); | 1214 | |
1264 | ath_stoprecv(sc); | 1215 | /* we can now sync irq and kill any running tasklets, since we already |
1265 | ath9k_hw_phy_disable(ah); | 1216 | * disabled interrupts and not holding a spin lock */ |
1266 | } else | 1217 | synchronize_irq(sc->irq); |
1267 | sc->rx.rxlink = NULL; | 1218 | tasklet_kill(&sc->intr_tq); |
1219 | tasklet_kill(&sc->bcon_tasklet); | ||
1220 | |||
1221 | prev_idle = sc->ps_idle; | ||
1222 | sc->ps_idle = true; | ||
1223 | |||
1224 | spin_lock_bh(&sc->sc_pcu_lock); | ||
1225 | |||
1226 | if (ah->led_pin >= 0) { | ||
1227 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); | ||
1228 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); | ||
1229 | } | ||
1230 | |||
1231 | ath_prepare_reset(sc, false, true); | ||
1268 | 1232 | ||
1269 | if (sc->rx.frag) { | 1233 | if (sc->rx.frag) { |
1270 | dev_kfree_skb_any(sc->rx.frag); | 1234 | dev_kfree_skb_any(sc->rx.frag); |
1271 | sc->rx.frag = NULL; | 1235 | sc->rx.frag = NULL; |
1272 | } | 1236 | } |
1273 | 1237 | ||
1274 | /* disable HAL and put h/w to sleep */ | 1238 | if (!ah->curchan) |
1275 | ath9k_hw_disable(ah); | 1239 | ah->curchan = ath9k_cmn_get_curchannel(hw, ah); |
1276 | 1240 | ||
1277 | spin_unlock_bh(&sc->sc_pcu_lock); | 1241 | ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
1242 | ath9k_hw_phy_disable(ah); | ||
1278 | 1243 | ||
1279 | /* we can now sync irq and kill any running tasklets, since we already | 1244 | ath9k_hw_configpcipowersave(ah, true); |
1280 | * disabled interrupts and not holding a spin lock */ | ||
1281 | synchronize_irq(sc->irq); | ||
1282 | tasklet_kill(&sc->intr_tq); | ||
1283 | tasklet_kill(&sc->bcon_tasklet); | ||
1284 | 1245 | ||
1285 | ath9k_ps_restore(sc); | 1246 | spin_unlock_bh(&sc->sc_pcu_lock); |
1286 | 1247 | ||
1287 | sc->ps_idle = true; | 1248 | ath9k_ps_restore(sc); |
1288 | ath_radio_disable(sc, hw); | ||
1289 | 1249 | ||
1290 | sc->sc_flags |= SC_OP_INVALID; | 1250 | sc->sc_flags |= SC_OP_INVALID; |
1251 | sc->ps_idle = prev_idle; | ||
1291 | 1252 | ||
1292 | mutex_unlock(&sc->mutex); | 1253 | mutex_unlock(&sc->mutex); |
1293 | 1254 | ||
@@ -1627,8 +1588,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1627 | struct ath_hw *ah = sc->sc_ah; | 1588 | struct ath_hw *ah = sc->sc_ah; |
1628 | struct ath_common *common = ath9k_hw_common(ah); | 1589 | struct ath_common *common = ath9k_hw_common(ah); |
1629 | struct ieee80211_conf *conf = &hw->conf; | 1590 | struct ieee80211_conf *conf = &hw->conf; |
1630 | bool disable_radio = false; | ||
1631 | 1591 | ||
1592 | ath9k_ps_wakeup(sc); | ||
1632 | mutex_lock(&sc->mutex); | 1593 | mutex_lock(&sc->mutex); |
1633 | 1594 | ||
1634 | /* | 1595 | /* |
@@ -1639,13 +1600,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1639 | */ | 1600 | */ |
1640 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 1601 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
1641 | sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); | 1602 | sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); |
1642 | if (!sc->ps_idle) { | 1603 | if (sc->ps_idle) |
1643 | ath_radio_enable(sc, hw); | 1604 | ath_cancel_work(sc); |
1644 | ath_dbg(common, ATH_DBG_CONFIG, | ||
1645 | "not-idle: enabling radio\n"); | ||
1646 | } else { | ||
1647 | disable_radio = true; | ||
1648 | } | ||
1649 | } | 1605 | } |
1650 | 1606 | ||
1651 | /* | 1607 | /* |
@@ -1752,18 +1708,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1752 | ath_dbg(common, ATH_DBG_CONFIG, | 1708 | ath_dbg(common, ATH_DBG_CONFIG, |
1753 | "Set power: %d\n", conf->power_level); | 1709 | "Set power: %d\n", conf->power_level); |
1754 | sc->config.txpowlimit = 2 * conf->power_level; | 1710 | sc->config.txpowlimit = 2 * conf->power_level; |
1755 | ath9k_ps_wakeup(sc); | ||
1756 | ath9k_cmn_update_txpow(ah, sc->curtxpow, | 1711 | ath9k_cmn_update_txpow(ah, sc->curtxpow, |
1757 | sc->config.txpowlimit, &sc->curtxpow); | 1712 | sc->config.txpowlimit, &sc->curtxpow); |
1758 | ath9k_ps_restore(sc); | ||
1759 | } | ||
1760 | |||
1761 | if (disable_radio) { | ||
1762 | ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); | ||
1763 | ath_radio_disable(sc, hw); | ||
1764 | } | 1713 | } |
1765 | 1714 | ||
1766 | mutex_unlock(&sc->mutex); | 1715 | mutex_unlock(&sc->mutex); |
1716 | ath9k_ps_restore(sc); | ||
1767 | 1717 | ||
1768 | return 0; | 1718 | return 0; |
1769 | } | 1719 | } |
@@ -2331,9 +2281,6 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2331 | return; | 2281 | return; |
2332 | } | 2282 | } |
2333 | 2283 | ||
2334 | if (drop) | ||
2335 | timeout = 1; | ||
2336 | |||
2337 | for (j = 0; j < timeout; j++) { | 2284 | for (j = 0; j < timeout; j++) { |
2338 | bool npend = false; | 2285 | bool npend = false; |
2339 | 2286 | ||
@@ -2351,21 +2298,22 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2351 | } | 2298 | } |
2352 | 2299 | ||
2353 | if (!npend) | 2300 | if (!npend) |
2354 | goto out; | 2301 | break; |
2355 | } | 2302 | } |
2356 | 2303 | ||
2357 | ath9k_ps_wakeup(sc); | 2304 | if (drop) { |
2358 | spin_lock_bh(&sc->sc_pcu_lock); | 2305 | ath9k_ps_wakeup(sc); |
2359 | drain_txq = ath_drain_all_txq(sc, false); | 2306 | spin_lock_bh(&sc->sc_pcu_lock); |
2360 | spin_unlock_bh(&sc->sc_pcu_lock); | 2307 | drain_txq = ath_drain_all_txq(sc, false); |
2308 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
2361 | 2309 | ||
2362 | if (!drain_txq) | 2310 | if (!drain_txq) |
2363 | ath_reset(sc, false); | 2311 | ath_reset(sc, false); |
2364 | 2312 | ||
2365 | ath9k_ps_restore(sc); | 2313 | ath9k_ps_restore(sc); |
2366 | ieee80211_wake_queues(hw); | 2314 | ieee80211_wake_queues(hw); |
2315 | } | ||
2367 | 2316 | ||
2368 | out: | ||
2369 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); | 2317 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); |
2370 | mutex_unlock(&sc->mutex); | 2318 | mutex_unlock(&sc->mutex); |
2371 | } | 2319 | } |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 2dcdf63cb390..a439edc5dc06 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -307,12 +307,11 @@ static int ath_pci_suspend(struct device *device) | |||
307 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 307 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
308 | struct ath_softc *sc = hw->priv; | 308 | struct ath_softc *sc = hw->priv; |
309 | 309 | ||
310 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | ||
311 | |||
312 | /* The device has to be moved to FULLSLEEP forcibly. | 310 | /* The device has to be moved to FULLSLEEP forcibly. |
313 | * Otherwise the chip never moved to full sleep, | 311 | * Otherwise the chip never moved to full sleep, |
314 | * when no interface is up. | 312 | * when no interface is up. |
315 | */ | 313 | */ |
314 | ath9k_hw_disable(sc->sc_ah); | ||
316 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); | 315 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); |
317 | 316 | ||
318 | return 0; | 317 | return 0; |
@@ -321,8 +320,6 @@ static int ath_pci_suspend(struct device *device) | |||
321 | static int ath_pci_resume(struct device *device) | 320 | static int ath_pci_resume(struct device *device) |
322 | { | 321 | { |
323 | struct pci_dev *pdev = to_pci_dev(device); | 322 | struct pci_dev *pdev = to_pci_dev(device); |
324 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
325 | struct ath_softc *sc = hw->priv; | ||
326 | u32 val; | 323 | u32 val; |
327 | 324 | ||
328 | /* | 325 | /* |
@@ -334,22 +331,6 @@ static int ath_pci_resume(struct device *device) | |||
334 | if ((val & 0x0000ff00) != 0) | 331 | if ((val & 0x0000ff00) != 0) |
335 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | 332 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); |
336 | 333 | ||
337 | ath9k_ps_wakeup(sc); | ||
338 | /* Enable LED */ | ||
339 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, | ||
340 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
341 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); | ||
342 | |||
343 | /* | ||
344 | * Reset key cache to sane defaults (all entries cleared) instead of | ||
345 | * semi-random values after suspend/resume. | ||
346 | */ | ||
347 | ath9k_cmn_init_crypto(sc->sc_ah); | ||
348 | ath9k_ps_restore(sc); | ||
349 | |||
350 | sc->ps_idle = true; | ||
351 | ath_radio_disable(sc, hw); | ||
352 | |||
353 | return 0; | 334 | return 0; |
354 | } | 335 | } |
355 | 336 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 80639e3e4ac9..9e65c3198ca7 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1954,7 +1954,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1954 | skb_pull(skb, padsize); | 1954 | skb_pull(skb, padsize); |
1955 | } | 1955 | } |
1956 | 1956 | ||
1957 | if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { | 1957 | if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { |
1958 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; | 1958 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; |
1959 | ath_dbg(common, ATH_DBG_PS, | 1959 | ath_dbg(common, ATH_DBG_PS, |
1960 | "Going back to sleep after having received TX status (0x%lx)\n", | 1960 | "Going back to sleep after having received TX status (0x%lx)\n", |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 7e2924f332a7..881ba043770a 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -2786,9 +2786,8 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) | |||
2786 | /* Driver ilate data, only for Tx (not command) queues, | 2786 | /* Driver ilate data, only for Tx (not command) queues, |
2787 | * not shared with device. */ | 2787 | * not shared with device. */ |
2788 | if (id != il->cmd_queue) { | 2788 | if (id != il->cmd_queue) { |
2789 | txq->txb = | 2789 | txq->txb = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->txb[0]), |
2790 | kzalloc(sizeof(txq->txb[0]) * TFD_QUEUE_SIZE_MAX, | 2790 | GFP_KERNEL); |
2791 | GFP_KERNEL); | ||
2792 | if (!txq->txb) { | 2791 | if (!txq->txb) { |
2793 | IL_ERR("kmalloc for auxiliary BD " | 2792 | IL_ERR("kmalloc for auxiliary BD " |
2794 | "structures failed\n"); | 2793 | "structures failed\n"); |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index a7ab280994c8..86344cefd32f 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # WIFI | 1 | # WIFI |
2 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o | 2 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o |
3 | iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o | 3 | iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o |
4 | iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o | 4 | iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o |
5 | iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o | 5 | iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o |
6 | iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o | 6 | iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o |
7 | 7 | ||
@@ -18,7 +18,7 @@ iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o | |||
18 | 18 | ||
19 | iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 19 | iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
20 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 20 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
21 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-sv-open.o | 21 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-testmode.o |
22 | 22 | ||
23 | CFLAGS_iwl-devtrace.o := -I$(src) | 23 | CFLAGS_iwl-devtrace.o := -I$(src) |
24 | 24 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index bc9bbbb2b494..8d3bad7ea5d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -182,6 +182,7 @@ static struct iwl_base_params iwl1000_base_params = { | |||
182 | .chain_noise_scale = 1000, | 182 | .chain_noise_scale = 1000, |
183 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 183 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
184 | .max_event_log_size = 128, | 184 | .max_event_log_size = 128, |
185 | .wd_disable = true, | ||
185 | }; | 186 | }; |
186 | static struct iwl_ht_params iwl1000_ht_params = { | 187 | static struct iwl_ht_params iwl1000_ht_params = { |
187 | .ht_greenfield_support = true, | 188 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 3a3f83032382..cf2fb47529b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -350,6 +350,7 @@ static struct iwl_base_params iwl5000_base_params = { | |||
350 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 350 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
351 | .max_event_log_size = 512, | 351 | .max_event_log_size = 512, |
352 | .no_idle_support = true, | 352 | .no_idle_support = true, |
353 | .wd_disable = true, | ||
353 | }; | 354 | }; |
354 | static struct iwl_ht_params iwl5000_ht_params = { | 355 | static struct iwl_ht_params iwl5000_ht_params = { |
355 | .ht_greenfield_support = true, | 356 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 0bc962217351..575d1bb8e8cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -934,57 +934,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) | |||
934 | return ant; | 934 | return ant; |
935 | } | 935 | } |
936 | 936 | ||
937 | /* notification wait support */ | ||
938 | void iwlagn_init_notification_wait(struct iwl_priv *priv, | ||
939 | struct iwl_notification_wait *wait_entry, | ||
940 | u8 cmd, | ||
941 | void (*fn)(struct iwl_priv *priv, | ||
942 | struct iwl_rx_packet *pkt, | ||
943 | void *data), | ||
944 | void *fn_data) | ||
945 | { | ||
946 | wait_entry->fn = fn; | ||
947 | wait_entry->fn_data = fn_data; | ||
948 | wait_entry->cmd = cmd; | ||
949 | wait_entry->triggered = false; | ||
950 | wait_entry->aborted = false; | ||
951 | |||
952 | spin_lock_bh(&priv->notif_wait_lock); | ||
953 | list_add(&wait_entry->list, &priv->notif_waits); | ||
954 | spin_unlock_bh(&priv->notif_wait_lock); | ||
955 | } | ||
956 | |||
957 | int iwlagn_wait_notification(struct iwl_priv *priv, | ||
958 | struct iwl_notification_wait *wait_entry, | ||
959 | unsigned long timeout) | ||
960 | { | ||
961 | int ret; | ||
962 | |||
963 | ret = wait_event_timeout(priv->notif_waitq, | ||
964 | wait_entry->triggered || wait_entry->aborted, | ||
965 | timeout); | ||
966 | |||
967 | spin_lock_bh(&priv->notif_wait_lock); | ||
968 | list_del(&wait_entry->list); | ||
969 | spin_unlock_bh(&priv->notif_wait_lock); | ||
970 | |||
971 | if (wait_entry->aborted) | ||
972 | return -EIO; | ||
973 | |||
974 | /* return value is always >= 0 */ | ||
975 | if (ret <= 0) | ||
976 | return -ETIMEDOUT; | ||
977 | return 0; | ||
978 | } | ||
979 | |||
980 | void iwlagn_remove_notification(struct iwl_priv *priv, | ||
981 | struct iwl_notification_wait *wait_entry) | ||
982 | { | ||
983 | spin_lock_bh(&priv->notif_wait_lock); | ||
984 | list_del(&wait_entry->list); | ||
985 | spin_unlock_bh(&priv->notif_wait_lock); | ||
986 | } | ||
987 | |||
988 | #ifdef CONFIG_PM_SLEEP | 937 | #ifdef CONFIG_PM_SLEEP |
989 | static void iwlagn_convert_p1k(u16 *p1k, __le16 *out) | 938 | static void iwlagn_convert_p1k(u16 *p1k, __le16 *out) |
990 | { | 939 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 087fd52e5727..90c55ea4cc39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -1131,9 +1131,9 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1131 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | 1131 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; |
1132 | 1132 | ||
1133 | /* set up notification wait support */ | 1133 | /* set up notification wait support */ |
1134 | spin_lock_init(&priv->notif_wait_lock); | 1134 | spin_lock_init(&priv->shrd->notif_wait_lock); |
1135 | INIT_LIST_HEAD(&priv->notif_waits); | 1135 | INIT_LIST_HEAD(&priv->shrd->notif_waits); |
1136 | init_waitqueue_head(&priv->notif_waitq); | 1136 | init_waitqueue_head(&priv->shrd->notif_waitq); |
1137 | 1137 | ||
1138 | /* Set up BT Rx handlers */ | 1138 | /* Set up BT Rx handlers */ |
1139 | if (priv->cfg->lib->bt_rx_handler_setup) | 1139 | if (priv->cfg->lib->bt_rx_handler_setup) |
@@ -1152,11 +1152,11 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1152 | * even if the RX handler consumes the RXB we have | 1152 | * even if the RX handler consumes the RXB we have |
1153 | * access to it in the notification wait entry. | 1153 | * access to it in the notification wait entry. |
1154 | */ | 1154 | */ |
1155 | if (!list_empty(&priv->notif_waits)) { | 1155 | if (!list_empty(&priv->shrd->notif_waits)) { |
1156 | struct iwl_notification_wait *w; | 1156 | struct iwl_notification_wait *w; |
1157 | 1157 | ||
1158 | spin_lock(&priv->notif_wait_lock); | 1158 | spin_lock(&priv->shrd->notif_wait_lock); |
1159 | list_for_each_entry(w, &priv->notif_waits, list) { | 1159 | list_for_each_entry(w, &priv->shrd->notif_waits, list) { |
1160 | if (w->cmd != pkt->hdr.cmd) | 1160 | if (w->cmd != pkt->hdr.cmd) |
1161 | continue; | 1161 | continue; |
1162 | IWL_DEBUG_RX(priv, | 1162 | IWL_DEBUG_RX(priv, |
@@ -1167,9 +1167,9 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1167 | if (w->fn) | 1167 | if (w->fn) |
1168 | w->fn(priv, pkt, w->fn_data); | 1168 | w->fn(priv, pkt, w->fn_data); |
1169 | } | 1169 | } |
1170 | spin_unlock(&priv->notif_wait_lock); | 1170 | spin_unlock(&priv->shrd->notif_wait_lock); |
1171 | 1171 | ||
1172 | wake_up_all(&priv->notif_waitq); | 1172 | wake_up_all(&priv->shrd->notif_waitq); |
1173 | } | 1173 | } |
1174 | 1174 | ||
1175 | if (priv->pre_rx_handler) | 1175 | if (priv->pre_rx_handler) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 8de97f5a1825..466e4ab544f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -60,7 +60,7 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
60 | u8 old_dev_type = send->dev_type; | 60 | u8 old_dev_type = send->dev_type; |
61 | int ret; | 61 | int ret; |
62 | 62 | ||
63 | iwlagn_init_notification_wait(priv, &disable_wait, | 63 | iwl_init_notification_wait(priv->shrd, &disable_wait, |
64 | REPLY_WIPAN_DEACTIVATION_COMPLETE, | 64 | REPLY_WIPAN_DEACTIVATION_COMPLETE, |
65 | NULL, NULL); | 65 | NULL, NULL); |
66 | 66 | ||
@@ -74,9 +74,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
74 | 74 | ||
75 | if (ret) { | 75 | if (ret) { |
76 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); | 76 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); |
77 | iwlagn_remove_notification(priv, &disable_wait); | 77 | iwl_remove_notification(priv->shrd, &disable_wait); |
78 | } else { | 78 | } else { |
79 | ret = iwlagn_wait_notification(priv, &disable_wait, HZ); | 79 | ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ); |
80 | if (ret) | 80 | if (ret) |
81 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); | 81 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); |
82 | } | 82 | } |
@@ -529,6 +529,24 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
529 | return 0; | 529 | return 0; |
530 | } | 530 | } |
531 | 531 | ||
532 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
533 | struct iwl_rxon_context *ctx) | ||
534 | { | ||
535 | if (conf_is_ht40_minus(conf)) { | ||
536 | ctx->ht.extension_chan_offset = | ||
537 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
538 | ctx->ht.is_40mhz = true; | ||
539 | } else if (conf_is_ht40_plus(conf)) { | ||
540 | ctx->ht.extension_chan_offset = | ||
541 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
542 | ctx->ht.is_40mhz = true; | ||
543 | } else { | ||
544 | ctx->ht.extension_chan_offset = | ||
545 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
546 | ctx->ht.is_40mhz = false; | ||
547 | } | ||
548 | } | ||
549 | |||
532 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | 550 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) |
533 | { | 551 | { |
534 | struct iwl_priv *priv = hw->priv; | 552 | struct iwl_priv *priv = hw->priv; |
@@ -590,19 +608,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
590 | ctx->ht.enabled = conf_is_ht(conf); | 608 | ctx->ht.enabled = conf_is_ht(conf); |
591 | 609 | ||
592 | if (ctx->ht.enabled) { | 610 | if (ctx->ht.enabled) { |
593 | if (conf_is_ht40_minus(conf)) { | 611 | /* if HT40 is used, it should not change |
594 | ctx->ht.extension_chan_offset = | 612 | * after associated except channel switch */ |
595 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | 613 | if (iwl_is_associated_ctx(ctx) && |
596 | ctx->ht.is_40mhz = true; | 614 | !ctx->ht.is_40mhz) |
597 | } else if (conf_is_ht40_plus(conf)) { | 615 | iwlagn_config_ht40(conf, ctx); |
598 | ctx->ht.extension_chan_offset = | ||
599 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
600 | ctx->ht.is_40mhz = true; | ||
601 | } else { | ||
602 | ctx->ht.extension_chan_offset = | ||
603 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
604 | ctx->ht.is_40mhz = false; | ||
605 | } | ||
606 | } else | 616 | } else |
607 | ctx->ht.is_40mhz = false; | 617 | ctx->ht.is_40mhz = false; |
608 | 618 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 901fd9485d75..626ed701100e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -1250,9 +1250,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
1250 | 1250 | ||
1251 | switch (keyconf->cipher) { | 1251 | switch (keyconf->cipher) { |
1252 | case WLAN_CIPHER_SUITE_TKIP: | 1252 | case WLAN_CIPHER_SUITE_TKIP: |
1253 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
1254 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1255 | |||
1256 | if (sta) | 1253 | if (sta) |
1257 | addr = sta->addr; | 1254 | addr = sta->addr; |
1258 | else /* station mode case only */ | 1255 | else /* station mode case only */ |
@@ -1265,8 +1262,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
1265 | seq.tkip.iv32, p1k, CMD_SYNC); | 1262 | seq.tkip.iv32, p1k, CMD_SYNC); |
1266 | break; | 1263 | break; |
1267 | case WLAN_CIPHER_SUITE_CCMP: | 1264 | case WLAN_CIPHER_SUITE_CCMP: |
1268 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1269 | /* fall through */ | ||
1270 | case WLAN_CIPHER_SUITE_WEP40: | 1265 | case WLAN_CIPHER_SUITE_WEP40: |
1271 | case WLAN_CIPHER_SUITE_WEP104: | 1266 | case WLAN_CIPHER_SUITE_WEP104: |
1272 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, | 1267 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index db0d3a84b1e4..daf010dad70c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1232,14 +1232,14 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
1232 | priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; | 1232 | priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; |
1233 | priv->cur_rssi_ctx = NULL; | 1233 | priv->cur_rssi_ctx = NULL; |
1234 | 1234 | ||
1235 | iwlagn_send_prio_tbl(priv); | 1235 | iwl_send_prio_tbl(trans(priv)); |
1236 | 1236 | ||
1237 | /* FIXME: w/a to force change uCode BT state machine */ | 1237 | /* FIXME: w/a to force change uCode BT state machine */ |
1238 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | 1238 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN, |
1239 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 1239 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
1240 | if (ret) | 1240 | if (ret) |
1241 | return ret; | 1241 | return ret; |
1242 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, | 1242 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_CLOSE, |
1243 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 1243 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
1244 | if (ret) | 1244 | if (ret) |
1245 | return ret; | 1245 | return ret; |
@@ -2022,9 +2022,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | |||
2022 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); | 2022 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); |
2023 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); | 2023 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); |
2024 | 2024 | ||
2025 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); | 2025 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); |
2026 | MODULE_PARM_DESC(wd_disable, | 2026 | MODULE_PARM_DESC(wd_disable, |
2027 | "Disable stuck queue watchdog timer (default: 0 [enabled])"); | 2027 | "Disable stuck queue watchdog timer 0=system default, " |
2028 | "1=disable, 2=enable (default: 0)"); | ||
2028 | 2029 | ||
2029 | /* | 2030 | /* |
2030 | * set bt_coex_active to true, uCode will do kill/defer | 2031 | * set bt_coex_active to true, uCode will do kill/defer |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5d8d2f445923..f2f10702754d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -101,13 +101,15 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
101 | struct ieee80211_vif *vif, | 101 | struct ieee80211_vif *vif, |
102 | struct ieee80211_bss_conf *bss_conf, | 102 | struct ieee80211_bss_conf *bss_conf, |
103 | u32 changes); | 103 | u32 changes); |
104 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
105 | struct iwl_rxon_context *ctx); | ||
104 | 106 | ||
105 | /* uCode */ | 107 | /* uCode */ |
106 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 108 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
107 | struct iwl_rx_mem_buffer *rxb, | 109 | struct iwl_rx_mem_buffer *rxb, |
108 | struct iwl_device_cmd *cmd); | 110 | struct iwl_device_cmd *cmd); |
109 | int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | 111 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); |
110 | void iwlagn_send_prio_tbl(struct iwl_priv *priv); | 112 | void iwl_send_prio_tbl(struct iwl_trans *trans); |
111 | int iwlagn_run_init_ucode(struct iwl_priv *priv); | 113 | int iwlagn_run_init_ucode(struct iwl_priv *priv); |
112 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 114 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, |
113 | enum iwl_ucode_type ucode_type); | 115 | enum iwl_ucode_type ucode_type); |
@@ -354,22 +356,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
354 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); | 356 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); |
355 | void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); | 357 | void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); |
356 | 358 | ||
357 | /* notification wait support */ | ||
358 | void __acquires(wait_entry) | ||
359 | iwlagn_init_notification_wait(struct iwl_priv *priv, | ||
360 | struct iwl_notification_wait *wait_entry, | ||
361 | u8 cmd, | ||
362 | void (*fn)(struct iwl_priv *priv, | ||
363 | struct iwl_rx_packet *pkt, | ||
364 | void *data), | ||
365 | void *fn_data); | ||
366 | int __must_check __releases(wait_entry) | ||
367 | iwlagn_wait_notification(struct iwl_priv *priv, | ||
368 | struct iwl_notification_wait *wait_entry, | ||
369 | unsigned long timeout); | ||
370 | void __releases(wait_entry) | ||
371 | iwlagn_remove_notification(struct iwl_priv *priv, | ||
372 | struct iwl_notification_wait *wait_entry); | ||
373 | extern int iwlagn_init_alive_start(struct iwl_priv *priv); | 359 | extern int iwlagn_init_alive_start(struct iwl_priv *priv); |
374 | extern int iwl_alive_start(struct iwl_priv *priv); | 360 | extern int iwl_alive_start(struct iwl_priv *priv); |
375 | /* svtool */ | 361 | /* svtool */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f9e9170e977a..3b6f48bfe0e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -836,19 +836,6 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
836 | } | 836 | } |
837 | #endif | 837 | #endif |
838 | 838 | ||
839 | static void iwlagn_abort_notification_waits(struct iwl_priv *priv) | ||
840 | { | ||
841 | unsigned long flags; | ||
842 | struct iwl_notification_wait *wait_entry; | ||
843 | |||
844 | spin_lock_irqsave(&priv->notif_wait_lock, flags); | ||
845 | list_for_each_entry(wait_entry, &priv->notif_waits, list) | ||
846 | wait_entry->aborted = true; | ||
847 | spin_unlock_irqrestore(&priv->notif_wait_lock, flags); | ||
848 | |||
849 | wake_up_all(&priv->notif_waitq); | ||
850 | } | ||
851 | |||
852 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | 839 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) |
853 | { | 840 | { |
854 | unsigned int reload_msec; | 841 | unsigned int reload_msec; |
@@ -860,7 +847,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
860 | /* Cancel currently queued command. */ | 847 | /* Cancel currently queued command. */ |
861 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); | 848 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); |
862 | 849 | ||
863 | iwlagn_abort_notification_waits(priv); | 850 | iwl_abort_notification_waits(priv->shrd); |
864 | 851 | ||
865 | /* Keep the restart process from trying to send host | 852 | /* Keep the restart process from trying to send host |
866 | * commands by clearing the ready bit */ | 853 | * commands by clearing the ready bit */ |
@@ -1505,11 +1492,23 @@ void iwl_setup_watchdog(struct iwl_priv *priv) | |||
1505 | { | 1492 | { |
1506 | unsigned int timeout = priv->cfg->base_params->wd_timeout; | 1493 | unsigned int timeout = priv->cfg->base_params->wd_timeout; |
1507 | 1494 | ||
1508 | if (timeout && !iwlagn_mod_params.wd_disable) | 1495 | if (!iwlagn_mod_params.wd_disable) { |
1509 | mod_timer(&priv->watchdog, | 1496 | /* use system default */ |
1510 | jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1497 | if (timeout && !priv->cfg->base_params->wd_disable) |
1511 | else | 1498 | mod_timer(&priv->watchdog, |
1512 | del_timer(&priv->watchdog); | 1499 | jiffies + |
1500 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
1501 | else | ||
1502 | del_timer(&priv->watchdog); | ||
1503 | } else { | ||
1504 | /* module parameter overwrite default configuration */ | ||
1505 | if (timeout && iwlagn_mod_params.wd_disable == 2) | ||
1506 | mod_timer(&priv->watchdog, | ||
1507 | jiffies + | ||
1508 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
1509 | else | ||
1510 | del_timer(&priv->watchdog); | ||
1511 | } | ||
1513 | } | 1512 | } |
1514 | 1513 | ||
1515 | /** | 1514 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f1d9d0c13e4c..6da53a36c1be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -113,6 +113,7 @@ struct iwl_lib_ops { | |||
113 | * @shadow_reg_enable: HW shadhow register bit | 113 | * @shadow_reg_enable: HW shadhow register bit |
114 | * @no_idle_support: do not support idle mode | 114 | * @no_idle_support: do not support idle mode |
115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | 115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up |
116 | * wd_disable: disable watchdog timer | ||
116 | */ | 117 | */ |
117 | struct iwl_base_params { | 118 | struct iwl_base_params { |
118 | int eeprom_size; | 119 | int eeprom_size; |
@@ -134,6 +135,7 @@ struct iwl_base_params { | |||
134 | const bool shadow_reg_enable; | 135 | const bool shadow_reg_enable; |
135 | const bool no_idle_support; | 136 | const bool no_idle_support; |
136 | const bool hd_v2; | 137 | const bool hd_v2; |
138 | const bool wd_disable; | ||
137 | }; | 139 | }; |
138 | /* | 140 | /* |
139 | * @advanced_bt_coexist: support advanced bt coexist | 141 | * @advanced_bt_coexist: support advanced bt coexist |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 44a7bdd7ccfd..f8fc2393dd4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -134,48 +134,43 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
134 | */ | 134 | */ |
135 | 135 | ||
136 | /* 0x0000000F - 0x00000001 */ | 136 | /* 0x0000000F - 0x00000001 */ |
137 | #define IWL_DL_INFO (1 << 0) | 137 | #define IWL_DL_INFO 0x00000001 |
138 | #define IWL_DL_MAC80211 (1 << 1) | 138 | #define IWL_DL_MAC80211 0x00000002 |
139 | #define IWL_DL_HCMD (1 << 2) | 139 | #define IWL_DL_HCMD 0x00000004 |
140 | #define IWL_DL_STATE (1 << 3) | 140 | #define IWL_DL_STATE 0x00000008 |
141 | /* 0x000000F0 - 0x00000010 */ | 141 | /* 0x000000F0 - 0x00000010 */ |
142 | #define IWL_DL_MACDUMP (1 << 4) | 142 | #define IWL_DL_EEPROM 0x00000040 |
143 | #define IWL_DL_HCMD_DUMP (1 << 5) | 143 | #define IWL_DL_RADIO 0x00000080 |
144 | #define IWL_DL_EEPROM (1 << 6) | ||
145 | #define IWL_DL_RADIO (1 << 7) | ||
146 | /* 0x00000F00 - 0x00000100 */ | 144 | /* 0x00000F00 - 0x00000100 */ |
147 | #define IWL_DL_POWER (1 << 8) | 145 | #define IWL_DL_POWER 0x00000100 |
148 | #define IWL_DL_TEMP (1 << 9) | 146 | #define IWL_DL_TEMP 0x00000200 |
149 | /* reserved (1 << 10) */ | 147 | #define IWL_DL_SCAN 0x00000800 |
150 | #define IWL_DL_SCAN (1 << 11) | ||
151 | /* 0x0000F000 - 0x00001000 */ | 148 | /* 0x0000F000 - 0x00001000 */ |
152 | #define IWL_DL_ASSOC (1 << 12) | 149 | #define IWL_DL_ASSOC 0x00001000 |
153 | #define IWL_DL_DROP (1 << 13) | 150 | #define IWL_DL_DROP 0x00002000 |
154 | /* reserved (1 << 14) */ | 151 | #define IWL_DL_COEX 0x00008000 |
155 | #define IWL_DL_COEX (1 << 15) | ||
156 | /* 0x000F0000 - 0x00010000 */ | 152 | /* 0x000F0000 - 0x00010000 */ |
157 | #define IWL_DL_FW (1 << 16) | 153 | #define IWL_DL_FW 0x00010000 |
158 | #define IWL_DL_RF_KILL (1 << 17) | 154 | #define IWL_DL_RF_KILL 0x00020000 |
159 | #define IWL_DL_FW_ERRORS (1 << 18) | 155 | #define IWL_DL_FW_ERRORS 0x00040000 |
160 | #define IWL_DL_LED (1 << 19) | 156 | #define IWL_DL_LED 0x00080000 |
161 | /* 0x00F00000 - 0x00100000 */ | 157 | /* 0x00F00000 - 0x00100000 */ |
162 | #define IWL_DL_RATE (1 << 20) | 158 | #define IWL_DL_RATE 0x00100000 |
163 | #define IWL_DL_CALIB (1 << 21) | 159 | #define IWL_DL_CALIB 0x00200000 |
164 | #define IWL_DL_WEP (1 << 22) | 160 | #define IWL_DL_WEP 0x00400000 |
165 | #define IWL_DL_TX (1 << 23) | 161 | #define IWL_DL_TX 0x00800000 |
166 | /* 0x0F000000 - 0x01000000 */ | 162 | /* 0x0F000000 - 0x01000000 */ |
167 | #define IWL_DL_RX (1 << 24) | 163 | #define IWL_DL_RX 0x01000000 |
168 | #define IWL_DL_ISR (1 << 25) | 164 | #define IWL_DL_ISR 0x02000000 |
169 | #define IWL_DL_HT (1 << 26) | 165 | #define IWL_DL_HT 0x04000000 |
170 | /* 0xF0000000 - 0x10000000 */ | 166 | /* 0xF0000000 - 0x10000000 */ |
171 | #define IWL_DL_11H (1 << 28) | 167 | #define IWL_DL_11H 0x10000000 |
172 | #define IWL_DL_STATS (1 << 29) | 168 | #define IWL_DL_STATS 0x20000000 |
173 | #define IWL_DL_TX_REPLY (1 << 30) | 169 | #define IWL_DL_TX_REPLY 0x40000000 |
174 | #define IWL_DL_TX_QUEUES (1 << 31) | 170 | #define IWL_DL_TX_QUEUES 0x80000000 |
175 | 171 | ||
176 | #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) | 172 | #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) |
177 | #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) | 173 | #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) |
178 | #define IWL_DEBUG_MACDUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_MACDUMP, f, ## a) | ||
179 | #define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a) | 174 | #define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a) |
180 | #define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a) | 175 | #define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a) |
181 | #define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a) | 176 | #define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a) |
@@ -184,7 +179,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
184 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) | 179 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) |
185 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) | 180 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) |
186 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) | 181 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) |
187 | #define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a) | ||
188 | #define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a) | 182 | #define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a) |
189 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) | 183 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) |
190 | #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) | 184 | #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) |
@@ -206,8 +200,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
206 | #define IWL_DEBUG_STATS_LIMIT(p, f, a...) \ | 200 | #define IWL_DEBUG_STATS_LIMIT(p, f, a...) \ |
207 | IWL_DEBUG_LIMIT(p, IWL_DL_STATS, f, ## a) | 201 | IWL_DEBUG_LIMIT(p, IWL_DL_STATS, f, ## a) |
208 | #define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a) | 202 | #define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a) |
209 | #define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \ | ||
210 | IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a) | ||
211 | #define IWL_DEBUG_TX_QUEUES(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_QUEUES, f, ## a) | 203 | #define IWL_DEBUG_TX_QUEUES(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_QUEUES, f, ## a) |
212 | #define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a) | 204 | #define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a) |
213 | #define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) | 205 | #define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 68b04f5b10ce..ccbcab40e78f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -234,11 +234,12 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
234 | 234 | ||
235 | /* default is to dump the entire data segment */ | 235 | /* default is to dump the entire data segment */ |
236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
237 | struct iwl_trans *trans = trans(priv); | ||
237 | priv->dbgfs_sram_offset = 0x800000; | 238 | priv->dbgfs_sram_offset = 0x800000; |
238 | if (priv->ucode_type == IWL_UCODE_INIT) | 239 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) |
239 | priv->dbgfs_sram_len = trans(priv)->ucode_init.data.len; | 240 | priv->dbgfs_sram_len = trans->ucode_init.data.len; |
240 | else | 241 | else |
241 | priv->dbgfs_sram_len = trans(priv)->ucode_rt.data.len; | 242 | priv->dbgfs_sram_len = trans->ucode_rt.data.len; |
242 | } | 243 | } |
243 | len = priv->dbgfs_sram_len; | 244 | len = priv->dbgfs_sram_len; |
244 | 245 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0c95ad3048a0..6f6a647d34f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -689,35 +689,6 @@ struct iwl_force_reset { | |||
689 | */ | 689 | */ |
690 | #define IWLAGN_EXT_BEACON_TIME_POS 22 | 690 | #define IWLAGN_EXT_BEACON_TIME_POS 22 |
691 | 691 | ||
692 | /** | ||
693 | * struct iwl_notification_wait - notification wait entry | ||
694 | * @list: list head for global list | ||
695 | * @fn: function called with the notification | ||
696 | * @cmd: command ID | ||
697 | * | ||
698 | * This structure is not used directly, to wait for a | ||
699 | * notification declare it on the stack, and call | ||
700 | * iwlagn_init_notification_wait() with appropriate | ||
701 | * parameters. Then do whatever will cause the ucode | ||
702 | * to notify the driver, and to wait for that then | ||
703 | * call iwlagn_wait_notification(). | ||
704 | * | ||
705 | * Each notification is one-shot. If at some point we | ||
706 | * need to support multi-shot notifications (which | ||
707 | * can't be allocated on the stack) we need to modify | ||
708 | * the code for them. | ||
709 | */ | ||
710 | struct iwl_notification_wait { | ||
711 | struct list_head list; | ||
712 | |||
713 | void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt, | ||
714 | void *data); | ||
715 | void *fn_data; | ||
716 | |||
717 | u8 cmd; | ||
718 | bool triggered, aborted; | ||
719 | }; | ||
720 | |||
721 | struct iwl_rxon_context { | 692 | struct iwl_rxon_context { |
722 | struct ieee80211_vif *vif; | 693 | struct ieee80211_vif *vif; |
723 | 694 | ||
@@ -790,6 +761,12 @@ struct iwl_testmode_trace { | |||
790 | dma_addr_t dma_addr; | 761 | dma_addr_t dma_addr; |
791 | bool trace_enabled; | 762 | bool trace_enabled; |
792 | }; | 763 | }; |
764 | struct iwl_testmode_sram { | ||
765 | u32 buff_size; | ||
766 | u32 num_chunks; | ||
767 | u8 *buff_addr; | ||
768 | bool sram_readed; | ||
769 | }; | ||
793 | #endif | 770 | #endif |
794 | 771 | ||
795 | struct iwl_wipan_noa_data { | 772 | struct iwl_wipan_noa_data { |
@@ -883,7 +860,6 @@ struct iwl_priv { | |||
883 | u32 ucode_ver; /* version of ucode, copy of | 860 | u32 ucode_ver; /* version of ucode, copy of |
884 | iwl_ucode.ver */ | 861 | iwl_ucode.ver */ |
885 | 862 | ||
886 | enum iwl_ucode_type ucode_type; | ||
887 | char firmware_name[25]; | 863 | char firmware_name[25]; |
888 | 864 | ||
889 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; | 865 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; |
@@ -987,10 +963,6 @@ struct iwl_priv { | |||
987 | /* counts reply_tx error */ | 963 | /* counts reply_tx error */ |
988 | struct reply_tx_error_statistics reply_tx_stats; | 964 | struct reply_tx_error_statistics reply_tx_stats; |
989 | struct reply_agg_tx_error_statistics reply_agg_tx_stats; | 965 | struct reply_agg_tx_error_statistics reply_agg_tx_stats; |
990 | /* notification wait support */ | ||
991 | struct list_head notif_waits; | ||
992 | spinlock_t notif_wait_lock; | ||
993 | wait_queue_head_t notif_waitq; | ||
994 | 966 | ||
995 | /* remain-on-channel offload support */ | 967 | /* remain-on-channel offload support */ |
996 | struct ieee80211_channel *hw_roc_channel; | 968 | struct ieee80211_channel *hw_roc_channel; |
@@ -1070,6 +1042,7 @@ struct iwl_priv { | |||
1070 | bool led_registered; | 1042 | bool led_registered; |
1071 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | 1043 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL |
1072 | struct iwl_testmode_trace testmode_trace; | 1044 | struct iwl_testmode_trace testmode_trace; |
1045 | struct iwl_testmode_sram testmode_sram; | ||
1073 | u32 tm_fixed_rate; | 1046 | u32 tm_fixed_rate; |
1074 | #endif | 1047 | #endif |
1075 | 1048 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 05b1f0d2f387..794b735264e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -481,15 +481,11 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
481 | { | 481 | { |
482 | struct iwl_priv *priv = hw->priv; | 482 | struct iwl_priv *priv = hw->priv; |
483 | 483 | ||
484 | IWL_DEBUG_MACDUMP(priv, "enter\n"); | ||
485 | |||
486 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 484 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
487 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | 485 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); |
488 | 486 | ||
489 | if (iwlagn_tx_skb(priv, skb)) | 487 | if (iwlagn_tx_skb(priv, skb)) |
490 | dev_kfree_skb_any(skb); | 488 | dev_kfree_skb_any(skb); |
491 | |||
492 | IWL_DEBUG_MACDUMP(priv, "leave\n"); | ||
493 | } | 489 | } |
494 | 490 | ||
495 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | 491 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 47be77a8a0a7..39aa9cf5b847 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -120,7 +120,7 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
120 | * @restart_fw: restart firmware, default = 1 | 120 | * @restart_fw: restart firmware, default = 1 |
121 | * @plcp_check: enable plcp health check, default = true | 121 | * @plcp_check: enable plcp health check, default = true |
122 | * @ack_check: disable ack health check, default = false | 122 | * @ack_check: disable ack health check, default = false |
123 | * @wd_disable: enable stuck queue check, default = false | 123 | * @wd_disable: enable stuck queue check, default = 0 |
124 | * @bt_coex_active: enable bt coex, default = true | 124 | * @bt_coex_active: enable bt coex, default = true |
125 | * @led_mode: system default, default = 0 | 125 | * @led_mode: system default, default = 0 |
126 | * @no_sleep_autoadjust: disable autoadjust, default = true | 126 | * @no_sleep_autoadjust: disable autoadjust, default = true |
@@ -141,7 +141,7 @@ struct iwl_mod_params { | |||
141 | int restart_fw; | 141 | int restart_fw; |
142 | bool plcp_check; | 142 | bool plcp_check; |
143 | bool ack_check; | 143 | bool ack_check; |
144 | bool wd_disable; | 144 | int wd_disable; |
145 | bool bt_coex_active; | 145 | bool bt_coex_active; |
146 | int led_mode; | 146 | int led_mode; |
147 | bool no_sleep_autoadjust; | 147 | bool no_sleep_autoadjust; |
@@ -257,6 +257,52 @@ struct iwl_tid_data { | |||
257 | }; | 257 | }; |
258 | 258 | ||
259 | /** | 259 | /** |
260 | * enum iwl_ucode_type | ||
261 | * | ||
262 | * The type of ucode currently loaded on the hardware. | ||
263 | * | ||
264 | * @IWL_UCODE_NONE: No ucode loaded | ||
265 | * @IWL_UCODE_REGULAR: Normal runtime ucode | ||
266 | * @IWL_UCODE_INIT: Initial ucode | ||
267 | * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode | ||
268 | */ | ||
269 | enum iwl_ucode_type { | ||
270 | IWL_UCODE_NONE, | ||
271 | IWL_UCODE_REGULAR, | ||
272 | IWL_UCODE_INIT, | ||
273 | IWL_UCODE_WOWLAN, | ||
274 | }; | ||
275 | |||
276 | /** | ||
277 | * struct iwl_notification_wait - notification wait entry | ||
278 | * @list: list head for global list | ||
279 | * @fn: function called with the notification | ||
280 | * @cmd: command ID | ||
281 | * | ||
282 | * This structure is not used directly, to wait for a | ||
283 | * notification declare it on the stack, and call | ||
284 | * iwlagn_init_notification_wait() with appropriate | ||
285 | * parameters. Then do whatever will cause the ucode | ||
286 | * to notify the driver, and to wait for that then | ||
287 | * call iwlagn_wait_notification(). | ||
288 | * | ||
289 | * Each notification is one-shot. If at some point we | ||
290 | * need to support multi-shot notifications (which | ||
291 | * can't be allocated on the stack) we need to modify | ||
292 | * the code for them. | ||
293 | */ | ||
294 | struct iwl_notification_wait { | ||
295 | struct list_head list; | ||
296 | |||
297 | void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt, | ||
298 | void *data); | ||
299 | void *fn_data; | ||
300 | |||
301 | u8 cmd; | ||
302 | bool triggered, aborted; | ||
303 | }; | ||
304 | |||
305 | /** | ||
260 | * struct iwl_shared - shared fields for all the layers of the driver | 306 | * struct iwl_shared - shared fields for all the layers of the driver |
261 | * | 307 | * |
262 | * @dbg_level_dev: dbg level set per device. Prevails on | 308 | * @dbg_level_dev: dbg level set per device. Prevails on |
@@ -273,6 +319,10 @@ struct iwl_tid_data { | |||
273 | * @sta_lock: protects the station table. | 319 | * @sta_lock: protects the station table. |
274 | * If lock and sta_lock are needed, lock must be acquired first. | 320 | * If lock and sta_lock are needed, lock must be acquired first. |
275 | * @mutex: | 321 | * @mutex: |
322 | * @ucode_type: indicator of loaded ucode image | ||
323 | * @notif_waits: things waiting for notification | ||
324 | * @notif_wait_lock: lock protecting notification | ||
325 | * @notif_waitq: head of notification wait queue | ||
276 | */ | 326 | */ |
277 | struct iwl_shared { | 327 | struct iwl_shared { |
278 | #ifdef CONFIG_IWLWIFI_DEBUG | 328 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -300,6 +350,14 @@ struct iwl_shared { | |||
300 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; | 350 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; |
301 | 351 | ||
302 | wait_queue_head_t wait_command_queue; | 352 | wait_queue_head_t wait_command_queue; |
353 | |||
354 | /* ucode related variables */ | ||
355 | enum iwl_ucode_type ucode_type; | ||
356 | |||
357 | /* notification wait support */ | ||
358 | struct list_head notif_waits; | ||
359 | spinlock_t notif_wait_lock; | ||
360 | wait_queue_head_t notif_waitq; | ||
303 | }; | 361 | }; |
304 | 362 | ||
305 | /*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ | 363 | /*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ |
@@ -443,6 +501,24 @@ bool iwl_check_for_ct_kill(struct iwl_priv *priv); | |||
443 | void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac); | 501 | void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac); |
444 | void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac); | 502 | void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac); |
445 | 503 | ||
504 | /* notification wait support */ | ||
505 | void iwl_abort_notification_waits(struct iwl_shared *shrd); | ||
506 | void __acquires(wait_entry) | ||
507 | iwl_init_notification_wait(struct iwl_shared *shrd, | ||
508 | struct iwl_notification_wait *wait_entry, | ||
509 | u8 cmd, | ||
510 | void (*fn)(struct iwl_priv *priv, | ||
511 | struct iwl_rx_packet *pkt, | ||
512 | void *data), | ||
513 | void *fn_data); | ||
514 | int __must_check __releases(wait_entry) | ||
515 | iwl_wait_notification(struct iwl_shared *shrd, | ||
516 | struct iwl_notification_wait *wait_entry, | ||
517 | unsigned long timeout); | ||
518 | void __releases(wait_entry) | ||
519 | iwl_remove_notification(struct iwl_shared *shrd, | ||
520 | struct iwl_notification_wait *wait_entry); | ||
521 | |||
446 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 522 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
447 | void iwl_reset_traffic_log(struct iwl_priv *priv); | 523 | void iwl_reset_traffic_log(struct iwl_priv *priv); |
448 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 524 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index be16cafbbc27..ff72dbcfd52d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c | |||
@@ -106,6 +106,10 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | |||
106 | [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, | 106 | [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, |
107 | 107 | ||
108 | [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, }, | 108 | [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, }, |
109 | |||
110 | [IWL_TM_ATTR_SRAM_ADDR] = { .type = NLA_U32, }, | ||
111 | [IWL_TM_ATTR_SRAM_SIZE] = { .type = NLA_U32, }, | ||
112 | [IWL_TM_ATTR_SRAM_DUMP] = { .type = NLA_UNSPEC, }, | ||
109 | }; | 113 | }; |
110 | 114 | ||
111 | /* | 115 | /* |
@@ -177,6 +181,18 @@ void iwl_testmode_init(struct iwl_priv *priv) | |||
177 | { | 181 | { |
178 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | 182 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; |
179 | priv->testmode_trace.trace_enabled = false; | 183 | priv->testmode_trace.trace_enabled = false; |
184 | priv->testmode_sram.sram_readed = false; | ||
185 | } | ||
186 | |||
187 | static void iwl_sram_cleanup(struct iwl_priv *priv) | ||
188 | { | ||
189 | if (priv->testmode_sram.sram_readed) { | ||
190 | kfree(priv->testmode_sram.buff_addr); | ||
191 | priv->testmode_sram.buff_addr = NULL; | ||
192 | priv->testmode_sram.buff_size = 0; | ||
193 | priv->testmode_sram.num_chunks = 0; | ||
194 | priv->testmode_sram.sram_readed = false; | ||
195 | } | ||
180 | } | 196 | } |
181 | 197 | ||
182 | static void iwl_trace_cleanup(struct iwl_priv *priv) | 198 | static void iwl_trace_cleanup(struct iwl_priv *priv) |
@@ -201,6 +217,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv) | |||
201 | void iwl_testmode_cleanup(struct iwl_priv *priv) | 217 | void iwl_testmode_cleanup(struct iwl_priv *priv) |
202 | { | 218 | { |
203 | iwl_trace_cleanup(priv); | 219 | iwl_trace_cleanup(priv); |
220 | iwl_sram_cleanup(priv); | ||
204 | } | 221 | } |
205 | 222 | ||
206 | /* | 223 | /* |
@@ -356,7 +373,7 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) | |||
356 | struct iwl_notification_wait calib_wait; | 373 | struct iwl_notification_wait calib_wait; |
357 | int ret; | 374 | int ret; |
358 | 375 | ||
359 | iwlagn_init_notification_wait(priv, &calib_wait, | 376 | iwl_init_notification_wait(priv->shrd, &calib_wait, |
360 | CALIBRATION_COMPLETE_NOTIFICATION, | 377 | CALIBRATION_COMPLETE_NOTIFICATION, |
361 | NULL, NULL); | 378 | NULL, NULL); |
362 | ret = iwlagn_init_alive_start(priv); | 379 | ret = iwlagn_init_alive_start(priv); |
@@ -366,14 +383,14 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) | |||
366 | goto cfg_init_calib_error; | 383 | goto cfg_init_calib_error; |
367 | } | 384 | } |
368 | 385 | ||
369 | ret = iwlagn_wait_notification(priv, &calib_wait, 2 * HZ); | 386 | ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ); |
370 | if (ret) | 387 | if (ret) |
371 | IWL_DEBUG_INFO(priv, "Error detecting" | 388 | IWL_DEBUG_INFO(priv, "Error detecting" |
372 | " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); | 389 | " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); |
373 | return ret; | 390 | return ret; |
374 | 391 | ||
375 | cfg_init_calib_error: | 392 | cfg_init_calib_error: |
376 | iwlagn_remove_notification(priv, &calib_wait); | 393 | iwl_remove_notification(priv->shrd, &calib_wait); |
377 | return ret; | 394 | return ret; |
378 | } | 395 | } |
379 | 396 | ||
@@ -446,6 +463,21 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
446 | "Error starting the device: %d\n", status); | 463 | "Error starting the device: %d\n", status); |
447 | break; | 464 | break; |
448 | 465 | ||
466 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | ||
467 | iwl_scan_cancel_timeout(priv, 200); | ||
468 | iwl_trans_stop_device(trans(priv)); | ||
469 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); | ||
470 | if (status) { | ||
471 | IWL_DEBUG_INFO(priv, | ||
472 | "Error loading WOWLAN ucode: %d\n", status); | ||
473 | break; | ||
474 | } | ||
475 | status = iwl_alive_start(priv); | ||
476 | if (status) | ||
477 | IWL_DEBUG_INFO(priv, | ||
478 | "Error starting the device: %d\n", status); | ||
479 | break; | ||
480 | |||
449 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | 481 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: |
450 | if (priv->eeprom) { | 482 | if (priv->eeprom) { |
451 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | 483 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, |
@@ -558,7 +590,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) | |||
558 | } | 590 | } |
559 | priv->testmode_trace.num_chunks = | 591 | priv->testmode_trace.num_chunks = |
560 | DIV_ROUND_UP(priv->testmode_trace.buff_size, | 592 | DIV_ROUND_UP(priv->testmode_trace.buff_size, |
561 | TRACE_CHUNK_SIZE); | 593 | DUMP_CHUNK_SIZE); |
562 | break; | 594 | break; |
563 | 595 | ||
564 | case IWL_TM_CMD_APP2DEV_END_TRACE: | 596 | case IWL_TM_CMD_APP2DEV_END_TRACE: |
@@ -590,15 +622,15 @@ static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, | |||
590 | idx = cb->args[4]; | 622 | idx = cb->args[4]; |
591 | if (idx >= priv->testmode_trace.num_chunks) | 623 | if (idx >= priv->testmode_trace.num_chunks) |
592 | return -ENOENT; | 624 | return -ENOENT; |
593 | length = TRACE_CHUNK_SIZE; | 625 | length = DUMP_CHUNK_SIZE; |
594 | if (((idx + 1) == priv->testmode_trace.num_chunks) && | 626 | if (((idx + 1) == priv->testmode_trace.num_chunks) && |
595 | (priv->testmode_trace.buff_size % TRACE_CHUNK_SIZE)) | 627 | (priv->testmode_trace.buff_size % DUMP_CHUNK_SIZE)) |
596 | length = priv->testmode_trace.buff_size % | 628 | length = priv->testmode_trace.buff_size % |
597 | TRACE_CHUNK_SIZE; | 629 | DUMP_CHUNK_SIZE; |
598 | 630 | ||
599 | NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length, | 631 | NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length, |
600 | priv->testmode_trace.trace_addr + | 632 | priv->testmode_trace.trace_addr + |
601 | (TRACE_CHUNK_SIZE * idx)); | 633 | (DUMP_CHUNK_SIZE * idx)); |
602 | idx++; | 634 | idx++; |
603 | cb->args[4] = idx; | 635 | cb->args[4] = idx; |
604 | return 0; | 636 | return 0; |
@@ -644,6 +676,110 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) | |||
644 | return 0; | 676 | return 0; |
645 | } | 677 | } |
646 | 678 | ||
679 | /* | ||
680 | * This function handles the user application commands for SRAM data dump | ||
681 | * | ||
682 | * It retrieves the mandatory fields IWL_TM_ATTR_SRAM_ADDR and | ||
683 | * IWL_TM_ATTR_SRAM_SIZE to decide the memory area for SRAM data reading | ||
684 | * | ||
685 | * Several error will be retured, -EBUSY if the SRAM data retrieved by | ||
686 | * previous command has not been delivered to userspace, or -ENOMSG if | ||
687 | * the mandatory fields (IWL_TM_ATTR_SRAM_ADDR,IWL_TM_ATTR_SRAM_SIZE) | ||
688 | * are missing, or -ENOMEM if the buffer allocation fails. | ||
689 | * | ||
690 | * Otherwise 0 is replied indicating the success of the SRAM reading. | ||
691 | * | ||
692 | * @hw: ieee80211_hw object that represents the device | ||
693 | * @tb: gnl message fields from the user space | ||
694 | */ | ||
695 | static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) | ||
696 | { | ||
697 | struct iwl_priv *priv = hw->priv; | ||
698 | u32 base, ofs, size, maxsize; | ||
699 | |||
700 | if (priv->testmode_sram.sram_readed) | ||
701 | return -EBUSY; | ||
702 | |||
703 | if (!tb[IWL_TM_ATTR_SRAM_ADDR]) { | ||
704 | IWL_DEBUG_INFO(priv, "Error finding SRAM offset address\n"); | ||
705 | return -ENOMSG; | ||
706 | } | ||
707 | ofs = nla_get_u32(tb[IWL_TM_ATTR_SRAM_ADDR]); | ||
708 | if (!tb[IWL_TM_ATTR_SRAM_SIZE]) { | ||
709 | IWL_DEBUG_INFO(priv, "Error finding size for SRAM reading\n"); | ||
710 | return -ENOMSG; | ||
711 | } | ||
712 | size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]); | ||
713 | switch (priv->shrd->ucode_type) { | ||
714 | case IWL_UCODE_REGULAR: | ||
715 | maxsize = trans(priv)->ucode_rt.data.len; | ||
716 | break; | ||
717 | case IWL_UCODE_INIT: | ||
718 | maxsize = trans(priv)->ucode_init.data.len; | ||
719 | break; | ||
720 | case IWL_UCODE_WOWLAN: | ||
721 | maxsize = trans(priv)->ucode_wowlan.data.len; | ||
722 | break; | ||
723 | case IWL_UCODE_NONE: | ||
724 | IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n"); | ||
725 | return -ENOSYS; | ||
726 | default: | ||
727 | IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n"); | ||
728 | return -ENOSYS; | ||
729 | } | ||
730 | if ((ofs + size) > maxsize) { | ||
731 | IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n"); | ||
732 | return -EINVAL; | ||
733 | } | ||
734 | priv->testmode_sram.buff_size = (size / 4) * 4; | ||
735 | priv->testmode_sram.buff_addr = | ||
736 | kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL); | ||
737 | if (priv->testmode_sram.buff_addr == NULL) { | ||
738 | IWL_DEBUG_INFO(priv, "Error allocating memory\n"); | ||
739 | return -ENOMEM; | ||
740 | } | ||
741 | base = 0x800000; | ||
742 | _iwl_read_targ_mem_words(bus(priv), base + ofs, | ||
743 | priv->testmode_sram.buff_addr, | ||
744 | priv->testmode_sram.buff_size / 4); | ||
745 | priv->testmode_sram.num_chunks = | ||
746 | DIV_ROUND_UP(priv->testmode_sram.buff_size, DUMP_CHUNK_SIZE); | ||
747 | priv->testmode_sram.sram_readed = true; | ||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb, | ||
752 | struct sk_buff *skb, | ||
753 | struct netlink_callback *cb) | ||
754 | { | ||
755 | struct iwl_priv *priv = hw->priv; | ||
756 | int idx, length; | ||
757 | |||
758 | if (priv->testmode_sram.sram_readed) { | ||
759 | idx = cb->args[4]; | ||
760 | if (idx >= priv->testmode_sram.num_chunks) { | ||
761 | iwl_sram_cleanup(priv); | ||
762 | return -ENOENT; | ||
763 | } | ||
764 | length = DUMP_CHUNK_SIZE; | ||
765 | if (((idx + 1) == priv->testmode_sram.num_chunks) && | ||
766 | (priv->testmode_sram.buff_size % DUMP_CHUNK_SIZE)) | ||
767 | length = priv->testmode_sram.buff_size % | ||
768 | DUMP_CHUNK_SIZE; | ||
769 | |||
770 | NLA_PUT(skb, IWL_TM_ATTR_SRAM_DUMP, length, | ||
771 | priv->testmode_sram.buff_addr + | ||
772 | (DUMP_CHUNK_SIZE * idx)); | ||
773 | idx++; | ||
774 | cb->args[4] = idx; | ||
775 | return 0; | ||
776 | } else | ||
777 | return -EFAULT; | ||
778 | |||
779 | nla_put_failure: | ||
780 | return -ENOBUFS; | ||
781 | } | ||
782 | |||
647 | 783 | ||
648 | /* The testmode gnl message handler that takes the gnl message from the | 784 | /* The testmode gnl message handler that takes the gnl message from the |
649 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then | 785 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then |
@@ -705,6 +841,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
705 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 841 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
706 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | 842 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: |
707 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: | 843 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: |
844 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | ||
708 | IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); | 845 | IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); |
709 | result = iwl_testmode_driver(hw, tb); | 846 | result = iwl_testmode_driver(hw, tb); |
710 | break; | 847 | break; |
@@ -721,6 +858,11 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
721 | result = iwl_testmode_ownership(hw, tb); | 858 | result = iwl_testmode_ownership(hw, tb); |
722 | break; | 859 | break; |
723 | 860 | ||
861 | case IWL_TM_CMD_APP2DEV_READ_SRAM: | ||
862 | IWL_DEBUG_INFO(priv, "testmode sram read cmd to driver\n"); | ||
863 | result = iwl_testmode_sram(hw, tb); | ||
864 | break; | ||
865 | |||
724 | default: | 866 | default: |
725 | IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); | 867 | IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); |
726 | result = -ENOSYS; | 868 | result = -ENOSYS; |
@@ -769,6 +911,10 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
769 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); | 911 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); |
770 | result = iwl_testmode_trace_dump(hw, tb, skb, cb); | 912 | result = iwl_testmode_trace_dump(hw, tb, skb, cb); |
771 | break; | 913 | break; |
914 | case IWL_TM_CMD_APP2DEV_DUMP_SRAM: | ||
915 | IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); | ||
916 | result = iwl_testmode_sram_dump(hw, tb, skb, cb); | ||
917 | break; | ||
772 | default: | 918 | default: |
773 | result = -EINVAL; | 919 | result = -EINVAL; |
774 | break; | 920 | break; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 177964850b7c..deedd27c5f3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h | |||
@@ -103,14 +103,22 @@ | |||
103 | * @IWL_TM_CMD_DEV2APP_EEPROM_RSP: | 103 | * @IWL_TM_CMD_DEV2APP_EEPROM_RSP: |
104 | * commands from kernel space to carry the eeprom response | 104 | * commands from kernel space to carry the eeprom response |
105 | * to user application | 105 | * to user application |
106 | * | ||
106 | * @IWL_TM_CMD_APP2DEV_OWNERSHIP: | 107 | * @IWL_TM_CMD_APP2DEV_OWNERSHIP: |
107 | * commands from user application to own change the ownership of the uCode | 108 | * commands from user application to own change the ownership of the uCode |
108 | * if application has the ownership, the only host command from | 109 | * if application has the ownership, the only host command from |
109 | * testmode will deliver to uCode. Default owner is driver | 110 | * testmode will deliver to uCode. Default owner is driver |
111 | * | ||
110 | * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: | 112 | * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: |
111 | * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32: | 113 | * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32: |
112 | * commands from user applicaiton to indirectly access peripheral register | 114 | * commands from user applicaiton to indirectly access peripheral register |
113 | * | 115 | * |
116 | * @IWL_TM_CMD_APP2DEV_READ_SRAM: | ||
117 | * @IWL_TM_CMD_APP2DEV_DUMP_SRAM: | ||
118 | * commands from user applicaiton to read data in sram | ||
119 | * | ||
120 | * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image | ||
121 | * | ||
114 | */ | 122 | */ |
115 | enum iwl_tm_cmd_t { | 123 | enum iwl_tm_cmd_t { |
116 | IWL_TM_CMD_APP2DEV_UCODE = 1, | 124 | IWL_TM_CMD_APP2DEV_UCODE = 1, |
@@ -132,7 +140,10 @@ enum iwl_tm_cmd_t { | |||
132 | IWL_TM_CMD_APP2DEV_OWNERSHIP = 17, | 140 | IWL_TM_CMD_APP2DEV_OWNERSHIP = 17, |
133 | IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32 = 18, | 141 | IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32 = 18, |
134 | IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32 = 19, | 142 | IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32 = 19, |
135 | IWL_TM_CMD_MAX = 20, | 143 | IWL_TM_CMD_APP2DEV_READ_SRAM = 20, |
144 | IWL_TM_CMD_APP2DEV_DUMP_SRAM = 21, | ||
145 | IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22, | ||
146 | IWL_TM_CMD_MAX = 23, | ||
136 | }; | 147 | }; |
137 | 148 | ||
138 | /* | 149 | /* |
@@ -202,6 +213,18 @@ enum iwl_tm_cmd_t { | |||
202 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP, | 213 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP, |
203 | * The mandatory fields are: | 214 | * The mandatory fields are: |
204 | * IWL_TM_ATTR_UCODE_OWNER for the new owner | 215 | * IWL_TM_ATTR_UCODE_OWNER for the new owner |
216 | * | ||
217 | * @IWL_TM_ATTR_SRAM_ADDR: | ||
218 | * @IWL_TM_ATTR_SRAM_SIZE: | ||
219 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_READ_SRAM, | ||
220 | * The mandatory fields are: | ||
221 | * IWL_TM_ATTR_SRAM_ADDR for the address in sram | ||
222 | * IWL_TM_ATTR_SRAM_SIZE for the buffer size of data reading | ||
223 | * | ||
224 | * @IWL_TM_ATTR_SRAM_DUMP: | ||
225 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_DUMP_SRAM, | ||
226 | * IWL_TM_ATTR_SRAM_DUMP for the data in sram | ||
227 | * | ||
205 | */ | 228 | */ |
206 | enum iwl_tm_attr_t { | 229 | enum iwl_tm_attr_t { |
207 | IWL_TM_ATTR_NOT_APPLICABLE = 0, | 230 | IWL_TM_ATTR_NOT_APPLICABLE = 0, |
@@ -219,7 +242,10 @@ enum iwl_tm_attr_t { | |||
219 | IWL_TM_ATTR_TRACE_DUMP = 12, | 242 | IWL_TM_ATTR_TRACE_DUMP = 12, |
220 | IWL_TM_ATTR_FIXRATE = 13, | 243 | IWL_TM_ATTR_FIXRATE = 13, |
221 | IWL_TM_ATTR_UCODE_OWNER = 14, | 244 | IWL_TM_ATTR_UCODE_OWNER = 14, |
222 | IWL_TM_ATTR_MAX = 15, | 245 | IWL_TM_ATTR_SRAM_ADDR = 15, |
246 | IWL_TM_ATTR_SRAM_SIZE = 16, | ||
247 | IWL_TM_ATTR_SRAM_DUMP = 17, | ||
248 | IWL_TM_ATTR_MAX = 18, | ||
223 | }; | 249 | }; |
224 | 250 | ||
225 | /* uCode trace buffer */ | 251 | /* uCode trace buffer */ |
@@ -227,6 +253,8 @@ enum iwl_tm_attr_t { | |||
227 | #define TRACE_BUFF_SIZE_MIN 0x20000 | 253 | #define TRACE_BUFF_SIZE_MIN 0x20000 |
228 | #define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN | 254 | #define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN |
229 | #define TRACE_BUFF_PADD 0x2000 | 255 | #define TRACE_BUFF_PADD 0x2000 |
230 | #define TRACE_CHUNK_SIZE (PAGE_SIZE - 1024) | 256 | |
257 | /* Maximum data size of each dump it packet */ | ||
258 | #define DUMP_CHUNK_SIZE (PAGE_SIZE - 1024) | ||
231 | 259 | ||
232 | #endif | 260 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index ee126f844a5c..becd92173ddd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -595,7 +595,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
595 | IWL_TRANS_GET_PCIE_TRANS(trans); | 595 | IWL_TRANS_GET_PCIE_TRANS(trans); |
596 | 596 | ||
597 | base = priv->device_pointers.error_event_table; | 597 | base = priv->device_pointers.error_event_table; |
598 | if (priv->ucode_type == IWL_UCODE_INIT) { | 598 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
599 | if (!base) | 599 | if (!base) |
600 | base = priv->init_errlog_ptr; | 600 | base = priv->init_errlog_ptr; |
601 | } else { | 601 | } else { |
@@ -607,7 +607,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
607 | IWL_ERR(trans, | 607 | IWL_ERR(trans, |
608 | "Not valid error log pointer 0x%08X for %s uCode\n", | 608 | "Not valid error log pointer 0x%08X for %s uCode\n", |
609 | base, | 609 | base, |
610 | (priv->ucode_type == IWL_UCODE_INIT) | 610 | (trans->shrd->ucode_type == IWL_UCODE_INIT) |
611 | ? "Init" : "RT"); | 611 | ? "Init" : "RT"); |
612 | return; | 612 | return; |
613 | } | 613 | } |
@@ -710,7 +710,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
710 | return pos; | 710 | return pos; |
711 | 711 | ||
712 | base = priv->device_pointers.log_event_table; | 712 | base = priv->device_pointers.log_event_table; |
713 | if (priv->ucode_type == IWL_UCODE_INIT) { | 713 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
714 | if (!base) | 714 | if (!base) |
715 | base = priv->init_evtlog_ptr; | 715 | base = priv->init_evtlog_ptr; |
716 | } else { | 716 | } else { |
@@ -824,7 +824,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
824 | struct iwl_priv *priv = priv(trans); | 824 | struct iwl_priv *priv = priv(trans); |
825 | 825 | ||
826 | base = priv->device_pointers.log_event_table; | 826 | base = priv->device_pointers.log_event_table; |
827 | if (priv->ucode_type == IWL_UCODE_INIT) { | 827 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
828 | logsize = priv->init_evtlog_size; | 828 | logsize = priv->init_evtlog_size; |
829 | if (!base) | 829 | if (!base) |
830 | base = priv->init_evtlog_ptr; | 830 | base = priv->init_evtlog_ptr; |
@@ -838,7 +838,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
838 | IWL_ERR(trans, | 838 | IWL_ERR(trans, |
839 | "Invalid event log pointer 0x%08X for %s uCode\n", | 839 | "Invalid event log pointer 0x%08X for %s uCode\n", |
840 | base, | 840 | base, |
841 | (priv->ucode_type == IWL_UCODE_INIT) | 841 | (trans->shrd->ucode_type == IWL_UCODE_INIT) |
842 | ? "Init" : "RT"); | 842 | ? "Init" : "RT"); |
843 | return -EINVAL; | 843 | return -EINVAL; |
844 | } | 844 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 2ac75427f10b..304b2ea0375c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -990,29 +990,16 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
990 | return 0; | 990 | return 0; |
991 | } | 991 | } |
992 | 992 | ||
993 | static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans) | 993 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) |
994 | { | 994 | { |
995 | unsigned long flags; | 995 | unsigned long flags; |
996 | struct iwl_trans_pcie *trans_pcie = | 996 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
997 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
998 | 997 | ||
998 | /* tell the device to stop sending interrupts */ | ||
999 | spin_lock_irqsave(&trans->shrd->lock, flags); | 999 | spin_lock_irqsave(&trans->shrd->lock, flags); |
1000 | iwl_disable_interrupts(trans); | 1000 | iwl_disable_interrupts(trans); |
1001 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1001 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
1002 | 1002 | ||
1003 | /* wait to make sure we flush pending tasklet*/ | ||
1004 | synchronize_irq(bus(trans)->irq); | ||
1005 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
1006 | } | ||
1007 | |||
1008 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | ||
1009 | { | ||
1010 | /* stop and reset the on-board processor */ | ||
1011 | iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
1012 | |||
1013 | /* tell the device to stop sending interrupts */ | ||
1014 | iwl_trans_pcie_disable_sync_irq(trans); | ||
1015 | |||
1016 | /* device going down, Stop using ICT table */ | 1003 | /* device going down, Stop using ICT table */ |
1017 | iwl_disable_ict(trans); | 1004 | iwl_disable_ict(trans); |
1018 | 1005 | ||
@@ -1039,6 +1026,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1039 | 1026 | ||
1040 | /* Stop the device, and put it in low power state */ | 1027 | /* Stop the device, and put it in low power state */ |
1041 | iwl_apm_stop(priv(trans)); | 1028 | iwl_apm_stop(priv(trans)); |
1029 | |||
1030 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. | ||
1031 | * Clean again the interrupt here | ||
1032 | */ | ||
1033 | spin_lock_irqsave(&trans->shrd->lock, flags); | ||
1034 | iwl_disable_interrupts(trans); | ||
1035 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | ||
1036 | |||
1037 | /* wait to make sure we flush pending tasklet*/ | ||
1038 | synchronize_irq(bus(trans)->irq); | ||
1039 | tasklet_kill(&trans_pcie->irq_tasklet); | ||
1040 | |||
1041 | /* stop and reset the on-board processor */ | ||
1042 | iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
1042 | } | 1043 | } |
1043 | 1044 | ||
1044 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1045 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 50227ebc0ee2..4a29b8ab998e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -220,13 +220,6 @@ struct fw_img { | |||
220 | struct fw_desc data; /* firmware data image */ | 220 | struct fw_desc data; /* firmware data image */ |
221 | }; | 221 | }; |
222 | 222 | ||
223 | enum iwl_ucode_type { | ||
224 | IWL_UCODE_NONE, | ||
225 | IWL_UCODE_REGULAR, | ||
226 | IWL_UCODE_INIT, | ||
227 | IWL_UCODE_WOWLAN, | ||
228 | }; | ||
229 | |||
230 | /** | 223 | /** |
231 | * struct iwl_trans - transport common data | 224 | * struct iwl_trans - transport common data |
232 | * @ops - pointer to iwl_trans_ops | 225 | * @ops - pointer to iwl_trans_ops |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 76949106dafc..b365de457b1b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
@@ -122,7 +122,7 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | |||
122 | /* | 122 | /* |
123 | * ucode | 123 | * ucode |
124 | */ | 124 | */ |
125 | static int iwlagn_load_section(struct iwl_trans *trans, const char *name, | 125 | static int iwl_load_section(struct iwl_trans *trans, const char *name, |
126 | struct fw_desc *image, u32 dst_addr) | 126 | struct fw_desc *image, u32 dst_addr) |
127 | { | 127 | { |
128 | struct iwl_bus *bus = bus(trans); | 128 | struct iwl_bus *bus = bus(trans); |
@@ -188,7 +188,7 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, | |||
188 | return NULL; | 188 | return NULL; |
189 | } | 189 | } |
190 | 190 | ||
191 | static int iwlagn_load_given_ucode(struct iwl_trans *trans, | 191 | static int iwl_load_given_ucode(struct iwl_trans *trans, |
192 | enum iwl_ucode_type ucode_type) | 192 | enum iwl_ucode_type ucode_type) |
193 | { | 193 | { |
194 | int ret = 0; | 194 | int ret = 0; |
@@ -201,19 +201,19 @@ static int iwlagn_load_given_ucode(struct iwl_trans *trans, | |||
201 | return -EINVAL; | 201 | return -EINVAL; |
202 | } | 202 | } |
203 | 203 | ||
204 | ret = iwlagn_load_section(trans, "INST", &image->code, | 204 | ret = iwl_load_section(trans, "INST", &image->code, |
205 | IWLAGN_RTC_INST_LOWER_BOUND); | 205 | IWLAGN_RTC_INST_LOWER_BOUND); |
206 | if (ret) | 206 | if (ret) |
207 | return ret; | 207 | return ret; |
208 | 208 | ||
209 | return iwlagn_load_section(trans, "DATA", &image->data, | 209 | return iwl_load_section(trans, "DATA", &image->data, |
210 | IWLAGN_RTC_DATA_LOWER_BOUND); | 210 | IWLAGN_RTC_DATA_LOWER_BOUND); |
211 | } | 211 | } |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Calibration | 214 | * Calibration |
215 | */ | 215 | */ |
216 | static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) | 216 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) |
217 | { | 217 | { |
218 | struct iwl_calib_xtal_freq_cmd cmd; | 218 | struct iwl_calib_xtal_freq_cmd cmd; |
219 | __le16 *xtal_calib = | 219 | __le16 *xtal_calib = |
@@ -225,7 +225,7 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) | |||
225 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); | 225 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
226 | } | 226 | } |
227 | 227 | ||
228 | static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) | 228 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) |
229 | { | 229 | { |
230 | struct iwl_calib_temperature_offset_cmd cmd; | 230 | struct iwl_calib_temperature_offset_cmd cmd; |
231 | __le16 *offset_calib = | 231 | __le16 *offset_calib = |
@@ -242,7 +242,7 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) | |||
242 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); | 242 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
243 | } | 243 | } |
244 | 244 | ||
245 | static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv) | 245 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) |
246 | { | 246 | { |
247 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 247 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
248 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv, | 248 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv, |
@@ -277,7 +277,7 @@ static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv) | |||
277 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); | 277 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
278 | } | 278 | } |
279 | 279 | ||
280 | static int iwlagn_send_calib_cfg(struct iwl_priv *priv) | 280 | static int iwl_send_calib_cfg(struct iwl_trans *trans) |
281 | { | 281 | { |
282 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | 282 | struct iwl_calib_cfg_cmd calib_cfg_cmd; |
283 | struct iwl_host_cmd cmd = { | 283 | struct iwl_host_cmd cmd = { |
@@ -293,7 +293,7 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv) | |||
293 | calib_cfg_cmd.ucd_calib_cfg.flags = | 293 | calib_cfg_cmd.ucd_calib_cfg.flags = |
294 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; | 294 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; |
295 | 295 | ||
296 | return iwl_trans_send_cmd(trans(priv), &cmd); | 296 | return iwl_trans_send_cmd(trans, &cmd); |
297 | } | 297 | } |
298 | 298 | ||
299 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 299 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
@@ -326,14 +326,14 @@ int iwlagn_init_alive_start(struct iwl_priv *priv) | |||
326 | * no need to close the envlope since we are going | 326 | * no need to close the envlope since we are going |
327 | * to load the runtime uCode later. | 327 | * to load the runtime uCode later. |
328 | */ | 328 | */ |
329 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | 329 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN, |
330 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 330 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
331 | if (ret) | 331 | if (ret) |
332 | return ret; | 332 | return ret; |
333 | 333 | ||
334 | } | 334 | } |
335 | 335 | ||
336 | ret = iwlagn_send_calib_cfg(priv); | 336 | ret = iwl_send_calib_cfg(trans(priv)); |
337 | if (ret) | 337 | if (ret) |
338 | return ret; | 338 | return ret; |
339 | 339 | ||
@@ -343,15 +343,15 @@ int iwlagn_init_alive_start(struct iwl_priv *priv) | |||
343 | */ | 343 | */ |
344 | if (priv->cfg->need_temp_offset_calib) { | 344 | if (priv->cfg->need_temp_offset_calib) { |
345 | if (priv->cfg->temp_offset_v2) | 345 | if (priv->cfg->temp_offset_v2) |
346 | return iwlagn_set_temperature_offset_calib_v2(priv); | 346 | return iwl_set_temperature_offset_calib_v2(priv); |
347 | else | 347 | else |
348 | return iwlagn_set_temperature_offset_calib(priv); | 348 | return iwl_set_temperature_offset_calib(priv); |
349 | } | 349 | } |
350 | 350 | ||
351 | return 0; | 351 | return 0; |
352 | } | 352 | } |
353 | 353 | ||
354 | static int iwlagn_send_wimax_coex(struct iwl_priv *priv) | 354 | static int iwl_send_wimax_coex(struct iwl_priv *priv) |
355 | { | 355 | { |
356 | struct iwl_wimax_coex_cmd coex_cmd; | 356 | struct iwl_wimax_coex_cmd coex_cmd; |
357 | 357 | ||
@@ -379,7 +379,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv) | |||
379 | sizeof(coex_cmd), &coex_cmd); | 379 | sizeof(coex_cmd), &coex_cmd); |
380 | } | 380 | } |
381 | 381 | ||
382 | static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | 382 | static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { |
383 | ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | | 383 | ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | |
384 | (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), | 384 | (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), |
385 | ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | | 385 | ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | |
@@ -401,42 +401,42 @@ static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | |||
401 | 0, 0, 0, 0, 0, 0, 0 | 401 | 0, 0, 0, 0, 0, 0, 0 |
402 | }; | 402 | }; |
403 | 403 | ||
404 | void iwlagn_send_prio_tbl(struct iwl_priv *priv) | 404 | void iwl_send_prio_tbl(struct iwl_trans *trans) |
405 | { | 405 | { |
406 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; | 406 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; |
407 | 407 | ||
408 | memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl, | 408 | memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, |
409 | sizeof(iwlagn_bt_prio_tbl)); | 409 | sizeof(iwl_bt_prio_tbl)); |
410 | if (iwl_trans_send_cmd_pdu(trans(priv), | 410 | if (iwl_trans_send_cmd_pdu(trans, |
411 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, | 411 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, |
412 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) | 412 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) |
413 | IWL_ERR(priv, "failed to send BT prio tbl command\n"); | 413 | IWL_ERR(trans, "failed to send BT prio tbl command\n"); |
414 | } | 414 | } |
415 | 415 | ||
416 | int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) | 416 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type) |
417 | { | 417 | { |
418 | struct iwl_bt_coex_prot_env_cmd env_cmd; | 418 | struct iwl_bt_coex_prot_env_cmd env_cmd; |
419 | int ret; | 419 | int ret; |
420 | 420 | ||
421 | env_cmd.action = action; | 421 | env_cmd.action = action; |
422 | env_cmd.type = type; | 422 | env_cmd.type = type; |
423 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 423 | ret = iwl_trans_send_cmd_pdu(trans, |
424 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, | 424 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, |
425 | sizeof(env_cmd), &env_cmd); | 425 | sizeof(env_cmd), &env_cmd); |
426 | if (ret) | 426 | if (ret) |
427 | IWL_ERR(priv, "failed to send BT env command\n"); | 427 | IWL_ERR(trans, "failed to send BT env command\n"); |
428 | return ret; | 428 | return ret; |
429 | } | 429 | } |
430 | 430 | ||
431 | 431 | ||
432 | static int iwlagn_alive_notify(struct iwl_priv *priv) | 432 | static int iwl_alive_notify(struct iwl_priv *priv) |
433 | { | 433 | { |
434 | struct iwl_rxon_context *ctx; | 434 | struct iwl_rxon_context *ctx; |
435 | int ret; | 435 | int ret; |
436 | 436 | ||
437 | if (!priv->tx_cmd_pool) | 437 | if (!priv->tx_cmd_pool) |
438 | priv->tx_cmd_pool = | 438 | priv->tx_cmd_pool = |
439 | kmem_cache_create("iwlagn_dev_cmd", | 439 | kmem_cache_create("iwl_dev_cmd", |
440 | sizeof(struct iwl_device_cmd), | 440 | sizeof(struct iwl_device_cmd), |
441 | sizeof(void *), 0, NULL); | 441 | sizeof(void *), 0, NULL); |
442 | 442 | ||
@@ -447,12 +447,12 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) | |||
447 | for_each_context(priv, ctx) | 447 | for_each_context(priv, ctx) |
448 | ctx->last_tx_rejected = false; | 448 | ctx->last_tx_rejected = false; |
449 | 449 | ||
450 | ret = iwlagn_send_wimax_coex(priv); | 450 | ret = iwl_send_wimax_coex(priv); |
451 | if (ret) | 451 | if (ret) |
452 | return ret; | 452 | return ret; |
453 | 453 | ||
454 | if (!priv->cfg->no_xtal_calib) { | 454 | if (!priv->cfg->no_xtal_calib) { |
455 | ret = iwlagn_set_Xtal_calib(priv); | 455 | ret = iwl_set_Xtal_calib(priv); |
456 | if (ret) | 456 | if (ret) |
457 | return ret; | 457 | return ret; |
458 | } | 458 | } |
@@ -548,7 +548,7 @@ struct iwlagn_alive_data { | |||
548 | u8 subtype; | 548 | u8 subtype; |
549 | }; | 549 | }; |
550 | 550 | ||
551 | static void iwlagn_alive_fn(struct iwl_priv *priv, | 551 | static void iwl_alive_fn(struct iwl_priv *priv, |
552 | struct iwl_rx_packet *pkt, | 552 | struct iwl_rx_packet *pkt, |
553 | void *data) | 553 | void *data) |
554 | { | 554 | { |
@@ -571,6 +571,70 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, | |||
571 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; | 571 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; |
572 | } | 572 | } |
573 | 573 | ||
574 | /* notification wait support */ | ||
575 | void iwl_init_notification_wait(struct iwl_shared *shrd, | ||
576 | struct iwl_notification_wait *wait_entry, | ||
577 | u8 cmd, | ||
578 | void (*fn)(struct iwl_priv *priv, | ||
579 | struct iwl_rx_packet *pkt, | ||
580 | void *data), | ||
581 | void *fn_data) | ||
582 | { | ||
583 | wait_entry->fn = fn; | ||
584 | wait_entry->fn_data = fn_data; | ||
585 | wait_entry->cmd = cmd; | ||
586 | wait_entry->triggered = false; | ||
587 | wait_entry->aborted = false; | ||
588 | |||
589 | spin_lock_bh(&shrd->notif_wait_lock); | ||
590 | list_add(&wait_entry->list, &shrd->notif_waits); | ||
591 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
592 | } | ||
593 | |||
594 | int iwl_wait_notification(struct iwl_shared *shrd, | ||
595 | struct iwl_notification_wait *wait_entry, | ||
596 | unsigned long timeout) | ||
597 | { | ||
598 | int ret; | ||
599 | |||
600 | ret = wait_event_timeout(shrd->notif_waitq, | ||
601 | wait_entry->triggered || wait_entry->aborted, | ||
602 | timeout); | ||
603 | |||
604 | spin_lock_bh(&shrd->notif_wait_lock); | ||
605 | list_del(&wait_entry->list); | ||
606 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
607 | |||
608 | if (wait_entry->aborted) | ||
609 | return -EIO; | ||
610 | |||
611 | /* return value is always >= 0 */ | ||
612 | if (ret <= 0) | ||
613 | return -ETIMEDOUT; | ||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | void iwl_remove_notification(struct iwl_shared *shrd, | ||
618 | struct iwl_notification_wait *wait_entry) | ||
619 | { | ||
620 | spin_lock_bh(&shrd->notif_wait_lock); | ||
621 | list_del(&wait_entry->list); | ||
622 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
623 | } | ||
624 | |||
625 | void iwl_abort_notification_waits(struct iwl_shared *shrd) | ||
626 | { | ||
627 | unsigned long flags; | ||
628 | struct iwl_notification_wait *wait_entry; | ||
629 | |||
630 | spin_lock_irqsave(&shrd->notif_wait_lock, flags); | ||
631 | list_for_each_entry(wait_entry, &shrd->notif_waits, list) | ||
632 | wait_entry->aborted = true; | ||
633 | spin_unlock_irqrestore(&shrd->notif_wait_lock, flags); | ||
634 | |||
635 | wake_up_all(&shrd->notif_waitq); | ||
636 | } | ||
637 | |||
574 | #define UCODE_ALIVE_TIMEOUT HZ | 638 | #define UCODE_ALIVE_TIMEOUT HZ |
575 | #define UCODE_CALIB_TIMEOUT (2*HZ) | 639 | #define UCODE_CALIB_TIMEOUT (2*HZ) |
576 | 640 | ||
@@ -579,41 +643,43 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
579 | { | 643 | { |
580 | struct iwl_notification_wait alive_wait; | 644 | struct iwl_notification_wait alive_wait; |
581 | struct iwlagn_alive_data alive_data; | 645 | struct iwlagn_alive_data alive_data; |
646 | struct iwl_trans *trans = trans(priv); | ||
582 | int ret; | 647 | int ret; |
583 | enum iwl_ucode_type old_type; | 648 | enum iwl_ucode_type old_type; |
584 | 649 | ||
585 | ret = iwl_trans_start_device(trans(priv)); | 650 | ret = iwl_trans_start_device(trans); |
586 | if (ret) | 651 | if (ret) |
587 | return ret; | 652 | return ret; |
588 | 653 | ||
589 | iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE, | 654 | iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, |
590 | iwlagn_alive_fn, &alive_data); | 655 | iwl_alive_fn, &alive_data); |
591 | 656 | ||
592 | old_type = priv->ucode_type; | 657 | old_type = trans->shrd->ucode_type; |
593 | priv->ucode_type = ucode_type; | 658 | trans->shrd->ucode_type = ucode_type; |
594 | 659 | ||
595 | ret = iwlagn_load_given_ucode(trans(priv), ucode_type); | 660 | ret = iwl_load_given_ucode(trans, ucode_type); |
596 | if (ret) { | 661 | if (ret) { |
597 | priv->ucode_type = old_type; | 662 | trans->shrd->ucode_type = old_type; |
598 | iwlagn_remove_notification(priv, &alive_wait); | 663 | iwl_remove_notification(trans->shrd, &alive_wait); |
599 | return ret; | 664 | return ret; |
600 | } | 665 | } |
601 | 666 | ||
602 | iwl_trans_kick_nic(trans(priv)); | 667 | iwl_trans_kick_nic(trans); |
603 | 668 | ||
604 | /* | 669 | /* |
605 | * Some things may run in the background now, but we | 670 | * Some things may run in the background now, but we |
606 | * just wait for the ALIVE notification here. | 671 | * just wait for the ALIVE notification here. |
607 | */ | 672 | */ |
608 | ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT); | 673 | ret = iwl_wait_notification(trans->shrd, &alive_wait, |
674 | UCODE_ALIVE_TIMEOUT); | ||
609 | if (ret) { | 675 | if (ret) { |
610 | priv->ucode_type = old_type; | 676 | trans->shrd->ucode_type = old_type; |
611 | return ret; | 677 | return ret; |
612 | } | 678 | } |
613 | 679 | ||
614 | if (!alive_data.valid) { | 680 | if (!alive_data.valid) { |
615 | IWL_ERR(priv, "Loaded ucode is not valid!\n"); | 681 | IWL_ERR(priv, "Loaded ucode is not valid!\n"); |
616 | priv->ucode_type = old_type; | 682 | trans->shrd->ucode_type = old_type; |
617 | return -EIO; | 683 | return -EIO; |
618 | } | 684 | } |
619 | 685 | ||
@@ -623,9 +689,9 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
623 | * skip it for WoWLAN. | 689 | * skip it for WoWLAN. |
624 | */ | 690 | */ |
625 | if (ucode_type != IWL_UCODE_WOWLAN) { | 691 | if (ucode_type != IWL_UCODE_WOWLAN) { |
626 | ret = iwl_verify_ucode(trans(priv), ucode_type); | 692 | ret = iwl_verify_ucode(trans, ucode_type); |
627 | if (ret) { | 693 | if (ret) { |
628 | priv->ucode_type = old_type; | 694 | trans->shrd->ucode_type = old_type; |
629 | return ret; | 695 | return ret; |
630 | } | 696 | } |
631 | 697 | ||
@@ -633,11 +699,11 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
633 | msleep(5); | 699 | msleep(5); |
634 | } | 700 | } |
635 | 701 | ||
636 | ret = iwlagn_alive_notify(priv); | 702 | ret = iwl_alive_notify(priv); |
637 | if (ret) { | 703 | if (ret) { |
638 | IWL_WARN(priv, | 704 | IWL_WARN(priv, |
639 | "Could not complete ALIVE transition: %d\n", ret); | 705 | "Could not complete ALIVE transition: %d\n", ret); |
640 | priv->ucode_type = old_type; | 706 | trans->shrd->ucode_type = old_type; |
641 | return ret; | 707 | return ret; |
642 | } | 708 | } |
643 | 709 | ||
@@ -655,10 +721,10 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
655 | if (!trans(priv)->ucode_init.code.len) | 721 | if (!trans(priv)->ucode_init.code.len) |
656 | return 0; | 722 | return 0; |
657 | 723 | ||
658 | if (priv->ucode_type != IWL_UCODE_NONE) | 724 | if (priv->shrd->ucode_type != IWL_UCODE_NONE) |
659 | return 0; | 725 | return 0; |
660 | 726 | ||
661 | iwlagn_init_notification_wait(priv, &calib_wait, | 727 | iwl_init_notification_wait(priv->shrd, &calib_wait, |
662 | CALIBRATION_COMPLETE_NOTIFICATION, | 728 | CALIBRATION_COMPLETE_NOTIFICATION, |
663 | NULL, NULL); | 729 | NULL, NULL); |
664 | 730 | ||
@@ -675,12 +741,13 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
675 | * Some things may run in the background now, but we | 741 | * Some things may run in the background now, but we |
676 | * just wait for the calibration complete notification. | 742 | * just wait for the calibration complete notification. |
677 | */ | 743 | */ |
678 | ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT); | 744 | ret = iwl_wait_notification(priv->shrd, &calib_wait, |
745 | UCODE_CALIB_TIMEOUT); | ||
679 | 746 | ||
680 | goto out; | 747 | goto out; |
681 | 748 | ||
682 | error: | 749 | error: |
683 | iwlagn_remove_notification(priv, &calib_wait); | 750 | iwl_remove_notification(priv->shrd, &calib_wait); |
684 | out: | 751 | out: |
685 | /* Whatever happened, stop the device */ | 752 | /* Whatever happened, stop the device */ |
686 | iwl_trans_stop_device(trans(priv)); | 753 | iwl_trans_stop_device(trans(priv)); |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 89f34ad8d34a..d1d84e0e30fc 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -635,7 +635,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
635 | if (channel && | 635 | if (channel && |
636 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { | 636 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { |
637 | bss = cfg80211_inform_bss(wiphy, channel, | 637 | bss = cfg80211_inform_bss(wiphy, channel, |
638 | bssid, le64_to_cpu(*(__le64 *)tsfdesc), | 638 | bssid, get_unaligned_le64(tsfdesc), |
639 | capa, intvl, ie, ielen, | 639 | capa, intvl, ie, ielen, |
640 | LBS_SCAN_RSSI_TO_MBM(rssi), | 640 | LBS_SCAN_RSSI_TO_MBM(rssi), |
641 | GFP_KERNEL); | 641 | GFP_KERNEL); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 0c87f42fa660..50b1ee7721e9 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -995,6 +995,7 @@ static int if_spi_host_to_card(struct lbs_private *priv, | |||
995 | spin_unlock_irqrestore(&card->buffer_lock, flags); | 995 | spin_unlock_irqrestore(&card->buffer_lock, flags); |
996 | break; | 996 | break; |
997 | default: | 997 | default: |
998 | kfree(packet); | ||
998 | netdev_err(priv->dev, "can't transfer buffer of type %d\n", | 999 | netdev_err(priv->dev, "can't transfer buffer of type %d\n", |
999 | type); | 1000 | type); |
1000 | err = -EINVAL; | 1001 | err = -EINVAL; |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 8a18bcc23b26..b8b9d37b01a9 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -819,8 +819,10 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
819 | wildcard_ssid_tlv->header.len = cpu_to_le16( | 819 | wildcard_ssid_tlv->header.len = cpu_to_le16( |
820 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> | 820 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> |
821 | max_ssid_length))); | 821 | max_ssid_length))); |
822 | wildcard_ssid_tlv->max_ssid_length = | 822 | |
823 | user_scan_in->ssid_list[ssid_idx].max_len; | 823 | /* max_ssid_length = 0 tells firmware to perform |
824 | specific scan for the SSID filled */ | ||
825 | wildcard_ssid_tlv->max_ssid_length = 0; | ||
824 | 826 | ||
825 | memcpy(wildcard_ssid_tlv->ssid, | 827 | memcpy(wildcard_ssid_tlv->ssid, |
826 | user_scan_in->ssid_list[ssid_idx].ssid, | 828 | user_scan_in->ssid_list[ssid_idx].ssid, |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 546551389a1d..7faed62c6378 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -584,8 +584,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
584 | mutex_lock(&priv->mutex); | 584 | mutex_lock(&priv->mutex); |
585 | WARN_ON(priv->fw_state != FW_STATE_READY); | 585 | WARN_ON(priv->fw_state != FW_STATE_READY); |
586 | 586 | ||
587 | cancel_work_sync(&priv->work); | ||
588 | |||
589 | p54spi_power_off(priv); | 587 | p54spi_power_off(priv); |
590 | spin_lock_irqsave(&priv->tx_lock, flags); | 588 | spin_lock_irqsave(&priv->tx_lock, flags); |
591 | INIT_LIST_HEAD(&priv->tx_pending); | 589 | INIT_LIST_HEAD(&priv->tx_pending); |
@@ -593,6 +591,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
593 | 591 | ||
594 | priv->fw_state = FW_STATE_OFF; | 592 | priv->fw_state = FW_STATE_OFF; |
595 | mutex_unlock(&priv->mutex); | 593 | mutex_unlock(&priv->mutex); |
594 | |||
595 | cancel_work_sync(&priv->work); | ||
596 | } | 596 | } |
597 | 597 | ||
598 | static int __devinit p54spi_probe(struct spi_device *spi) | 598 | static int __devinit p54spi_probe(struct spi_device *spi) |
@@ -652,6 +652,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
652 | init_completion(&priv->fw_comp); | 652 | init_completion(&priv->fw_comp); |
653 | INIT_LIST_HEAD(&priv->tx_pending); | 653 | INIT_LIST_HEAD(&priv->tx_pending); |
654 | mutex_init(&priv->mutex); | 654 | mutex_init(&priv->mutex); |
655 | spin_lock_init(&priv->tx_lock); | ||
655 | SET_IEEE80211_DEV(hw, &spi->dev); | 656 | SET_IEEE80211_DEV(hw, &spi->dev); |
656 | priv->common.open = p54spi_op_start; | 657 | priv->common.open = p54spi_op_start; |
657 | priv->common.stop = p54spi_op_stop; | 658 | priv->common.stop = p54spi_op_stop; |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index f83bc5a5e81f..4e44b1af119a 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -778,7 +778,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, | |||
778 | dwrq->flags = 0; | 778 | dwrq->flags = 0; |
779 | dwrq->length = 0; | 779 | dwrq->length = 0; |
780 | } | 780 | } |
781 | essid->octets[essid->length] = '\0'; | 781 | essid->octets[dwrq->length] = '\0'; |
782 | memcpy(extra, essid->octets, dwrq->length); | 782 | memcpy(extra, essid->octets, dwrq->length); |
783 | kfree(essid); | 783 | kfree(essid); |
784 | 784 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 25dab2987131..e5df380d4fbe 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -3773,7 +3773,7 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) | |||
3773 | /* Apparently the data is read from end to start */ | 3773 | /* Apparently the data is read from end to start */ |
3774 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); | 3774 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); |
3775 | /* The returned value is in CPU order, but eeprom is le */ | 3775 | /* The returned value is in CPU order, but eeprom is le */ |
3776 | rt2x00dev->eeprom[i] = cpu_to_le32(reg); | 3776 | *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg); |
3777 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); | 3777 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); |
3778 | *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); | 3778 | *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); |
3779 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); | 3779 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f1565792f270..377876315b8d 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -919,6 +919,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
919 | { USB_DEVICE(0x050d, 0x935b) }, | 919 | { USB_DEVICE(0x050d, 0x935b) }, |
920 | /* Buffalo */ | 920 | /* Buffalo */ |
921 | { USB_DEVICE(0x0411, 0x00e8) }, | 921 | { USB_DEVICE(0x0411, 0x00e8) }, |
922 | { USB_DEVICE(0x0411, 0x0158) }, | ||
922 | { USB_DEVICE(0x0411, 0x016f) }, | 923 | { USB_DEVICE(0x0411, 0x016f) }, |
923 | { USB_DEVICE(0x0411, 0x01a2) }, | 924 | { USB_DEVICE(0x0411, 0x01a2) }, |
924 | /* Corega */ | 925 | /* Corega */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2ec5c00235e6..99ff12d0c29d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -943,6 +943,7 @@ struct rt2x00_dev { | |||
943 | * Powersaving work | 943 | * Powersaving work |
944 | */ | 944 | */ |
945 | struct delayed_work autowakeup_work; | 945 | struct delayed_work autowakeup_work; |
946 | struct work_struct sleep_work; | ||
946 | 947 | ||
947 | /* | 948 | /* |
948 | * Data queue arrays for RX, TX, Beacon and ATIM. | 949 | * Data queue arrays for RX, TX, Beacon and ATIM. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e1fb2a8569be..c3e1aa7c1a80 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -465,6 +465,23 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie) | |||
465 | return NULL; | 465 | return NULL; |
466 | } | 466 | } |
467 | 467 | ||
468 | static void rt2x00lib_sleep(struct work_struct *work) | ||
469 | { | ||
470 | struct rt2x00_dev *rt2x00dev = | ||
471 | container_of(work, struct rt2x00_dev, sleep_work); | ||
472 | |||
473 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
474 | return; | ||
475 | |||
476 | /* | ||
477 | * Check again is powersaving is enabled, to prevent races from delayed | ||
478 | * work execution. | ||
479 | */ | ||
480 | if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) | ||
481 | rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, | ||
482 | IEEE80211_CONF_CHANGE_PS); | ||
483 | } | ||
484 | |||
468 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, | 485 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, |
469 | struct sk_buff *skb, | 486 | struct sk_buff *skb, |
470 | struct rxdone_entry_desc *rxdesc) | 487 | struct rxdone_entry_desc *rxdesc) |
@@ -512,8 +529,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, | |||
512 | cam |= (tim_ie->bitmap_ctrl & 0x01); | 529 | cam |= (tim_ie->bitmap_ctrl & 0x01); |
513 | 530 | ||
514 | if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) | 531 | if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) |
515 | rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, | 532 | queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work); |
516 | IEEE80211_CONF_CHANGE_PS); | ||
517 | } | 533 | } |
518 | 534 | ||
519 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, | 535 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, |
@@ -815,11 +831,11 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
815 | if (spec->supported_rates & SUPPORT_RATE_OFDM) | 831 | if (spec->supported_rates & SUPPORT_RATE_OFDM) |
816 | num_rates += 8; | 832 | num_rates += 8; |
817 | 833 | ||
818 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); | 834 | channels = kcalloc(spec->num_channels, sizeof(*channels), GFP_KERNEL); |
819 | if (!channels) | 835 | if (!channels) |
820 | return -ENOMEM; | 836 | return -ENOMEM; |
821 | 837 | ||
822 | rates = kzalloc(sizeof(*rates) * num_rates, GFP_KERNEL); | 838 | rates = kcalloc(num_rates, sizeof(*rates), GFP_KERNEL); |
823 | if (!rates) | 839 | if (!rates) |
824 | goto exit_free_channels; | 840 | goto exit_free_channels; |
825 | 841 | ||
@@ -1141,6 +1157,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1141 | 1157 | ||
1142 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 1158 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1143 | INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); | 1159 | INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); |
1160 | INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); | ||
1144 | 1161 | ||
1145 | /* | 1162 | /* |
1146 | * Let the driver probe the device to detect the capabilities. | 1163 | * Let the driver probe the device to detect the capabilities. |
@@ -1197,6 +1214,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1197 | */ | 1214 | */ |
1198 | cancel_work_sync(&rt2x00dev->intf_work); | 1215 | cancel_work_sync(&rt2x00dev->intf_work); |
1199 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); | 1216 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); |
1217 | cancel_work_sync(&rt2x00dev->sleep_work); | ||
1200 | if (rt2x00_is_usb(rt2x00dev)) { | 1218 | if (rt2x00_is_usb(rt2x00dev)) { |
1201 | del_timer_sync(&rt2x00dev->txstatus_timer); | 1219 | del_timer_sync(&rt2x00dev->txstatus_timer); |
1202 | cancel_work_sync(&rt2x00dev->rxdone_work); | 1220 | cancel_work_sync(&rt2x00dev->rxdone_work); |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index db5262844543..55c8e50f45fd 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -395,7 +395,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
395 | if (mac->link_state != MAC80211_LINKED) | 395 | if (mac->link_state != MAC80211_LINKED) |
396 | return; | 396 | return; |
397 | 397 | ||
398 | spin_lock(&rtlpriv->locks.lps_lock); | 398 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
399 | 399 | ||
400 | /* Idle for a while if we connect to AP a while ago. */ | 400 | /* Idle for a while if we connect to AP a while ago. */ |
401 | if (mac->cnt_after_linked >= 2) { | 401 | if (mac->cnt_after_linked >= 2) { |
@@ -407,7 +407,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
407 | } | 407 | } |
408 | } | 408 | } |
409 | 409 | ||
410 | spin_unlock(&rtlpriv->locks.lps_lock); | 410 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
411 | } | 411 | } |
412 | 412 | ||
413 | /*Leave the leisure power save mode.*/ | 413 | /*Leave the leisure power save mode.*/ |
@@ -416,8 +416,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
416 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 416 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
419 | unsigned long flags; | ||
419 | 420 | ||
420 | spin_lock(&rtlpriv->locks.lps_lock); | 421 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags); |
421 | 422 | ||
422 | if (ppsc->fwctrl_lps) { | 423 | if (ppsc->fwctrl_lps) { |
423 | if (ppsc->dot11_psmode != EACTIVE) { | 424 | if (ppsc->dot11_psmode != EACTIVE) { |
@@ -438,7 +439,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
438 | rtl_lps_set_psmode(hw, EACTIVE); | 439 | rtl_lps_set_psmode(hw, EACTIVE); |
439 | } | 440 | } |
440 | } | 441 | } |
441 | spin_unlock(&rtlpriv->locks.lps_lock); | 442 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags); |
442 | } | 443 | } |
443 | 444 | ||
444 | /* For sw LPS*/ | 445 | /* For sw LPS*/ |
@@ -539,9 +540,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
539 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | 540 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
540 | } | 541 | } |
541 | 542 | ||
542 | spin_lock(&rtlpriv->locks.lps_lock); | 543 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
543 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); | 544 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); |
544 | spin_unlock(&rtlpriv->locks.lps_lock); | 545 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
545 | } | 546 | } |
546 | 547 | ||
547 | void rtl_swlps_rfon_wq_callback(void *data) | 548 | void rtl_swlps_rfon_wq_callback(void *data) |
@@ -574,9 +575,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
574 | if (rtlpriv->link_info.busytraffic) | 575 | if (rtlpriv->link_info.busytraffic) |
575 | return; | 576 | return; |
576 | 577 | ||
577 | spin_lock(&rtlpriv->locks.lps_lock); | 578 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
578 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); | 579 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); |
579 | spin_unlock(&rtlpriv->locks.lps_lock); | 580 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
580 | 581 | ||
581 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | 582 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
582 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | 583 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index fa393dfe136c..931d97979b04 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | |||
@@ -262,10 +262,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) | |||
262 | u32 fwsize; | 262 | u32 fwsize; |
263 | enum version_8192c version = rtlhal->version; | 263 | enum version_8192c version = rtlhal->version; |
264 | 264 | ||
265 | pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); | ||
266 | if (!rtlhal->pfirmware) | 265 | if (!rtlhal->pfirmware) |
267 | return 1; | 266 | return 1; |
268 | 267 | ||
268 | pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); | ||
269 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; | 269 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; |
270 | pfwdata = (u8 *) rtlhal->pfirmware; | 270 | pfwdata = (u8 *) rtlhal->pfirmware; |
271 | fwsize = rtlhal->fwsize; | 271 | fwsize = rtlhal->fwsize; |