aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c146
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c143
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c6
5 files changed, 151 insertions, 150 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d8e6d2e6a86b..57a853d22115 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1930,74 +1930,6 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv,
1930} 1930}
1931 1931
1932/** 1932/**
1933 * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack
1934 *
1935 * Go through block-ack's bitmap of ACK'd frames, update driver's record of
1936 * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
1937 */
1938static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1939 struct iwl_ht_agg *agg,
1940 struct iwl4965_compressed_ba_resp*
1941 ba_resp)
1942
1943{
1944 int i, sh, ack;
1945 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1946 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1947 u64 bitmap;
1948 int successes = 0;
1949 struct ieee80211_tx_info *info;
1950
1951 if (unlikely(!agg->wait_for_ba)) {
1952 IWL_ERROR("Received BA when not expected\n");
1953 return -EINVAL;
1954 }
1955
1956 /* Mark that the expected block-ack response arrived */
1957 agg->wait_for_ba = 0;
1958 IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1959
1960 /* Calculate shift to align block-ack bits with our Tx window bits */
1961 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4);
1962 if (sh < 0) /* tbw something is wrong with indices */
1963 sh += 0x100;
1964
1965 /* don't use 64-bit values for now */
1966 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1967
1968 if (agg->frame_count > (64 - sh)) {
1969 IWL_DEBUG_TX_REPLY("more frames than bitmap size");
1970 return -1;
1971 }
1972
1973 /* check for success or failure according to the
1974 * transmitted bitmap and block-ack bitmap */
1975 bitmap &= agg->bitmap;
1976
1977 /* For each frame attempted in aggregation,
1978 * update driver's record of tx frame's status. */
1979 for (i = 0; i < agg->frame_count ; i++) {
1980 ack = bitmap & (1 << i);
1981 successes += !!ack;
1982 IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
1983 ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,
1984 agg->start_idx + i);
1985 }
1986
1987 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
1988 memset(&info->status, 0, sizeof(info->status));
1989 info->flags = IEEE80211_TX_STAT_ACK;
1990 info->flags |= IEEE80211_TX_STAT_AMPDU;
1991 info->status.ampdu_ack_map = successes;
1992 info->status.ampdu_ack_len = agg->frame_count;
1993 iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1994
1995 IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
1996
1997 return 0;
1998}
1999
2000/**
2001 * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration 1933 * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration
2002 */ 1934 */
2003static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, 1935static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv,
@@ -2048,82 +1980,6 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
2048 return 0; 1980 return 0;
2049} 1981}
2050 1982
2051
2052/**
2053 * iwl4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
2054 *
2055 * Handles block-acknowledge notification from device, which reports success
2056 * of frames sent via aggregation.
2057 */
2058static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv,
2059 struct iwl_rx_mem_buffer *rxb)
2060{
2061 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
2062 struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
2063 int index;
2064 struct iwl_tx_queue *txq = NULL;
2065 struct iwl_ht_agg *agg;
2066 DECLARE_MAC_BUF(mac);
2067
2068 /* "flow" corresponds to Tx queue */
2069 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
2070
2071 /* "ssn" is start of block-ack Tx window, corresponds to index
2072 * (in Tx queue's circular buffer) of first TFD/frame in window */
2073 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
2074
2075 if (scd_flow >= priv->hw_params.max_txq_num) {
2076 IWL_ERROR("BUG_ON scd_flow is bigger than number of queues");
2077 return;
2078 }
2079
2080 txq = &priv->txq[scd_flow];
2081 agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg;
2082
2083 /* Find index just before block-ack window */
2084 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
2085
2086 /* TODO: Need to get this copy more safely - now good for debug */
2087
2088 IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, "
2089 "sta_id = %d\n",
2090 agg->wait_for_ba,
2091 print_mac(mac, (u8*) &ba_resp->sta_addr_lo32),
2092 ba_resp->sta_id);
2093 IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
2094 "%d, scd_ssn = %d\n",
2095 ba_resp->tid,
2096 ba_resp->seq_ctl,
2097 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
2098 ba_resp->scd_flow,
2099 ba_resp->scd_ssn);
2100 IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
2101 agg->start_idx,
2102 (unsigned long long)agg->bitmap);
2103
2104 /* Update driver's record of ACK vs. not for each frame in window */
2105 iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp);
2106
2107 /* Release all TFDs before the SSN, i.e. all TFDs in front of
2108 * block-ack window (we assume that they've been successfully
2109 * transmitted ... if not, it's too late anyway). */
2110 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
2111 /* calculate mac80211 ampdu sw queue to wake */
2112 int ampdu_q =
2113 scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;
2114 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
2115 priv->stations[ba_resp->sta_id].
2116 tid[ba_resp->tid].tfds_in_queue -= freed;
2117 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
2118 priv->mac80211_registered &&
2119 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)
2120 ieee80211_wake_queue(priv->hw, ampdu_q);
2121
2122 iwl_txq_check_empty(priv, ba_resp->sta_id,
2123 ba_resp->tid, scd_flow);
2124 }
2125}
2126
2127/** 1983/**
2128 * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue 1984 * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue
2129 */ 1985 */
@@ -2555,8 +2411,6 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
2555 priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx; 2411 priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx;
2556 /* Tx response */ 2412 /* Tx response */
2557 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; 2413 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
2558 /* block ack */
2559 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba;
2560} 2414}
2561 2415
2562static void iwl4965_setup_deferred_work(struct iwl_priv *priv) 2416static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 9f8446c5a1bc..fe05d60ebe63 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1536,7 +1536,7 @@ struct iwl5000_tx_resp {
1536 * 1536 *
1537 * Reports Block-Acknowledge from recipient station 1537 * Reports Block-Acknowledge from recipient station
1538 */ 1538 */
1539struct iwl4965_compressed_ba_resp { 1539struct iwl_compressed_ba_resp {
1540 __le32 sta_addr_lo32; 1540 __le32 sta_addr_lo32;
1541 __le16 sta_addr_hi16; 1541 __le16 sta_addr_hi16;
1542 __le16 reserved; 1542 __le16 reserved;
@@ -3001,7 +3001,7 @@ struct iwl_rx_packet {
3001 struct iwl4965_sleep_notification sleep_notif; 3001 struct iwl4965_sleep_notification sleep_notif;
3002 struct iwl4965_spectrum_resp spectrum; 3002 struct iwl4965_spectrum_resp spectrum;
3003 struct iwl_notif_statistics stats; 3003 struct iwl_notif_statistics stats;
3004 struct iwl4965_compressed_ba_resp compressed_ba; 3004 struct iwl_compressed_ba_resp compressed_ba;
3005 struct iwl4965_missed_beacon_notif missed_beacon; 3005 struct iwl4965_missed_beacon_notif missed_beacon;
3006 struct iwl5000_calibration calib; 3006 struct iwl5000_calibration calib;
3007 __le32 status; 3007 __le32 status;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 0d8cc8c659a0..06c272cee97d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -377,6 +377,8 @@ extern void iwl_rx_reply_rx(struct iwl_priv *priv,
377 struct iwl_rx_mem_buffer *rxb); 377 struct iwl_rx_mem_buffer *rxb);
378extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv, 378extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
379 struct iwl_rx_mem_buffer *rxb); 379 struct iwl_rx_mem_buffer *rxb);
380void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
381 struct iwl_rx_mem_buffer *rxb);
380 382
381static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) 383static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
382{ 384{
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7296e2846ec3..032641d4c7d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1350,6 +1350,149 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
1350} 1350}
1351EXPORT_SYMBOL(iwl_txq_check_empty); 1351EXPORT_SYMBOL(iwl_txq_check_empty);
1352 1352
1353/**
1354 * iwl_tx_status_reply_compressed_ba - Update tx status from block-ack
1355 *
1356 * Go through block-ack's bitmap of ACK'd frames, update driver's record of
1357 * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
1358 */
1359static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1360 struct iwl_ht_agg *agg,
1361 struct iwl_compressed_ba_resp *ba_resp)
1362
1363{
1364 int i, sh, ack;
1365 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1366 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1367 u64 bitmap;
1368 int successes = 0;
1369 struct ieee80211_tx_info *info;
1370
1371 if (unlikely(!agg->wait_for_ba)) {
1372 IWL_ERROR("Received BA when not expected\n");
1373 return -EINVAL;
1374 }
1375
1376 /* Mark that the expected block-ack response arrived */
1377 agg->wait_for_ba = 0;
1378 IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1379
1380 /* Calculate shift to align block-ack bits with our Tx window bits */
1381 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4);
1382 if (sh < 0) /* tbw something is wrong with indices */
1383 sh += 0x100;
1384
1385 /* don't use 64-bit values for now */
1386 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1387
1388 if (agg->frame_count > (64 - sh)) {
1389 IWL_DEBUG_TX_REPLY("more frames than bitmap size");
1390 return -1;
1391 }
1392
1393 /* check for success or failure according to the
1394 * transmitted bitmap and block-ack bitmap */
1395 bitmap &= agg->bitmap;
1396
1397 /* For each frame attempted in aggregation,
1398 * update driver's record of tx frame's status. */
1399 for (i = 0; i < agg->frame_count ; i++) {
1400 ack = bitmap & (1 << i);
1401 successes += !!ack;
1402 IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
1403 ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,
1404 agg->start_idx + i);
1405 }
1406
1407 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
1408 memset(&info->status, 0, sizeof(info->status));
1409 info->flags = IEEE80211_TX_STAT_ACK;
1410 info->flags |= IEEE80211_TX_STAT_AMPDU;
1411 info->status.ampdu_ack_map = successes;
1412 info->status.ampdu_ack_len = agg->frame_count;
1413 iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1414
1415 IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
1416
1417 return 0;
1418}
1419
1420/**
1421 * iwl_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
1422 *
1423 * Handles block-acknowledge notification from device, which reports success
1424 * of frames sent via aggregation.
1425 */
1426void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1427 struct iwl_rx_mem_buffer *rxb)
1428{
1429 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1430 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1431 int index;
1432 struct iwl_tx_queue *txq = NULL;
1433 struct iwl_ht_agg *agg;
1434 DECLARE_MAC_BUF(mac);
1435
1436 /* "flow" corresponds to Tx queue */
1437 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1438
1439 /* "ssn" is start of block-ack Tx window, corresponds to index
1440 * (in Tx queue's circular buffer) of first TFD/frame in window */
1441 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
1442
1443 if (scd_flow >= priv->hw_params.max_txq_num) {
1444 IWL_ERROR("BUG_ON scd_flow is bigger than number of queues");
1445 return;
1446 }
1447
1448 txq = &priv->txq[scd_flow];
1449 agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg;
1450
1451 /* Find index just before block-ack window */
1452 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1453
1454 /* TODO: Need to get this copy more safely - now good for debug */
1455
1456 IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, "
1457 "sta_id = %d\n",
1458 agg->wait_for_ba,
1459 print_mac(mac, (u8 *) &ba_resp->sta_addr_lo32),
1460 ba_resp->sta_id);
1461 IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
1462 "%d, scd_ssn = %d\n",
1463 ba_resp->tid,
1464 ba_resp->seq_ctl,
1465 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
1466 ba_resp->scd_flow,
1467 ba_resp->scd_ssn);
1468 IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
1469 agg->start_idx,
1470 (unsigned long long)agg->bitmap);
1471
1472 /* Update driver's record of ACK vs. not for each frame in window */
1473 iwl_tx_status_reply_compressed_ba(priv, agg, ba_resp);
1474
1475 /* Release all TFDs before the SSN, i.e. all TFDs in front of
1476 * block-ack window (we assume that they've been successfully
1477 * transmitted ... if not, it's too late anyway). */
1478 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1479 /* calculate mac80211 ampdu sw queue to wake */
1480 int ampdu_q =
1481 scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;
1482 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
1483 priv->stations[ba_resp->sta_id].
1484 tid[ba_resp->tid].tfds_in_queue -= freed;
1485 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
1486 priv->mac80211_registered &&
1487 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)
1488 ieee80211_wake_queue(priv->hw, ampdu_q);
1489
1490 iwl_txq_check_empty(priv, ba_resp->sta_id,
1491 ba_resp->tid, scd_flow);
1492 }
1493}
1494EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);
1495
1353#ifdef CONFIG_IWLWIF_DEBUG 1496#ifdef CONFIG_IWLWIF_DEBUG
1354#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x 1497#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
1355 1498
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 4129e90f360a..a87e870f96d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1249,7 +1249,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
1249 * This function chains into the hardware specific files for them to setup 1249 * This function chains into the hardware specific files for them to setup
1250 * any hardware specific handlers as well. 1250 * any hardware specific handlers as well.
1251 */ 1251 */
1252static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) 1252static void iwl_setup_rx_handlers(struct iwl_priv *priv)
1253{ 1253{
1254 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; 1254 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
1255 priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error; 1255 priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error;
@@ -1279,6 +1279,8 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
1279 /* Rx handlers */ 1279 /* Rx handlers */
1280 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; 1280 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy;
1281 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; 1281 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx;
1282 /* block ack */
1283 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba;
1282 /* Set up hardware specific Rx handlers */ 1284 /* Set up hardware specific Rx handlers */
1283 priv->cfg->ops->lib->rx_handler_setup(priv); 1285 priv->cfg->ops->lib->rx_handler_setup(priv);
1284} 1286}
@@ -4272,7 +4274,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4272 4274
4273 4275
4274 iwl_setup_deferred_work(priv); 4276 iwl_setup_deferred_work(priv);
4275 iwl4965_setup_rx_handlers(priv); 4277 iwl_setup_rx_handlers(priv);
4276 4278
4277 /******************** 4279 /********************
4278 * 9. Conclude 4280 * 9. Conclude