iwlagn: move the Rx dispatching to the upper layer
The upper layer receives a pointer to an iwl_rx_mem_buffer. I would prefer the upper layer to receive a pointer to an iwl_rx_packet, but this is impossible since the Rx path needs to add the address of the page to the skb. I may find a solution later. All the pre_rx_handler and notification code has been moved to the upper layer. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
This commit is contained in:
committed by
Wey-Yi Guy
parent
a27367d25d
commit
1ab9f6c11b
@@ -513,6 +513,9 @@ static void iwl_rx_handle(struct iwl_priv *priv)
|
|||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
pkt = rxb_addr(rxb);
|
pkt = rxb_addr(rxb);
|
||||||
|
|
||||||
|
IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
|
||||||
|
i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
|
||||||
|
|
||||||
len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
|
len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
|
||||||
len += sizeof(u32); /* account for status word */
|
len += sizeof(u32); /* account for status word */
|
||||||
trace_iwlwifi_dev_rx(priv, pkt, len);
|
trace_iwlwifi_dev_rx(priv, pkt, len);
|
||||||
@@ -531,44 +534,7 @@ static void iwl_rx_handle(struct iwl_priv *priv)
|
|||||||
(pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
|
(pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
|
||||||
(pkt->hdr.cmd != REPLY_TX);
|
(pkt->hdr.cmd != REPLY_TX);
|
||||||
|
|
||||||
/*
|
iwl_rx_dispatch(priv, rxb);
|
||||||
* Do the notification wait before RX handlers so
|
|
||||||
* even if the RX handler consumes the RXB we have
|
|
||||||
* access to it in the notification wait entry.
|
|
||||||
*/
|
|
||||||
if (!list_empty(&priv->_agn.notif_waits)) {
|
|
||||||
struct iwl_notification_wait *w;
|
|
||||||
|
|
||||||
spin_lock(&priv->_agn.notif_wait_lock);
|
|
||||||
list_for_each_entry(w, &priv->_agn.notif_waits, list) {
|
|
||||||
if (w->cmd == pkt->hdr.cmd) {
|
|
||||||
w->triggered = true;
|
|
||||||
if (w->fn)
|
|
||||||
w->fn(priv, pkt, w->fn_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock(&priv->_agn.notif_wait_lock);
|
|
||||||
|
|
||||||
wake_up_all(&priv->_agn.notif_waitq);
|
|
||||||
}
|
|
||||||
if (priv->pre_rx_handler)
|
|
||||||
priv->pre_rx_handler(priv, rxb);
|
|
||||||
|
|
||||||
/* Based on type of command response or notification,
|
|
||||||
* handle those that need handling via function in
|
|
||||||
* rx_handlers table. See iwl_setup_rx_handlers() */
|
|
||||||
if (priv->rx_handlers[pkt->hdr.cmd]) {
|
|
||||||
IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
|
|
||||||
i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
|
|
||||||
priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
|
|
||||||
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
|
|
||||||
} else {
|
|
||||||
/* No handling needed */
|
|
||||||
IWL_DEBUG_RX(priv,
|
|
||||||
"r %d i %d No handler needed for %s, 0x%02x\n",
|
|
||||||
r, i, get_cmd_string(pkt->hdr.cmd),
|
|
||||||
pkt->hdr.cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: After here, we should always check rxb->page
|
* XXX: After here, we should always check rxb->page
|
||||||
|
@@ -187,6 +187,8 @@ void iwlagn_rx_replenish(struct iwl_priv *priv);
|
|||||||
void iwlagn_rx_replenish_now(struct iwl_priv *priv);
|
void iwlagn_rx_replenish_now(struct iwl_priv *priv);
|
||||||
int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
|
int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
|
||||||
void iwl_setup_rx_handlers(struct iwl_priv *priv);
|
void iwl_setup_rx_handlers(struct iwl_priv *priv);
|
||||||
|
void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
|
||||||
|
|
||||||
|
|
||||||
/* tx */
|
/* tx */
|
||||||
void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq,
|
void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq,
|
||||||
|
@@ -1105,3 +1105,49 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
|
|||||||
/* Set up hardware specific Rx handlers */
|
/* Set up hardware specific Rx handlers */
|
||||||
priv->cfg->ops->lib->rx_handler_setup(priv);
|
priv->cfg->ops->lib->rx_handler_setup(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||||
|
{
|
||||||
|
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the notification wait before RX handlers so
|
||||||
|
* even if the RX handler consumes the RXB we have
|
||||||
|
* access to it in the notification wait entry.
|
||||||
|
*/
|
||||||
|
if (!list_empty(&priv->_agn.notif_waits)) {
|
||||||
|
struct iwl_notification_wait *w;
|
||||||
|
|
||||||
|
spin_lock(&priv->_agn.notif_wait_lock);
|
||||||
|
list_for_each_entry(w, &priv->_agn.notif_waits, list) {
|
||||||
|
if (w->cmd != pkt->hdr.cmd)
|
||||||
|
continue;
|
||||||
|
IWL_DEBUG_RX(priv,
|
||||||
|
"Notif: %s, 0x%02x - wake the callers up\n",
|
||||||
|
get_cmd_string(pkt->hdr.cmd),
|
||||||
|
pkt->hdr.cmd);
|
||||||
|
w->triggered = true;
|
||||||
|
if (w->fn)
|
||||||
|
w->fn(priv, pkt, w->fn_data);
|
||||||
|
}
|
||||||
|
spin_unlock(&priv->_agn.notif_wait_lock);
|
||||||
|
|
||||||
|
wake_up_all(&priv->_agn.notif_waitq);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->pre_rx_handler)
|
||||||
|
priv->pre_rx_handler(priv, rxb);
|
||||||
|
|
||||||
|
/* Based on type of command response or notification,
|
||||||
|
* handle those that need handling via function in
|
||||||
|
* rx_handlers table. See iwl_setup_rx_handlers() */
|
||||||
|
if (priv->rx_handlers[pkt->hdr.cmd]) {
|
||||||
|
priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
|
||||||
|
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
|
||||||
|
} else {
|
||||||
|
/* No handling needed */
|
||||||
|
IWL_DEBUG_RX(priv,
|
||||||
|
"No handler needed for %s, 0x%02x\n",
|
||||||
|
get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user