Commit 25a6572c authored by Tomas Winkler's avatar Tomas Winkler Committed by John W. Linville

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 398f9e76
...@@ -3204,10 +3204,7 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) ...@@ -3204,10 +3204,7 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
{ {
__le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
tx_resp->frame_count);
return le32_to_cpu(*scd_ssn) & MAX_SN;
} }
/** /**
...@@ -3215,15 +3212,14 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) ...@@ -3215,15 +3212,14 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
*/ */
static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg, struct iwl_ht_agg *agg,
struct iwl4965_tx_resp_agg *tx_resp, struct iwl4965_tx_resp *tx_resp,
u16 start_idx) int txq_id, u16 start_idx)
{ {
u16 status; u16 status;
struct agg_tx_status *frame_status = &tx_resp->status; struct agg_tx_status *frame_status = tx_resp->u.agg_status;
struct ieee80211_tx_info *info = NULL; struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL; struct ieee80211_hdr *hdr = NULL;
int i, sh; int i, sh, idx;
int txq_id, idx;
u16 seq; u16 seq;
if (agg->wait_for_ba) if (agg->wait_for_ba)
...@@ -3238,9 +3234,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, ...@@ -3238,9 +3234,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
if (agg->frame_count == 1) { if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */ /* Only one frame was attempted; no block-ack will arrive */
status = le16_to_cpu(frame_status[0].status); status = le16_to_cpu(frame_status[0].status);
seq = le16_to_cpu(frame_status[0].sequence); idx = start_idx;
idx = SEQ_TO_INDEX(seq);
txq_id = SEQ_TO_QUEUE(seq);
/* FIXME: code repetition */ /* FIXME: code repetition */
IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", 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,7 +3335,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status); u32 status = le32_to_cpu(tx_resp->u.status);
int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
u16 fc; u16 fc;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
...@@ -3380,8 +3374,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -3380,8 +3374,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
agg = &priv->stations[sta_id].tid[tid].agg; agg = &priv->stations[sta_id].tid[tid].agg;
iwl4965_tx_status_reply_tx(priv, agg, iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
(struct iwl4965_tx_resp_agg *)tx_resp, index);
if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
/* TODO: send BAR */ /* TODO: send BAR */
......
...@@ -1126,23 +1126,20 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask) ...@@ -1126,23 +1126,20 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
{ {
__le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + return le32_to_cpup((__le32*)&tx_resp->status +
tx_resp->frame_count); tx_resp->frame_count) & MAX_SN;
return le32_to_cpu(*scd_ssn) & MAX_SN;
} }
static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg, struct iwl_ht_agg *agg,
struct iwl5000_tx_resp *tx_resp, struct iwl5000_tx_resp *tx_resp,
u16 start_idx) int txq_id, u16 start_idx)
{ {
u16 status; u16 status;
struct agg_tx_status *frame_status = &tx_resp->status; struct agg_tx_status *frame_status = &tx_resp->status;
struct ieee80211_tx_info *info = NULL; struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL; struct ieee80211_hdr *hdr = NULL;
int i, sh; int i, sh, idx;
int txq_id, idx;
u16 seq; u16 seq;
if (agg->wait_for_ba) if (agg->wait_for_ba)
...@@ -1157,9 +1154,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, ...@@ -1157,9 +1154,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
if (agg->frame_count == 1) { if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */ /* Only one frame was attempted; no block-ack will arrive */
status = le16_to_cpu(frame_status[0].status); status = le16_to_cpu(frame_status[0].status);
seq = le16_to_cpu(frame_status[0].sequence); idx = start_idx;
idx = SEQ_TO_INDEX(seq);
txq_id = SEQ_TO_QUEUE(seq);
/* FIXME: code repetition */ /* FIXME: code repetition */
IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", 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,7 +1291,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
agg = &priv->stations[sta_id].tid[tid].agg; agg = &priv->stations[sta_id].tid[tid].agg;
iwl5000_tx_status_reply_tx(priv, agg, tx_resp, index); iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
/* TODO: send BAR */ /* TODO: send BAR */
......
...@@ -1481,21 +1481,10 @@ struct iwl4965_tx_resp { ...@@ -1481,21 +1481,10 @@ struct iwl4965_tx_resp {
* table entry used for all frames in the new agg. * table entry used for all frames in the new agg.
* 31-16: Sequence # for this frame's Tx cmd (not SSN!) * 31-16: Sequence # for this frame's Tx cmd (not SSN!)
*/ */
__le32 status; /* TX status (for aggregation status of 1st frame) */ union {
} __attribute__ ((packed)); __le32 status;
struct agg_tx_status agg_status[0]; /* for each agg frame */
struct iwl4965_tx_resp_agg { } u;
u8 frame_count; /* 1 no aggregation, >1 aggregation */
u8 reserved1;
u8 failure_rts;
u8 failure_frame;
__le32 rate_n_flags;
__le16 wireless_media_time;
__le16 reserved3;
__le32 pa_power1;
__le32 pa_power2;
struct agg_tx_status status; /* TX status (for aggregation status */
/* of 1st frame) */
} __attribute__ ((packed)); } __attribute__ ((packed));
struct iwl5000_tx_resp { struct iwl5000_tx_resp {
......
...@@ -1668,7 +1668,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, ...@@ -1668,7 +1668,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
IWL_DEBUG_RX("beacon status %x retries %d iss %d " IWL_DEBUG_RX("beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n", "tsf %d %d rate %d\n",
le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
beacon->beacon_notify_hdr.failure_frame, beacon->beacon_notify_hdr.failure_frame,
le32_to_cpu(beacon->ibss_mgr_status), le32_to_cpu(beacon->ibss_mgr_status),
le32_to_cpu(beacon->high_tsf), le32_to_cpu(beacon->high_tsf),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment