Skip to content

Commit

Permalink
iwlagn: move the mapping ac to queue / fifo to transport
Browse files Browse the repository at this point in the history
This mapping is transport related.
This allows us to remove the notion of tx queue from the tx path in
the upper layer.
iwl_wake_any_queue moved to transport layer since it needs to access
these mappings.
The TX API is nicer now:

int (*tx)(struct iwl_trans *trans, struct sk_buff *skb,
		struct iwl_device_cmd *dev_cmd, u8 ctx, u8 sta_id);

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Emmanuel Grumbach authored and John W. Linville committed Aug 29, 2011
1 parent dfa2bdb commit e13c0c5
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 168 deletions.
3 changes: 2 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
*/
if (ctx->last_tx_rejected) {
ctx->last_tx_rejected = false;
iwl_wake_any_queue(priv, ctx);
iwl_trans_wake_any_queue(trans(priv),
ctx->ctxid);
}
ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;

Expand Down
53 changes: 1 addition & 52 deletions drivers/net/wireless/iwlwifi/iwl-agn-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl_device_cmd *dev_cmd = NULL;
struct iwl_tx_cmd *tx_cmd;
int txq_id;

u16 seq_number = 0;
__le16 fc;
u8 hdr_len;
u16 len;
u8 sta_id;
u8 tid = 0;
unsigned long flags;
bool is_agg = false;

Expand Down Expand Up @@ -343,50 +340,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
}

/*
* Send this frame after DTIM -- there's a special queue
* reserved for this for contexts that support AP mode.
*/
if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
txq_id = ctx->mcast_queue;
/*
* The microcode will clear the more data
* bit in the last frame it transmits.
*/
hdr->frame_control |=
cpu_to_le16(IEEE80211_FCTL_MOREDATA);
} else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
txq_id = IWL_AUX_QUEUE;
else
txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];

/* irqs already disabled/saved above when locking priv->shrd->lock */
spin_lock(&priv->shrd->sta_lock);

if (ieee80211_is_data_qos(fc)) {
u8 *qc = NULL;
struct iwl_tid_data *tid_data;
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
tid_data = &priv->shrd->tid_data[sta_id][tid];

if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
goto drop_unlock_sta;

seq_number = tid_data->seq_number;
seq_number &= IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = hdr->seq_ctrl &
cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(seq_number);
seq_number += 0x10;
/* aggregation is on for this <sta,tid> */
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
tid_data->agg.state == IWL_AGG_ON) {
txq_id = tid_data->agg.txq_id;
is_agg = true;
}
}

dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC);

if (unlikely(!dev_cmd))
Expand Down Expand Up @@ -416,16 +372,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
info->driver_data[0] = ctx;
info->driver_data[1] = dev_cmd;

if (iwl_trans_tx(trans(priv), skb, dev_cmd, txq_id, fc, is_agg))
if (iwl_trans_tx(trans(priv), skb, dev_cmd, ctx->ctxid, sta_id))
goto drop_unlock_sta;

if (ieee80211_is_data_qos(fc)) {
priv->shrd->tid_data[sta_id][tid].tfds_in_queue++;
if (!ieee80211_has_morefrags(fc))
priv->shrd->tid_data[sta_id][tid].seq_number =
seq_number;
}

spin_unlock(&priv->shrd->sta_lock);
spin_unlock_irqrestore(&priv->shrd->lock, flags);

Expand Down
23 changes: 0 additions & 23 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,24 +617,6 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,

static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
{
static const u8 iwlagn_bss_ac_to_fifo[] = {
IWL_TX_FIFO_VO,
IWL_TX_FIFO_VI,
IWL_TX_FIFO_BE,
IWL_TX_FIFO_BK,
};
static const u8 iwlagn_bss_ac_to_queue[] = {
0, 1, 2, 3,
};
static const u8 iwlagn_pan_ac_to_fifo[] = {
IWL_TX_FIFO_VO_IPAN,
IWL_TX_FIFO_VI_IPAN,
IWL_TX_FIFO_BE_IPAN,
IWL_TX_FIFO_BK_IPAN,
};
static const u8 iwlagn_pan_ac_to_queue[] = {
7, 6, 5, 4,
};
int i;

/*
Expand All @@ -656,8 +638,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
BIT(NL80211_IFTYPE_ADHOC);
priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
Expand All @@ -677,9 +657,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);

Expand Down
11 changes: 0 additions & 11 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,6 @@ struct iwl_channel_info {
#define IWL_DEFAULT_CMD_QUEUE_NUM 4
#define IWL_IPAN_CMD_QUEUE_NUM 9

/*
* This queue number is required for proper operation
* because the ucode will stop/start the scheduler as
* required.
*/
#define IWL_IPAN_MCAST_QUEUE 8

#define IEEE80211_DATA_LEN 2304
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
Expand Down Expand Up @@ -965,10 +958,6 @@ struct iwl_notification_wait {
struct iwl_rxon_context {
struct ieee80211_vif *vif;

const u8 *ac_to_fifo;
const u8 *ac_to_queue;
u8 mcast_queue;

/*
* We could use the vif to indicate active, but we
* also need it to be active during disabling when
Expand Down
13 changes: 0 additions & 13 deletions drivers/net/wireless/iwlwifi/iwl-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,6 @@ static inline void iwl_stop_queue(struct iwl_priv *priv,
ieee80211_stop_queue(priv->hw, ac);
}

static inline void iwl_wake_any_queue(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
u8 ac;

for (ac = 0; ac < AC_NUM; ac++) {
IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n",
ac, (atomic_read(&priv->queue_stop_count[ac]) > 0)
? "stopped" : "awake");
iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]);
}
}

#ifdef ieee80211_stop_queue
#undef ieee80211_stop_queue
#endif
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
ctx->active.bssid_addr))
continue;
ctx->last_tx_rejected = false;
iwl_wake_any_queue(priv, ctx);
iwl_trans_wake_any_queue(trans(priv), ctx->ctxid);
}
}

Expand Down
14 changes: 14 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ struct iwl_dma_ptr {
size_t size;
};

/*
* This queue number is required for proper operation
* because the ucode will stop/start the scheduler as
* required.
*/
#define IWL_IPAN_MCAST_QUEUE 8

/**
* struct iwl_trans_pcie - PCIe transport specific data
* @rxq: all the RX queue data
Expand All @@ -115,6 +122,9 @@ struct iwl_dma_ptr {
* @scd_base_addr: scheduler sram base address in SRAM
* @scd_bc_tbls: pointer to the byte count table of the scheduler
* @kw: keep warm address
* @ac_to_fifo: to what fifo is a specifc AC mapped ?
* @ac_to_queue: to what tx queue is a specifc AC mapped ?
* @mcast_queue:
*/
struct iwl_trans_pcie {
struct iwl_rx_queue rxq;
Expand All @@ -136,6 +146,10 @@ struct iwl_trans_pcie {
u32 scd_base_addr;
struct iwl_dma_ptr scd_bc_tbls;
struct iwl_dma_ptr kw;

const u8 *ac_to_fifo[NUM_IWL_RXON_CTX];
const u8 *ac_to_queue[NUM_IWL_RXON_CTX];
u8 mcast_queue[NUM_IWL_RXON_CTX];
};

#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
Expand Down
8 changes: 5 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,10 +424,12 @@ void iwl_trans_tx_queue_set_status(struct iwl_priv *priv,
scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
}

static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie,
u8 ctx, u16 tid)
{
const u8 *ac_to_fifo = trans_pcie->ac_to_fifo[ctx];
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
return ctx->ac_to_fifo[tid_to_ac[tid]];
return ac_to_fifo[tid_to_ac[tid]];

/* no support for TIDs 8-15 yet */
return -EINVAL;
Expand All @@ -451,7 +453,7 @@ void iwl_trans_pcie_txq_agg_setup(struct iwl_priv *priv,
if (WARN_ON(tid >= IWL_MAX_TID_COUNT))
return;

tx_fifo = get_fifo_from_tid(&priv->contexts[ctx], tid);
tx_fifo = get_fifo_from_tid(trans_pcie, ctx, tid);
if (WARN_ON(tx_fifo < 0)) {
IWL_ERR(trans, "txq_agg_setup, bad fifo: %d\n", tx_fifo);
return;
Expand Down
Loading

0 comments on commit e13c0c5

Please sign in to comment.