Explorar el Código

qcacld-3.0: Configure callback function for monitor mode traffic

Configure HDD callback function to process packets received in
monitor mode for lithium based chipsets.

Change-Id: I8c742a10c00e667736400a064f17bbb7144521e4
CRs-Fixed: 1113187
Ravi Joshi hace 8 años
padre
commit
106ffe0f1e

+ 93 - 1
core/hdd/src/wlan_hdd_rx_monitor.c

@@ -24,5 +24,97 @@
  * under proprietary terms before Copyright ownership was assigned
  * to the Linux Foundation.
  */
-
+#include "wlan_hdd_includes.h"
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <cds_sched.h>
+#include <cds_utils.h>
 #include "wlan_hdd_rx_monitor.h"
+
+/**
+ * hdd_rx_monitor_callback(): Callback function for receive monitor mode
+ * @vdev: Handle to vdev object
+ * @mpdu: pointer to mpdu to be delivered to os
+ * @rx_status: receive status
+ *
+ * Returns: None
+ */
+void hdd_rx_monitor_callback(ol_osif_vdev_handle context,
+				qdf_nbuf_t rxbuf,
+				void *rx_status)
+{
+	hdd_adapter_t *adapter;
+	int rxstat;
+	struct sk_buff *skb;
+	struct sk_buff *skb_next;
+	unsigned int cpu_index;
+
+	qdf_assert(context);
+	qdf_assert(rxbuf);
+
+	adapter = (hdd_adapter_t *)context;
+	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
+			"invalid adapter %p", adapter);
+		return;
+	}
+
+	cpu_index = wlan_hdd_get_cpu();
+
+	/* walk the chain until all are processed */
+	skb = (struct sk_buff *)rxbuf;
+	while (NULL != skb) {
+		skb_next = skb->next;
+		skb->dev = adapter->dev;
+
+		++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
+		++adapter->stats.rx_packets;
+		adapter->stats.rx_bytes += skb->len;
+
+		/* Remove SKB from internal tracking table before submitting
+		 * it to stack
+		 */
+		qdf_net_buf_debug_release_skb(skb);
+
+		/*
+		 * If this is not a last packet on the chain
+		 * Just put packet into backlog queue, not scheduling RX sirq
+		 */
+		if (skb->next) {
+			rxstat = netif_rx(skb);
+		} else {
+			/*
+			 * This is the last packet on the chain
+			 * Scheduling rx sirq
+			 */
+			rxstat = netif_rx_ni(skb);
+		}
+
+		if (NET_RX_SUCCESS == rxstat)
+			++adapter->
+				hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
+		else
+			++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
+
+		skb = skb_next;
+	}
+
+	adapter->dev->last_rx = jiffies;
+
+	return;
+}
+
+/**
+ * hdd_monitor_set_rx_monitor_cb(): Set rx monitor mode callback function
+ * @txrx: pointer to txrx ops
+ * @rx_monitor_cb: pointer to callback function
+ *
+ * Returns: None
+ */
+void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+				ol_txrx_rx_mon_fp rx_monitor_cb)
+{
+	txrx->rx.mon = rx_monitor_cb;
+}

+ 17 - 0
core/hdd/src/wlan_hdd_rx_monitor.h

@@ -28,5 +28,22 @@
 #ifndef __WLAN_HDD_RX_MONITOR_H
 #define __WLAN_HDD_RX_MONITOR_H
 
+struct ol_txrx_ops;
+
+#if defined(QCA_WIFI_QCA6290)
+void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+				ol_txrx_rx_mon_fp rx_monitor_cb);
+
+void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
+				qdf_nbuf_t mpdu,
+				void *rx_status);
+#else
+static void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+					ol_txrx_rx_mon_fp rx_monitor_cb){ }
+static void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
+				qdf_nbuf_t mpdu,
+				void *rx_status){ }
+#endif /* CONFIG_LITHIUM */
+
 #endif /* __WLAN_HDD_RX_MONITOR_H */
 

+ 3 - 0
core/hdd/src/wlan_hdd_tx_rx.c

@@ -60,6 +60,8 @@
 #include "wlan_hdd_nan_datapath.h"
 #include "pld_common.h"
 #include <cdp_txrx_handle.h>
+#include "wlan_hdd_rx_monitor.h"
+
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
 /*
  * Mapping Linux AC interpretation to SME AC.
@@ -1427,6 +1429,7 @@ int hdd_set_mon_rx_cb(struct net_device *dev)
 
 	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
 	txrx_ops.rx.rx = hdd_mon_rx_packet_cbk;
+	hdd_monitor_set_rx_monitor_cb(&txrx_ops, hdd_rx_monitor_callback);
 	cdp_vdev_register(soc,
 		(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
 		(struct cdp_pdev *)pdev, adapter->sessionId),