aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c314
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 a8f2adfd799..299fd9d5960 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
49static 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
126static 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
173static 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
200const 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
49static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, 224static 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
1157void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) 1314int 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
1452int iwlagn_manage_ibss_station(struct iwl_priv *priv, 1560int 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