Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ab9f6c1 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Wey-Yi Guy
Browse files

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: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent a27367d2
Loading
Loading
Loading
Loading
+4 −38
Original line number Diff line number Diff line
@@ -513,6 +513,9 @@ static void iwl_rx_handle(struct iwl_priv *priv)
			       DMA_FROM_DEVICE);
		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 += sizeof(u32); /* account for status word */
		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 != REPLY_TX);

		/*
		 * 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);
		}
		iwl_rx_dispatch(priv, rxb);

		/*
		 * XXX: After here, we should always check rxb->page
+2 −0
Original line number Diff line number Diff line
@@ -187,6 +187,8 @@ void iwlagn_rx_replenish(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);
void iwl_setup_rx_handlers(struct iwl_priv *priv);
void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);


/* tx */
void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+46 −0
Original line number Diff line number Diff line
@@ -1105,3 +1105,49 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
	/* Set up hardware specific Rx handlers */
	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);
	}
}