diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 314 |
1 files changed, 212 insertions, 102 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a8f2adfd799e..299fd9d59604 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -46,6 +46,181 @@ static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) | |||
46 | tx_resp->frame_count) & MAX_SN; | 46 | tx_resp->frame_count) & MAX_SN; |
47 | } | 47 | } |
48 | 48 | ||
49 | static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) | ||
50 | { | ||
51 | status &= TX_STATUS_MSK; | ||
52 | |||
53 | switch (status) { | ||
54 | case TX_STATUS_POSTPONE_DELAY: | ||
55 | priv->_agn.reply_tx_stats.pp_delay++; | ||
56 | break; | ||
57 | case TX_STATUS_POSTPONE_FEW_BYTES: | ||
58 | priv->_agn.reply_tx_stats.pp_few_bytes++; | ||
59 | break; | ||
60 | case TX_STATUS_POSTPONE_BT_PRIO: | ||
61 | priv->_agn.reply_tx_stats.pp_bt_prio++; | ||
62 | break; | ||
63 | case TX_STATUS_POSTPONE_QUIET_PERIOD: | ||
64 | priv->_agn.reply_tx_stats.pp_quiet_period++; | ||
65 | break; | ||
66 | case TX_STATUS_POSTPONE_CALC_TTAK: | ||
67 | priv->_agn.reply_tx_stats.pp_calc_ttak++; | ||
68 | break; | ||
69 | case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY: | ||
70 | priv->_agn.reply_tx_stats.int_crossed_retry++; | ||
71 | break; | ||
72 | case TX_STATUS_FAIL_SHORT_LIMIT: | ||
73 | priv->_agn.reply_tx_stats.short_limit++; | ||
74 | break; | ||
75 | case TX_STATUS_FAIL_LONG_LIMIT: | ||
76 | priv->_agn.reply_tx_stats.long_limit++; | ||
77 | break; | ||
78 | case TX_STATUS_FAIL_FIFO_UNDERRUN: | ||
79 | priv->_agn.reply_tx_stats.fifo_underrun++; | ||
80 | break; | ||
81 | case TX_STATUS_FAIL_DRAIN_FLOW: | ||
82 | priv->_agn.reply_tx_stats.drain_flow++; | ||
83 | break; | ||
84 | case TX_STATUS_FAIL_RFKILL_FLUSH: | ||
85 | priv->_agn.reply_tx_stats.rfkill_flush++; | ||
86 | break; | ||
87 | case TX_STATUS_FAIL_LIFE_EXPIRE: | ||
88 | priv->_agn.reply_tx_stats.life_expire++; | ||
89 | break; | ||
90 | case TX_STATUS_FAIL_DEST_PS: | ||
91 | priv->_agn.reply_tx_stats.dest_ps++; | ||
92 | break; | ||
93 | case TX_STATUS_FAIL_HOST_ABORTED: | ||
94 | priv->_agn.reply_tx_stats.host_abort++; | ||
95 | break; | ||
96 | case TX_STATUS_FAIL_BT_RETRY: | ||
97 | priv->_agn.reply_tx_stats.bt_retry++; | ||
98 | break; | ||
99 | case TX_STATUS_FAIL_STA_INVALID: | ||
100 | priv->_agn.reply_tx_stats.sta_invalid++; | ||
101 | break; | ||
102 | case TX_STATUS_FAIL_FRAG_DROPPED: | ||
103 | priv->_agn.reply_tx_stats.frag_drop++; | ||
104 | break; | ||
105 | case TX_STATUS_FAIL_TID_DISABLE: | ||
106 | priv->_agn.reply_tx_stats.tid_disable++; | ||
107 | break; | ||
108 | case TX_STATUS_FAIL_FIFO_FLUSHED: | ||
109 | priv->_agn.reply_tx_stats.fifo_flush++; | ||
110 | break; | ||
111 | case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL: | ||
112 | priv->_agn.reply_tx_stats.insuff_cf_poll++; | ||
113 | break; | ||
114 | case TX_STATUS_FAIL_PASSIVE_NO_RX: | ||
115 | priv->_agn.reply_tx_stats.fail_hw_drop++; | ||
116 | break; | ||
117 | case TX_STATUS_FAIL_NO_BEACON_ON_RADAR: | ||
118 | priv->_agn.reply_tx_stats.sta_color_mismatch++; | ||
119 | break; | ||
120 | default: | ||
121 | priv->_agn.reply_tx_stats.unknown++; | ||
122 | break; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) | ||
127 | { | ||
128 | status &= AGG_TX_STATUS_MSK; | ||
129 | |||
130 | switch (status) { | ||
131 | case AGG_TX_STATE_UNDERRUN_MSK: | ||
132 | priv->_agn.reply_agg_tx_stats.underrun++; | ||
133 | break; | ||
134 | case AGG_TX_STATE_BT_PRIO_MSK: | ||
135 | priv->_agn.reply_agg_tx_stats.bt_prio++; | ||
136 | break; | ||
137 | case AGG_TX_STATE_FEW_BYTES_MSK: | ||
138 | priv->_agn.reply_agg_tx_stats.few_bytes++; | ||
139 | break; | ||
140 | case AGG_TX_STATE_ABORT_MSK: | ||
141 | priv->_agn.reply_agg_tx_stats.abort++; | ||
142 | break; | ||
143 | case AGG_TX_STATE_LAST_SENT_TTL_MSK: | ||
144 | priv->_agn.reply_agg_tx_stats.last_sent_ttl++; | ||
145 | break; | ||
146 | case AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK: | ||
147 | priv->_agn.reply_agg_tx_stats.last_sent_try++; | ||
148 | break; | ||
149 | case AGG_TX_STATE_LAST_SENT_BT_KILL_MSK: | ||
150 | priv->_agn.reply_agg_tx_stats.last_sent_bt_kill++; | ||
151 | break; | ||
152 | case AGG_TX_STATE_SCD_QUERY_MSK: | ||
153 | priv->_agn.reply_agg_tx_stats.scd_query++; | ||
154 | break; | ||
155 | case AGG_TX_STATE_TEST_BAD_CRC32_MSK: | ||
156 | priv->_agn.reply_agg_tx_stats.bad_crc32++; | ||
157 | break; | ||
158 | case AGG_TX_STATE_RESPONSE_MSK: | ||
159 | priv->_agn.reply_agg_tx_stats.response++; | ||
160 | break; | ||
161 | case AGG_TX_STATE_DUMP_TX_MSK: | ||
162 | priv->_agn.reply_agg_tx_stats.dump_tx++; | ||
163 | break; | ||
164 | case AGG_TX_STATE_DELAY_TX_MSK: | ||
165 | priv->_agn.reply_agg_tx_stats.delay_tx++; | ||
166 | break; | ||
167 | default: | ||
168 | priv->_agn.reply_agg_tx_stats.unknown++; | ||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static void iwlagn_set_tx_status(struct iwl_priv *priv, | ||
174 | struct ieee80211_tx_info *info, | ||
175 | struct iwl5000_tx_resp *tx_resp, | ||
176 | int txq_id, bool is_agg) | ||
177 | { | ||
178 | u16 status = le16_to_cpu(tx_resp->status.status); | ||
179 | |||
180 | info->status.rates[0].count = tx_resp->failure_frame + 1; | ||
181 | if (is_agg) | ||
182 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
183 | info->flags |= iwl_tx_status_to_mac80211(status); | ||
184 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | ||
185 | info); | ||
186 | if (!iwl_is_tx_success(status)) | ||
187 | iwlagn_count_tx_err_status(priv, status); | ||
188 | |||
189 | IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " | ||
190 | "0x%x retries %d\n", | ||
191 | txq_id, | ||
192 | iwl_get_tx_fail_reason(status), status, | ||
193 | le32_to_cpu(tx_resp->rate_n_flags), | ||
194 | tx_resp->failure_frame); | ||
195 | } | ||
196 | |||
197 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
198 | #define AGG_TX_STATE_FAIL(x) case AGG_TX_STATE_ ## x: return #x | ||
199 | |||
200 | const char *iwl_get_agg_tx_fail_reason(u16 status) | ||
201 | { | ||
202 | status &= AGG_TX_STATUS_MSK; | ||
203 | switch (status) { | ||
204 | case AGG_TX_STATE_TRANSMITTED: | ||
205 | return "SUCCESS"; | ||
206 | AGG_TX_STATE_FAIL(UNDERRUN_MSK); | ||
207 | AGG_TX_STATE_FAIL(BT_PRIO_MSK); | ||
208 | AGG_TX_STATE_FAIL(FEW_BYTES_MSK); | ||
209 | AGG_TX_STATE_FAIL(ABORT_MSK); | ||
210 | AGG_TX_STATE_FAIL(LAST_SENT_TTL_MSK); | ||
211 | AGG_TX_STATE_FAIL(LAST_SENT_TRY_CNT_MSK); | ||
212 | AGG_TX_STATE_FAIL(LAST_SENT_BT_KILL_MSK); | ||
213 | AGG_TX_STATE_FAIL(SCD_QUERY_MSK); | ||
214 | AGG_TX_STATE_FAIL(TEST_BAD_CRC32_MSK); | ||
215 | AGG_TX_STATE_FAIL(RESPONSE_MSK); | ||
216 | AGG_TX_STATE_FAIL(DUMP_TX_MSK); | ||
217 | AGG_TX_STATE_FAIL(DELAY_TX_MSK); | ||
218 | } | ||
219 | |||
220 | return "UNKNOWN"; | ||
221 | } | ||
222 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
223 | |||
49 | static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, | 224 | static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, |
50 | struct iwl_ht_agg *agg, | 225 | struct iwl_ht_agg *agg, |
51 | struct iwl5000_tx_resp *tx_resp, | 226 | struct iwl5000_tx_resp *tx_resp, |
@@ -53,9 +228,7 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, | |||
53 | { | 228 | { |
54 | u16 status; | 229 | u16 status; |
55 | struct agg_tx_status *frame_status = &tx_resp->status; | 230 | struct agg_tx_status *frame_status = &tx_resp->status; |
56 | struct ieee80211_tx_info *info = NULL; | ||
57 | struct ieee80211_hdr *hdr = NULL; | 231 | struct ieee80211_hdr *hdr = NULL; |
58 | u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | ||
59 | int i, sh, idx; | 232 | int i, sh, idx; |
60 | u16 seq; | 233 | u16 seq; |
61 | 234 | ||
@@ -64,31 +237,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, | |||
64 | 237 | ||
65 | agg->frame_count = tx_resp->frame_count; | 238 | agg->frame_count = tx_resp->frame_count; |
66 | agg->start_idx = start_idx; | 239 | agg->start_idx = start_idx; |
67 | agg->rate_n_flags = rate_n_flags; | 240 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
68 | agg->bitmap = 0; | 241 | agg->bitmap = 0; |
69 | 242 | ||
70 | /* # frames attempted by Tx command */ | 243 | /* # frames attempted by Tx command */ |
71 | if (agg->frame_count == 1) { | 244 | if (agg->frame_count == 1) { |
72 | /* Only one frame was attempted; no block-ack will arrive */ | 245 | /* Only one frame was attempted; no block-ack will arrive */ |
73 | status = le16_to_cpu(frame_status[0].status); | ||
74 | idx = start_idx; | 246 | idx = start_idx; |
75 | 247 | ||
76 | /* FIXME: code repetition */ | ||
77 | IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", | 248 | IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", |
78 | agg->frame_count, agg->start_idx, idx); | 249 | agg->frame_count, agg->start_idx, idx); |
79 | 250 | iwlagn_set_tx_status(priv, | |
80 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); | 251 | IEEE80211_SKB_CB( |
81 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 252 | priv->txq[txq_id].txb[idx].skb), |
82 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 253 | tx_resp, txq_id, true); |
83 | info->flags |= iwl_tx_status_to_mac80211(status); | ||
84 | iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info); | ||
85 | |||
86 | /* FIXME: code repetition end */ | ||
87 | |||
88 | IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", | ||
89 | status & 0xff, tx_resp->failure_frame); | ||
90 | IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags); | ||
91 | |||
92 | agg->wait_for_ba = 0; | 254 | agg->wait_for_ba = 0; |
93 | } else { | 255 | } else { |
94 | /* Two or more frames were attempted; expect block-ack */ | 256 | /* Two or more frames were attempted; expect block-ack */ |
@@ -109,12 +271,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, | |||
109 | idx = SEQ_TO_INDEX(seq); | 271 | idx = SEQ_TO_INDEX(seq); |
110 | txq_id = SEQ_TO_QUEUE(seq); | 272 | txq_id = SEQ_TO_QUEUE(seq); |
111 | 273 | ||
274 | if (status & AGG_TX_STATUS_MSK) | ||
275 | iwlagn_count_agg_tx_err_status(priv, status); | ||
276 | |||
112 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | | 277 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | |
113 | AGG_TX_STATE_ABORT_MSK)) | 278 | AGG_TX_STATE_ABORT_MSK)) |
114 | continue; | 279 | continue; |
115 | 280 | ||
116 | IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", | 281 | IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", |
117 | agg->frame_count, txq_id, idx); | 282 | agg->frame_count, txq_id, idx); |
283 | IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), " | ||
284 | "try-count (0x%08x)\n", | ||
285 | iwl_get_agg_tx_fail_reason(status), | ||
286 | status & AGG_TX_STATUS_MSK, | ||
287 | status & AGG_TX_TRY_MSK); | ||
118 | 288 | ||
119 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); | 289 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); |
120 | if (!hdr) { | 290 | if (!hdr) { |
@@ -281,20 +451,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
281 | } | 451 | } |
282 | } else { | 452 | } else { |
283 | BUG_ON(txq_id != txq->swq_id); | 453 | BUG_ON(txq_id != txq->swq_id); |
284 | 454 | iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); | |
285 | info->status.rates[0].count = tx_resp->failure_frame + 1; | ||
286 | info->flags |= iwl_tx_status_to_mac80211(status); | ||
287 | iwlagn_hwrate_to_tx_control(priv, | ||
288 | le32_to_cpu(tx_resp->rate_n_flags), | ||
289 | info); | ||
290 | |||
291 | IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " | ||
292 | "0x%x retries %d\n", | ||
293 | txq_id, | ||
294 | iwl_get_tx_fail_reason(status), status, | ||
295 | le32_to_cpu(tx_resp->rate_n_flags), | ||
296 | tx_resp->failure_frame); | ||
297 | |||
298 | freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); | 455 | freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); |
299 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | 456 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
300 | 457 | ||
@@ -1154,7 +1311,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
1154 | return added; | 1311 | return added; |
1155 | } | 1312 | } |
1156 | 1313 | ||
1157 | void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | 1314 | int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) |
1158 | { | 1315 | { |
1159 | struct iwl_host_cmd cmd = { | 1316 | struct iwl_host_cmd cmd = { |
1160 | .id = REPLY_SCAN_CMD, | 1317 | .id = REPLY_SCAN_CMD, |
@@ -1162,7 +1319,6 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1162 | .flags = CMD_SIZE_HUGE, | 1319 | .flags = CMD_SIZE_HUGE, |
1163 | }; | 1320 | }; |
1164 | struct iwl_scan_cmd *scan; | 1321 | struct iwl_scan_cmd *scan; |
1165 | struct ieee80211_conf *conf = NULL; | ||
1166 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 1322 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
1167 | u32 rate_flags = 0; | 1323 | u32 rate_flags = 0; |
1168 | u16 cmd_len; | 1324 | u16 cmd_len; |
@@ -1175,59 +1331,20 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1175 | int chan_mod; | 1331 | int chan_mod; |
1176 | u8 active_chains; | 1332 | u8 active_chains; |
1177 | u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; | 1333 | u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; |
1334 | int ret; | ||
1335 | |||
1336 | lockdep_assert_held(&priv->mutex); | ||
1178 | 1337 | ||
1179 | if (vif) | 1338 | if (vif) |
1180 | ctx = iwl_rxon_ctx_from_vif(vif); | 1339 | ctx = iwl_rxon_ctx_from_vif(vif); |
1181 | 1340 | ||
1182 | conf = ieee80211_get_hw_conf(priv->hw); | ||
1183 | |||
1184 | cancel_delayed_work(&priv->scan_check); | ||
1185 | |||
1186 | if (!iwl_is_ready(priv)) { | ||
1187 | IWL_WARN(priv, "request scan called when driver not ready.\n"); | ||
1188 | goto done; | ||
1189 | } | ||
1190 | |||
1191 | /* Make sure the scan wasn't canceled before this queued work | ||
1192 | * was given the chance to run... */ | ||
1193 | if (!test_bit(STATUS_SCANNING, &priv->status)) | ||
1194 | goto done; | ||
1195 | |||
1196 | /* This should never be called or scheduled if there is currently | ||
1197 | * a scan active in the hardware. */ | ||
1198 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
1199 | IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. " | ||
1200 | "Ignoring second request.\n"); | ||
1201 | goto done; | ||
1202 | } | ||
1203 | |||
1204 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
1205 | IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n"); | ||
1206 | goto done; | ||
1207 | } | ||
1208 | |||
1209 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
1210 | IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n"); | ||
1211 | goto done; | ||
1212 | } | ||
1213 | |||
1214 | if (iwl_is_rfkill(priv)) { | ||
1215 | IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n"); | ||
1216 | goto done; | ||
1217 | } | ||
1218 | |||
1219 | if (!test_bit(STATUS_READY, &priv->status)) { | ||
1220 | IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n"); | ||
1221 | goto done; | ||
1222 | } | ||
1223 | |||
1224 | if (!priv->scan_cmd) { | 1341 | if (!priv->scan_cmd) { |
1225 | priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + | 1342 | priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + |
1226 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); | 1343 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); |
1227 | if (!priv->scan_cmd) { | 1344 | if (!priv->scan_cmd) { |
1228 | IWL_DEBUG_SCAN(priv, | 1345 | IWL_DEBUG_SCAN(priv, |
1229 | "fail to allocate memory for scan\n"); | 1346 | "fail to allocate memory for scan\n"); |
1230 | goto done; | 1347 | return -ENOMEM; |
1231 | } | 1348 | } |
1232 | } | 1349 | } |
1233 | scan = priv->scan_cmd; | 1350 | scan = priv->scan_cmd; |
@@ -1334,8 +1451,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1334 | IWL_GOOD_CRC_TH_NEVER; | 1451 | IWL_GOOD_CRC_TH_NEVER; |
1335 | break; | 1452 | break; |
1336 | default: | 1453 | default: |
1337 | IWL_WARN(priv, "Invalid scan band count\n"); | 1454 | IWL_WARN(priv, "Invalid scan band\n"); |
1338 | goto done; | 1455 | return -EIO; |
1339 | } | 1456 | } |
1340 | 1457 | ||
1341 | band = priv->scan_band; | 1458 | band = priv->scan_band; |
@@ -1415,7 +1532,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1415 | } | 1532 | } |
1416 | if (scan->channel_count == 0) { | 1533 | if (scan->channel_count == 0) { |
1417 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); | 1534 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); |
1418 | goto done; | 1535 | return -EIO; |
1419 | } | 1536 | } |
1420 | 1537 | ||
1421 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 1538 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + |
@@ -1423,30 +1540,21 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1423 | cmd.data = scan; | 1540 | cmd.data = scan; |
1424 | scan->len = cpu_to_le16(cmd.len); | 1541 | scan->len = cpu_to_le16(cmd.len); |
1425 | 1542 | ||
1426 | set_bit(STATUS_SCAN_HW, &priv->status); | 1543 | if (priv->cfg->ops->hcmd->set_pan_params) { |
1427 | 1544 | ret = priv->cfg->ops->hcmd->set_pan_params(priv); | |
1428 | if (priv->cfg->ops->hcmd->set_pan_params && | 1545 | if (ret) |
1429 | priv->cfg->ops->hcmd->set_pan_params(priv)) | 1546 | return ret; |
1430 | goto done; | 1547 | } |
1431 | 1548 | ||
1432 | if (iwl_send_cmd_sync(priv, &cmd)) | 1549 | set_bit(STATUS_SCAN_HW, &priv->status); |
1433 | goto done; | 1550 | ret = iwl_send_cmd_sync(priv, &cmd); |
1551 | if (ret) { | ||
1552 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
1553 | if (priv->cfg->ops->hcmd->set_pan_params) | ||
1554 | priv->cfg->ops->hcmd->set_pan_params(priv); | ||
1555 | } | ||
1434 | 1556 | ||
1435 | queue_delayed_work(priv->workqueue, &priv->scan_check, | 1557 | return ret; |
1436 | IWL_SCAN_CHECK_WATCHDOG); | ||
1437 | |||
1438 | return; | ||
1439 | |||
1440 | done: | ||
1441 | /* Cannot perform scan. Make sure we clear scanning | ||
1442 | * bits from status so next scan request can be performed. | ||
1443 | * If we don't clear scanning status bit here all next scan | ||
1444 | * will fail | ||
1445 | */ | ||
1446 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
1447 | clear_bit(STATUS_SCANNING, &priv->status); | ||
1448 | /* inform mac80211 scan aborted */ | ||
1449 | queue_work(priv->workqueue, &priv->scan_completed); | ||
1450 | } | 1558 | } |
1451 | 1559 | ||
1452 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, | 1560 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, |
@@ -1673,6 +1781,8 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
1673 | bt_cmd.kill_ack_mask = priv->kill_ack_mask; | 1781 | bt_cmd.kill_ack_mask = priv->kill_ack_mask; |
1674 | bt_cmd.kill_cts_mask = priv->kill_cts_mask; | 1782 | bt_cmd.kill_cts_mask = priv->kill_cts_mask; |
1675 | bt_cmd.valid = priv->bt_valid; | 1783 | bt_cmd.valid = priv->bt_valid; |
1784 | bt_cmd.tx_prio_boost = 0; | ||
1785 | bt_cmd.rx_prio_boost = 0; | ||
1676 | 1786 | ||
1677 | /* | 1787 | /* |
1678 | * Configure BT coex mode to "no coexistence" when the | 1788 | * Configure BT coex mode to "no coexistence" when the |