diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2012-02-13 11:23:13 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-02-22 20:51:13 +0100 |
commit | 3dfea27d103e9913698cf1a2c86745a74c7c556b (patch) | |
tree | 4794a2ca538aef954ae65a913a1b9e941f36c9be /drivers/net/wireless/iwlegacy/4965.c | |
parent | iwlegacy: regulatory_bands is not an ops (diff) | |
download | linux-3dfea27d103e9913698cf1a2c86745a74c7c556b.tar.xz linux-3dfea27d103e9913698cf1a2c86745a74c7c556b.zip |
iwlegacy: gather all 4965 handlers in one place
Handers belongs logically into 4965-mac.c file.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlegacy/4965.c')
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965.c | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index aea84bf4e935..cf49a7af6c6e 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -1737,317 +1737,6 @@ il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data) return (u16) sizeof(struct il4965_addsta_cmd); } -static inline u32 -il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp) -{ - return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; -} - -static inline u32 -il4965_tx_status_to_mac80211(u32 status) -{ - status &= TX_STATUS_MSK; - - switch (status) { - case TX_STATUS_SUCCESS: - case TX_STATUS_DIRECT_DONE: - return IEEE80211_TX_STAT_ACK; - case TX_STATUS_FAIL_DEST_PS: - return IEEE80211_TX_STAT_TX_FILTERED; - default: - return 0; - } -} - -static inline bool -il4965_is_tx_success(u32 status) -{ - status &= TX_STATUS_MSK; - return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE); -} - -/** - * il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue - */ -static int -il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg, - struct il4965_tx_resp *tx_resp, int txq_id, - u16 start_idx) -{ - u16 status; - struct agg_tx_status *frame_status = tx_resp->u.agg_status; - struct ieee80211_tx_info *info = NULL; - struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); - int i, sh, idx; - u16 seq; - if (agg->wait_for_ba) - D_TX_REPLY("got tx response w/o block-ack\n"); - - agg->frame_count = tx_resp->frame_count; - agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; - agg->bitmap = 0; - - /* num frames attempted by Tx command */ - if (agg->frame_count == 1) { - /* Only one frame was attempted; no block-ack will arrive */ - status = le16_to_cpu(frame_status[0].status); - idx = start_idx; - - D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", - agg->frame_count, agg->start_idx, idx); - - info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]); - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags &= ~IEEE80211_TX_CTL_AMPDU; - info->flags |= il4965_tx_status_to_mac80211(status); - il4965_hwrate_to_tx_control(il, rate_n_flags, info); - - D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff, - tx_resp->failure_frame); - D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags); - - agg->wait_for_ba = 0; - } else { - /* Two or more frames were attempted; expect block-ack */ - u64 bitmap = 0; - int start = agg->start_idx; - struct sk_buff *skb; - - /* Construct bit-map of pending frames within Tx win */ - for (i = 0; i < agg->frame_count; i++) { - u16 sc; - status = le16_to_cpu(frame_status[i].status); - seq = le16_to_cpu(frame_status[i].sequence); - idx = SEQ_TO_IDX(seq); - txq_id = SEQ_TO_QUEUE(seq); - - if (status & - (AGG_TX_STATE_FEW_BYTES_MSK | - AGG_TX_STATE_ABORT_MSK)) - continue; - - D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n", - agg->frame_count, txq_id, idx); - - skb = il->txq[txq_id].skbs[idx]; - if (WARN_ON_ONCE(skb == NULL)) - return -1; - hdr = (struct ieee80211_hdr *) skb->data; - - sc = le16_to_cpu(hdr->seq_ctrl); - if (idx != (SEQ_TO_SN(sc) & 0xff)) { - IL_ERR("BUG_ON idx doesn't match seq control" - " idx=%d, seq_idx=%d, seq=%d\n", idx, - SEQ_TO_SN(sc), hdr->seq_ctrl); - return -1; - } - - D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx, - SEQ_TO_SN(sc)); - - sh = idx - start; - if (sh > 64) { - sh = (start - idx) + 0xff; - bitmap = bitmap << sh; - sh = 0; - start = idx; - } else if (sh < -64) - sh = 0xff - (start - idx); - else if (sh < 0) { - sh = start - idx; - start = idx; - bitmap = bitmap << sh; - sh = 0; - } - bitmap |= 1ULL << sh; - D_TX_REPLY("start=%d bitmap=0x%llx\n", start, - (unsigned long long)bitmap); - } - - agg->bitmap = bitmap; - agg->start_idx = start; - D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", - agg->frame_count, agg->start_idx, - (unsigned long long)agg->bitmap); - - if (bitmap) - agg->wait_for_ba = 1; - } - return 0; -} - -static u8 -il4965_find_station(struct il_priv *il, const u8 * addr) -{ - int i; - int start = 0; - int ret = IL_INVALID_STATION; - unsigned long flags; - - if ((il->iw_mode == NL80211_IFTYPE_ADHOC)) - start = IL_STA_ID; - - if (is_broadcast_ether_addr(addr)) - return il->hw_params.bcast_id; - - spin_lock_irqsave(&il->sta_lock, flags); - for (i = start; i < il->hw_params.max_stations; i++) - if (il->stations[i].used && - (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) { - ret = i; - goto out; - } - - D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations); - -out: - /* - * It may be possible that more commands interacting with stations - * arrive before we completed processing the adding of - * station - */ - if (ret != IL_INVALID_STATION && - (!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) || - ((il->stations[ret].used & IL_STA_UCODE_ACTIVE) && - (il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) { - IL_ERR("Requested station info for sta %d before ready.\n", - ret); - ret = IL_INVALID_STATION; - } - spin_unlock_irqrestore(&il->sta_lock, flags); - return ret; -} - -static int -il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr) -{ - if (il->iw_mode == NL80211_IFTYPE_STATION) { - return IL_AP_ID; - } else { - u8 *da = ieee80211_get_DA(hdr); - return il4965_find_station(il, da); - } -} - -/** - * il4965_hdl_tx - Handle standard (non-aggregation) Tx response - */ -static void -il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) -{ - struct il_rx_pkt *pkt = rxb_addr(rxb); - u16 sequence = le16_to_cpu(pkt->hdr.sequence); - int txq_id = SEQ_TO_QUEUE(sequence); - int idx = SEQ_TO_IDX(sequence); - struct il_tx_queue *txq = &il->txq[txq_id]; - struct sk_buff *skb; - struct ieee80211_hdr *hdr; - struct ieee80211_tx_info *info; - struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le32_to_cpu(tx_resp->u.status); - int uninitialized_var(tid); - int sta_id; - int freed; - u8 *qc = NULL; - unsigned long flags; - - if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) { - IL_ERR("Read idx for DMA queue txq_id (%d) idx %d " - "is out of range [0-%d] %d %d\n", txq_id, idx, - txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr); - return; - } - - txq->time_stamp = jiffies; - - skb = txq->skbs[txq->q.read_ptr]; - info = IEEE80211_SKB_CB(skb); - memset(&info->status, 0, sizeof(info->status)); - - hdr = (struct ieee80211_hdr *) skb->data; - if (ieee80211_is_data_qos(hdr->frame_control)) { - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & 0xf; - } - - sta_id = il4965_get_ra_sta_id(il, hdr); - if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) { - IL_ERR("Station not known\n"); - return; - } - - spin_lock_irqsave(&il->sta_lock, flags); - if (txq->sched_retry) { - const u32 scd_ssn = il4965_get_scd_ssn(tx_resp); - struct il_ht_agg *agg = NULL; - WARN_ON(!qc); - - agg = &il->stations[sta_id].tid[tid].agg; - - il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx); - - /* check if BAR is needed */ - if ((tx_resp->frame_count == 1) && - !il4965_is_tx_success(status)) - info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - - if (txq->q.read_ptr != (scd_ssn & 0xff)) { - idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); - D_TX_REPLY("Retry scheduler reclaim scd_ssn " - "%d idx %d\n", scd_ssn, idx); - freed = il4965_tx_queue_reclaim(il, txq_id, idx); - if (qc) - il4965_free_tfds_in_queue(il, sta_id, tid, - freed); - - if (il->mac80211_registered && - il_queue_space(&txq->q) > txq->q.low_mark && - agg->state != IL_EMPTYING_HW_QUEUE_DELBA) - il_wake_queue(il, txq); - } - } else { - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags |= il4965_tx_status_to_mac80211(status); - il4965_hwrate_to_tx_control(il, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - D_TX_REPLY("TXQ %d status %s (0x%08x) " - "rate_n_flags 0x%x retries %d\n", txq_id, - il4965_get_tx_fail_reason(status), status, - le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - - freed = il4965_tx_queue_reclaim(il, txq_id, idx); - if (qc && likely(sta_id != IL_INVALID_STATION)) - il4965_free_tfds_in_queue(il, sta_id, tid, freed); - else if (sta_id == IL_INVALID_STATION) - D_TX_REPLY("Station not known\n"); - - if (il->mac80211_registered && - il_queue_space(&txq->q) > txq->q.low_mark) - il_wake_queue(il, txq); - } - if (qc && likely(sta_id != IL_INVALID_STATION)) - il4965_txq_check_empty(il, sta_id, tid, txq_id); - - il4965_check_abort_status(il, tx_resp->frame_count, status); - - spin_unlock_irqrestore(&il->sta_lock, flags); -} - -/* Set up 4965-specific Rx frame reply handlers */ -static void -il4965_handler_setup(struct il_priv *il) -{ - /* Legacy Rx frames */ - il->handlers[N_RX] = il4965_hdl_rx; - /* Tx response */ - il->handlers[C_TX] = il4965_hdl_tx; -} - static struct il_hcmd_ops il4965_hcmd = { .rxon_assoc = il4965_send_rxon_assoc, .commit_rxon = il4965_commit_rxon, @@ -2205,7 +1894,6 @@ static struct il_lib_ops il4965_lib = { .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd, .txq_free_tfd = il4965_hw_txq_free_tfd, .txq_init = il4965_hw_tx_queue_init, - .handler_setup = il4965_handler_setup, .is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr, .init_alive_start = il4965_init_alive_start, .load_ucode = il4965_load_bsm, |