summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
diff options
context:
space:
mode:
authorAmit Beka <amit.beka@intel.com>2012-03-07 09:52:29 -0800
committerJohn W. Linville <linville@tuxdriver.com>2012-03-08 13:59:52 -0500
commit0aef8ddc8bedac1db4c96fddc9fb1b44b730cf4f (patch)
tree5d1e270ed94fc179643d7d4229aa4e7959c35e85 /drivers/net/wireless/iwlwifi/iwl-agn-rx.c
parent8722c899a07f45457464803142bd1c2d2a2c3bd8 (diff)
iwlwifi: add testmode command for rx forwarding
Added a testmode command which tells iwl_rx_dispatch to send the RX both as a notification to nl80211 and with the registered RX handlers. This is used for monitoring RX from userspace while preserving the regular flows in the driver. Signed-off-by: Amit Beka <amit.beka@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index e504675f263..8e7cdfaf10c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -1152,6 +1152,8 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+ void (*pre_rx_handler)(struct iwl_priv *,
+ struct iwl_rx_cmd_buffer *);
int err = 0;
/*
@@ -1161,10 +1163,20 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
*/
iwl_notification_wait_notify(&priv->notif_wait, pkt);
- if (priv->pre_rx_handler &&
- priv->ucode_owner == IWL_OWNERSHIP_TM)
- priv->pre_rx_handler(priv, rxb);
- else {
+ /* RX data may be forwarded to userspace (using pre_rx_handler) in one
+ * of two cases: the first, that the user owns the uCode through
+ * testmode - in such case the pre_rx_handler is set and no further
+ * processing takes place. The other case is when the user want to
+ * monitor the rx w/o affecting the regular flow - the pre_rx_handler
+ * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow
+ * continues.
+ * We need to use ACCESS_ONCE to prevent a case where the handler
+ * changes between the check and the call.
+ */
+ pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler);
+ if (pre_rx_handler)
+ pre_rx_handler(priv, rxb);
+ if (priv->ucode_owner != IWL_OWNERSHIP_TM) {
/* Based on type of command response or notification,
* handle those that need handling via function in
* rx_handlers table. See iwl_setup_rx_handlers() */