aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-06-11 21:47:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-14 12:18:07 -0400
commit25a6572cc13ba2a3fefc02a63a077ff3664a1ca9 (patch)
tree7c796dc956d9c643d966bd7a09c3d3c6320031f8
parent398f9e765f57c0dca0f6fb13c28ad929c09c68ef (diff)
iwlwifi: refactor tx aggregation response flow
This patch refactors tx aggregation respnse flow and fixes bug revealed by tx_info to cb patch Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c2
4 files changed, 19 insertions, 42 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 4d47dd7acc15..3f24e979731b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -3204,10 +3204,7 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
3204 3204
3205static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) 3205static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
3206{ 3206{
3207 __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + 3207 return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
3208 tx_resp->frame_count);
3209 return le32_to_cpu(*scd_ssn) & MAX_SN;
3210
3211} 3208}
3212 3209
3213/** 3210/**
@@ -3215,15 +3212,14 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
3215 */ 3212 */
3216static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, 3213static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
3217 struct iwl_ht_agg *agg, 3214 struct iwl_ht_agg *agg,
3218 struct iwl4965_tx_resp_agg *tx_resp, 3215 struct iwl4965_tx_resp *tx_resp,
3219 u16 start_idx) 3216 int txq_id, u16 start_idx)
3220{ 3217{
3221 u16 status; 3218 u16 status;
3222 struct agg_tx_status *frame_status = &tx_resp->status; 3219 struct agg_tx_status *frame_status = tx_resp->u.agg_status;
3223 struct ieee80211_tx_info *info = NULL; 3220 struct ieee80211_tx_info *info = NULL;
3224 struct ieee80211_hdr *hdr = NULL; 3221 struct ieee80211_hdr *hdr = NULL;
3225 int i, sh; 3222 int i, sh, idx;
3226 int txq_id, idx;
3227 u16 seq; 3223 u16 seq;
3228 3224
3229 if (agg->wait_for_ba) 3225 if (agg->wait_for_ba)
@@ -3238,9 +3234,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
3238 if (agg->frame_count == 1) { 3234 if (agg->frame_count == 1) {
3239 /* Only one frame was attempted; no block-ack will arrive */ 3235 /* Only one frame was attempted; no block-ack will arrive */
3240 status = le16_to_cpu(frame_status[0].status); 3236 status = le16_to_cpu(frame_status[0].status);
3241 seq = le16_to_cpu(frame_status[0].sequence); 3237 idx = start_idx;
3242 idx = SEQ_TO_INDEX(seq);
3243 txq_id = SEQ_TO_QUEUE(seq);
3244 3238
3245 /* FIXME: code repetition */ 3239 /* FIXME: code repetition */
3246 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", 3240 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
@@ -3341,7 +3335,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
3341 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 3335 struct iwl_tx_queue *txq = &priv->txq[txq_id];
3342 struct ieee80211_tx_info *info; 3336 struct ieee80211_tx_info *info;
3343 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 3337 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
3344 u32 status = le32_to_cpu(tx_resp->status); 3338 u32 status = le32_to_cpu(tx_resp->u.status);
3345 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; 3339 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
3346 u16 fc; 3340 u16 fc;
3347 struct ieee80211_hdr *hdr; 3341 struct ieee80211_hdr *hdr;
@@ -3380,8 +3374,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
3380 3374
3381 agg = &priv->stations[sta_id].tid[tid].agg; 3375 agg = &priv->stations[sta_id].tid[tid].agg;
3382 3376
3383 iwl4965_tx_status_reply_tx(priv, agg, 3377 iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
3384 (struct iwl4965_tx_resp_agg *)tx_resp, index);
3385 3378
3386 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { 3379 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
3387 /* TODO: send BAR */ 3380 /* TODO: send BAR */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index d3c0e10397c8..2a30306b7ed0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1126,23 +1126,20 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
1126 1126
1127static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) 1127static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
1128{ 1128{
1129 __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + 1129 return le32_to_cpup((__le32*)&tx_resp->status +
1130 tx_resp->frame_count); 1130 tx_resp->frame_count) & MAX_SN;
1131 return le32_to_cpu(*scd_ssn) & MAX_SN;
1132
1133} 1131}
1134 1132
1135static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, 1133static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
1136 struct iwl_ht_agg *agg, 1134 struct iwl_ht_agg *agg,
1137 struct iwl5000_tx_resp *tx_resp, 1135 struct iwl5000_tx_resp *tx_resp,
1138 u16 start_idx) 1136 int txq_id, u16 start_idx)
1139{ 1137{
1140 u16 status; 1138 u16 status;
1141 struct agg_tx_status *frame_status = &tx_resp->status; 1139 struct agg_tx_status *frame_status = &tx_resp->status;
1142 struct ieee80211_tx_info *info = NULL; 1140 struct ieee80211_tx_info *info = NULL;
1143 struct ieee80211_hdr *hdr = NULL; 1141 struct ieee80211_hdr *hdr = NULL;
1144 int i, sh; 1142 int i, sh, idx;
1145 int txq_id, idx;
1146 u16 seq; 1143 u16 seq;
1147 1144
1148 if (agg->wait_for_ba) 1145 if (agg->wait_for_ba)
@@ -1157,9 +1154,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
1157 if (agg->frame_count == 1) { 1154 if (agg->frame_count == 1) {
1158 /* Only one frame was attempted; no block-ack will arrive */ 1155 /* Only one frame was attempted; no block-ack will arrive */
1159 status = le16_to_cpu(frame_status[0].status); 1156 status = le16_to_cpu(frame_status[0].status);
1160 seq = le16_to_cpu(frame_status[0].sequence); 1157 idx = start_idx;
1161 idx = SEQ_TO_INDEX(seq);
1162 txq_id = SEQ_TO_QUEUE(seq);
1163 1158
1164 /* FIXME: code repetition */ 1159 /* FIXME: code repetition */
1165 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", 1160 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
@@ -1296,7 +1291,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1296 1291
1297 agg = &priv->stations[sta_id].tid[tid].agg; 1292 agg = &priv->stations[sta_id].tid[tid].agg;
1298 1293
1299 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, index); 1294 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
1300 1295
1301 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { 1296 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
1302 /* TODO: send BAR */ 1297 /* TODO: send BAR */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index fb6f5ffb9f1d..9b64a390564c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1481,21 +1481,10 @@ struct iwl4965_tx_resp {
1481 * table entry used for all frames in the new agg. 1481 * table entry used for all frames in the new agg.
1482 * 31-16: Sequence # for this frame's Tx cmd (not SSN!) 1482 * 31-16: Sequence # for this frame's Tx cmd (not SSN!)
1483 */ 1483 */
1484 __le32 status; /* TX status (for aggregation status of 1st frame) */ 1484 union {
1485} __attribute__ ((packed)); 1485 __le32 status;
1486 1486 struct agg_tx_status agg_status[0]; /* for each agg frame */
1487struct iwl4965_tx_resp_agg { 1487 } u;
1488 u8 frame_count; /* 1 no aggregation, >1 aggregation */
1489 u8 reserved1;
1490 u8 failure_rts;
1491 u8 failure_frame;
1492 __le32 rate_n_flags;
1493 __le16 wireless_media_time;
1494 __le16 reserved3;
1495 __le32 pa_power1;
1496 __le32 pa_power2;
1497 struct agg_tx_status status; /* TX status (for aggregation status */
1498 /* of 1st frame) */
1499} __attribute__ ((packed)); 1488} __attribute__ ((packed));
1500 1489
1501struct iwl5000_tx_resp { 1490struct iwl5000_tx_resp {
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 8e7860debdf6..510e40348a30 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1668,7 +1668,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
1668 1668
1669 IWL_DEBUG_RX("beacon status %x retries %d iss %d " 1669 IWL_DEBUG_RX("beacon status %x retries %d iss %d "
1670 "tsf %d %d rate %d\n", 1670 "tsf %d %d rate %d\n",
1671 le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, 1671 le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
1672 beacon->beacon_notify_hdr.failure_frame, 1672 beacon->beacon_notify_hdr.failure_frame,
1673 le32_to_cpu(beacon->ibss_mgr_status), 1673 le32_to_cpu(beacon->ibss_mgr_status),
1674 le32_to_cpu(beacon->high_tsf), 1674 le32_to_cpu(beacon->high_tsf),