Prechádzať zdrojové kódy

qcacmn: Register separate function pointer to receive EAPOL frames

Add changes to register separate function pointer to receive EAPOL
frames instead of using regular RX path and adding export symbol
for __qdf_nbuf_data_get_eapol_subtype() to access in it multiple
modules

Change-Id: Id05b982d31a7e008536d10dd5281e88cceba96db
Shiva Sankar Gajula 3 rokov pred
rodič
commit
dcbdb29d04

+ 4 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -971,6 +971,7 @@ typedef void (*ol_txrx_pktdump_cb)(ol_txrx_soc_handle soc,
  * format specified by the OS to use for tx and rx
  * frames (either 802.3 or native WiFi). In case RX Threads are enabled, pkts
  * are given to the thread, instead of the stack via this pointer.
+ * @rx.rx_eapol - This rx function pointer used to receive only eapol frames
  * @rx.stack - function to give packets to the stack. Differs from @rx.rx.
  * In case RX Threads are enabled, this pointer holds the callback to give
  * packets to the stack.
@@ -1006,6 +1007,9 @@ struct ol_txrx_ops {
 	/* rx function pointers - specified by OS shim, stored by txrx */
 	struct {
 		ol_txrx_rx_fp           rx;
+#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
+		ol_txrx_rx_fp     rx_eapol;
+#endif
 		ol_txrx_rx_fp           rx_stack;
 		ol_txrx_rx_flush_fp     rx_flush;
 		ol_txrx_rx_gro_flush_ind_fp           rx_gro_flush;

+ 5 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -2134,10 +2134,15 @@ struct cdp_peer_hmwds_ast_add_status {
 	uint8_t  ast_mac[QDF_MAC_ADDR_SIZE];
 };
 
+/*
+ * Enumeration of cdp soc parameters
+ * @DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT: For sending EAPOL's over control port
+ */
 enum cdp_soc_param_t {
 	DP_SOC_PARAM_MSDU_EXCEPTION_DESC,
 	DP_SOC_PARAM_CMEM_FSE_SUPPORT,
 	DP_SOC_PARAM_MAX_AST_AGEOUT,
+	DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT,
 	DP_SOC_PARAM_MAX,
 };
 

+ 43 - 0
dp/wifi3.0/dp_main.c

@@ -5763,6 +5763,41 @@ static void dp_vdev_pdev_list_remove(struct dp_soc *soc,
 	qdf_spin_unlock_bh(&pdev->vdev_list_lock);
 }
 
+#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
+/*
+ * dp_vdev_init_rx_eapol() - initializing osif_rx_eapol
+ * @vdev: Datapath VDEV handle
+ *
+ * Return: None
+ */
+static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev)
+{
+	vdev->osif_rx_eapol = NULL;
+}
+
+/*
+ * dp_vdev_register_rx_eapol() - Register VDEV operations for rx_eapol
+ * @vdev: DP vdev handle
+ * @txrx_ops: Tx and Rx operations
+ *
+ * Return: None
+ */
+static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
+					     struct ol_txrx_ops *txrx_ops)
+{
+	vdev->osif_rx_eapol = txrx_ops->rx.rx_eapol;
+}
+#else
+static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev)
+{
+}
+
+static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
+					     struct ol_txrx_ops *txrx_ops)
+{
+}
+#endif
+
 /*
 * dp_vdev_attach_wifi3() - attach txrx vdev
 * @txrx_pdev: Datapath PDEV handle
@@ -5825,6 +5860,7 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
 	vdev->drop_unenc = 1;
 	vdev->sec_type = cdp_sec_type_none;
 	vdev->multipass_en = false;
+	dp_vdev_init_rx_eapol(vdev);
 	qdf_atomic_init(&vdev->ref_cnt);
 	for (i = 0; i < DP_MOD_ID_MAX; i++)
 		qdf_atomic_init(&vdev->mod_refs[i]);
@@ -5998,6 +6034,8 @@ static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc_hdl,
 #endif
 	vdev->me_convert = txrx_ops->me_convert;
 
+	dp_vdev_register_rx_eapol(vdev, txrx_ops);
+
 	dp_vdev_register_tx_handler(vdev, soc, txrx_ops);
 
 	dp_init_info("%pK: DP Vdev Register success", soc);
@@ -10258,6 +10296,11 @@ static QDF_STATUS dp_soc_set_param(struct cdp_soc_t  *soc_hdl,
 		soc->max_ast_ageout_count = value;
 		dp_info("Max ast ageout count %u", soc->max_ast_ageout_count);
 		break;
+	case DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT:
+		soc->eapol_over_control_port = value;
+		dp_info("Eapol over control_port:%d",
+			soc->eapol_over_control_port);
+		break;
 	default:
 		dp_info("not handled param %d ", param);
 		break;

+ 48 - 6
dp/wifi3.0/dp_rx.c

@@ -1582,13 +1582,23 @@ static void dp_rx_check_delivery_to_stack(struct dp_soc *soc,
 }
 #endif /* ifdef DELIVERY_TO_STACK_STATUS_CHECK */
 
-void dp_rx_deliver_to_stack(struct dp_soc *soc,
+/*
+ * dp_rx_validate_rx_callbacks() - validate rx callbacks
+ * @soc DP soc
+ * @vdev: DP vdev handle
+ * @peer: pointer to the peer object
+ * nbuf_head: skb list head
+ *
+ * Return: QDF_STATUS - QDF_STATUS_SUCCESS
+ *			QDF_STATUS_E_FAILURE
+ */
+static inline QDF_STATUS
+dp_rx_validate_rx_callbacks(struct dp_soc *soc,
 			    struct dp_vdev *vdev,
 			    struct dp_peer *peer,
-			    qdf_nbuf_t nbuf_head,
-			    qdf_nbuf_t nbuf_tail)
+			    qdf_nbuf_t nbuf_head)
 {
-	int num_nbuf = 0;
+	int num_nbuf;
 
 	if (qdf_unlikely(!vdev || vdev->delete.pending)) {
 		num_nbuf = dp_rx_drop_nbuf_list(NULL, nbuf_head);
@@ -1598,7 +1608,7 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc,
 		 * belonged. Hence we update the soc rx error stats.
 		 */
 		DP_STATS_INC(soc, rx.err.invalid_vdev, num_nbuf);
-		return;
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	/*
@@ -1613,9 +1623,22 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc,
 							nbuf_head);
 			DP_STATS_DEC(peer, rx.to_stack.num, num_nbuf);
 		}
-		return;
+		return QDF_STATUS_E_FAILURE;
 	}
 
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS dp_rx_deliver_to_stack(struct dp_soc *soc,
+				  struct dp_vdev *vdev,
+				  struct dp_peer *peer,
+				  qdf_nbuf_t nbuf_head,
+				  qdf_nbuf_t nbuf_tail)
+{
+	if (dp_rx_validate_rx_callbacks(soc, vdev, peer, nbuf_head) !=
+					QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_FAILURE;
+
 	if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw) ||
 			(vdev->rx_decap_type == htt_cmn_pkt_type_native_wifi)) {
 		vdev->osif_rsim_rx_decap(vdev->osif_vdev, &nbuf_head,
@@ -1623,8 +1646,27 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc,
 	}
 
 	dp_rx_check_delivery_to_stack(soc, vdev, peer, nbuf_head);
+
+	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
+QDF_STATUS dp_rx_eapol_deliver_to_stack(struct dp_soc *soc,
+					struct dp_vdev *vdev,
+					struct dp_peer *peer,
+					qdf_nbuf_t nbuf_head,
+					qdf_nbuf_t nbuf_tail)
+{
+	if (dp_rx_validate_rx_callbacks(soc, vdev, peer, nbuf_head) !=
+					QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_FAILURE;
+
+	vdev->osif_rx_eapol(vdev->osif_vdev, nbuf_head);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 #ifndef QCA_HOST_MODE_WIFI_DISABLED
 #ifdef VDEV_PEER_PROTOCOL_COUNT
 #define dp_rx_msdu_stats_update_prot_cnts(vdev_hdl, nbuf, peer) \

+ 25 - 6
dp/wifi3.0/dp_rx.h

@@ -1587,13 +1587,32 @@ QDF_STATUS dp_peer_set_rx_capture_enabled(struct dp_pdev *pdev,
  * @nbuf_head: skb list head
  * @nbuf_tail: skb list tail
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-void dp_rx_deliver_to_stack(struct dp_soc *soc,
-			    struct dp_vdev *vdev,
-			    struct dp_peer *peer,
-			    qdf_nbuf_t nbuf_head,
-			    qdf_nbuf_t nbuf_tail);
+QDF_STATUS dp_rx_deliver_to_stack(struct dp_soc *soc,
+				  struct dp_vdev *vdev,
+				  struct dp_peer *peer,
+				  qdf_nbuf_t nbuf_head,
+				  qdf_nbuf_t nbuf_tail);
+
+#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
+/**
+ * dp_rx_eapol_deliver_to_stack() - deliver pkts to network stack
+ * caller to hold peer refcount and check for valid peer
+ * @soc: soc
+ * @vdev: vdev
+ * @peer: peer
+ * @nbuf_head: skb list head
+ * @nbuf_tail: skb list tail
+ *
+ * return: QDF_STATUS
+ */
+QDF_STATUS dp_rx_eapol_deliver_to_stack(struct dp_soc *soc,
+					struct dp_vdev *vdev,
+					struct dp_peer *peer,
+					qdf_nbuf_t nbuf_head,
+					qdf_nbuf_t nbuf_tail);
+#endif
 
 #ifndef QCA_HOST_MODE_WIFI_DISABLED
 

+ 45 - 3
dp/wifi3.0/dp_rx_err.c

@@ -1742,6 +1742,44 @@ fail:
 	return;
 }
 
+/*
+ * dp_rx_deliver_to_osif_stack() - function to deliver rx pkts to stack
+ * @soc: DP soc
+ * @vdv: DP vdev handle
+ * @peer: pointer to the peer object
+ * @nbuf: skb list head
+ * @tail: skb list tail
+ * @is_eapol: eapol pkt check
+ *
+ * Return: None
+ */
+#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
+static inline void
+dp_rx_deliver_to_osif_stack(struct dp_soc *soc,
+			    struct dp_vdev *vdev,
+			    struct dp_peer *peer,
+			    qdf_nbuf_t nbuf,
+			    qdf_nbuf_t tail,
+			    bool is_eapol)
+{
+	if (is_eapol && soc->eapol_over_control_port)
+		dp_rx_eapol_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
+	else
+		dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
+}
+#else
+static inline void
+dp_rx_deliver_to_osif_stack(struct dp_soc *soc,
+			    struct dp_vdev *vdev,
+			    struct dp_peer *peer,
+			    qdf_nbuf_t nbuf,
+			    qdf_nbuf_t tail,
+			    bool is_eapol)
+{
+	dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
+}
+#endif
+
 #ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG
 /**
  * dp_rx_err_route_hdl() - Function to send EAPOL frames to stack
@@ -1768,6 +1806,7 @@ dp_rx_err_route_hdl(struct dp_soc *soc, qdf_nbuf_t nbuf,
 	uint16_t msdu_len;
 	struct dp_vdev *vdev;
 	struct hal_rx_msdu_metadata msdu_metadata;
+	bool is_eapol;
 
 	hal_rx_msdu_metadata_get(soc->hal_soc, rx_tlv_hdr, &msdu_metadata);
 	msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc, rx_tlv_hdr);
@@ -1820,8 +1859,8 @@ dp_rx_err_route_hdl(struct dp_soc *soc, qdf_nbuf_t nbuf,
 	 * Indicate EAPOL frame to stack only when vap mac address
 	 * matches the destination address.
 	 */
-	if (qdf_nbuf_is_ipv4_eapol_pkt(nbuf) ||
-	    qdf_nbuf_is_ipv4_wapi_pkt(nbuf)) {
+	is_eapol = qdf_nbuf_is_ipv4_eapol_pkt(nbuf);
+	if (is_eapol || qdf_nbuf_is_ipv4_wapi_pkt(nbuf)) {
 		qdf_ether_header_t *eh =
 			(qdf_ether_header_t *)qdf_nbuf_data(nbuf);
 		if (qdf_mem_cmp(eh->ether_dhost, &vdev->mac_addr.raw[0],
@@ -1839,7 +1878,10 @@ dp_rx_err_route_hdl(struct dp_soc *soc, qdf_nbuf_t nbuf,
 			DP_STATS_INC(peer, rx.to_stack.num, 1);
 			qdf_nbuf_set_exc_frame(nbuf, 1);
 			qdf_nbuf_set_next(nbuf, NULL);
-			dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
+
+			dp_rx_deliver_to_osif_stack(soc, vdev, peer, nbuf,
+						    NULL, is_eapol);
+
 			return;
 		}
 	}

+ 5 - 0
dp/wifi3.0/dp_types.h

@@ -1913,6 +1913,7 @@ struct dp_soc {
 	uint8_t wds_ast_aging_timer_cnt;
 	bool pending_ageout;
 	uint32_t max_ast_ageout_count;
+	uint8_t eapol_over_control_port;
 
 	qdf_timer_t lmac_reap_timer;
 	uint8_t lmac_timer_init;
@@ -2706,6 +2707,10 @@ struct dp_vdev {
 	ol_txrx_rx_gro_flush_ind_fp osif_gro_flush;
 	/* default RX call back function called by dp */
 	ol_txrx_rx_fp osif_rx;
+#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
+	/* callback to receive eapol frames */
+	ol_txrx_rx_fp osif_rx_eapol;
+#endif
 	/* callback to deliver rx frames to the OS */
 	ol_txrx_rx_fp osif_rx_stack;
 	/* Callback to handle rx fisa frames */

+ 2 - 0
qdf/linux/src/qdf_nbuf.c

@@ -1358,6 +1358,8 @@ __qdf_nbuf_data_get_eapol_subtype(uint8_t *data)
 	return subtype;
 }
 
+qdf_export_symbol(__qdf_nbuf_data_get_eapol_subtype);
+
 /**
  * __qdf_nbuf_data_get_arp_subtype() - get the subtype
  *            of ARP packet.