Browse Source

qca-wifi: MSCS module implementation

Implement a new driver module for Mirrored stream classification
signalling(MSCS) feature. This module which register to NSS MSCS client
to provide callback for peer lookup and priority update based on MSCS
parameters associated with a peer

Change-Id: I7aa465446cb22f0198459193fa04dd66fc903cc7
Mainak Sen 4 years ago
parent
commit
29417fc9d2
5 changed files with 316 additions and 0 deletions
  1. 108 0
      dp/wifi3.0/dp_mscs.c
  2. 28 0
      dp/wifi3.0/dp_mscs.h
  3. 32 0
      qca_mscs/inc/qca_mscs.h
  4. 24 0
      qca_mscs/inc/qca_mscs_if.h
  5. 124 0
      qca_mscs/src/qca_mscs.c

+ 108 - 0
dp/wifi3.0/dp_mscs.c

@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "dp_peer.h"
+#include "qdf_nbuf.h"
+#include "dp_types.h"
+#include "dp_internal.h"
+#include "dp_tx.h"
+#include "dp_mscs.h"
+
+#define DP_MSCS_INVALID_TID 0xFF
+#define DP_MSCS_VALID_TID_MASK 0x7
+
+/**
+ * dp_mscs_peer_lookup_n_get_priority() - Get priority for MSCS peer
+ * @soc_hdl - soc handle
+ * @src_mac_addr - src mac address from connection
+ * @nbuf - network buffer
+ *
+ * Return: 0 when peer has active mscs session and valid user priority
+ */
+int dp_mscs_peer_lookup_n_get_priority(struct cdp_soc_t *soc_hdl,
+		uint8_t *src_mac_addr, qdf_nbuf_t nbuf)
+{
+	struct dp_peer *peer;
+	uint8_t user_prio_bitmap;
+	uint8_t user_prio_limit;
+	uint8_t user_prio;
+	int status = 0;
+	struct dp_soc *dpsoc = cdp_soc_t_to_dp_soc(soc_hdl);
+
+	if (!dpsoc) {
+		QDF_TRACE(QDF_MODULE_ID_MSCS, QDF_TRACE_LEVEL_ERROR,
+				"%s: Invalid soc\n", __func__);
+		return -1;
+	}
+
+	/*
+	 * Find the MSCS peer from global soc
+	 */
+	peer = dp_peer_find_hash_find(dpsoc, src_mac_addr, 0,
+			DP_VDEV_ALL, DP_MOD_ID_MSCS);
+
+	if (!peer) {
+		/*
+		 * No WLAN client peer found with this peer mac
+		 */
+		return -1;
+	}
+
+	/*
+	 * check if there is any active MSCS session for this peer
+	 */
+	if (!peer->mscs_active) {
+		QDF_TRACE(QDF_MODULE_ID_MSCS, QDF_TRACE_LEVEL_DEBUG,
+				"%s: MSCS session not active on peer or peer delete in progress\n", __func__);
+		status = 1;
+		goto fail;
+	}
+
+	/*
+	 * Get user priority bitmap for this peer MSCS active session
+	 */
+	user_prio_bitmap = peer->mscs_ipv4_parameter.user_priority_bitmap;
+	user_prio_limit = peer->mscs_ipv4_parameter.user_priority_limit;
+	user_prio = qdf_nbuf_get_priority(nbuf) & DP_MSCS_VALID_TID_MASK;
+
+	/*
+	 * check if nbuf priority is matching with any of the valid priority value
+	 */
+	if (!((1 << user_prio) & user_prio_bitmap)) {
+		QDF_TRACE(QDF_MODULE_ID_MSCS, QDF_TRACE_LEVEL_DEBUG,
+				"%s: Nbuf TID is not valid, no match in user prioroty bitmap\n", __func__);
+		status = 1;
+		goto fail;
+	}
+
+	user_prio = QDF_MIN(user_prio, user_prio_limit);
+
+	/*
+	 * Update skb priority
+	 */
+	qdf_nbuf_set_priority(nbuf, user_prio);
+	QDF_TRACE(QDF_MODULE_ID_MSCS, QDF_TRACE_LEVEL_DEBUG,
+			"%s: User priority for this MSCS session %d\n", __func__, user_prio);
+	status = 0;
+
+fail:
+	if (peer)
+		dp_peer_unref_delete(peer, DP_MOD_ID_MSCS);
+	return status;
+}
+
+qdf_export_symbol(dp_mscs_peer_lookup_n_get_priority);

+ 28 - 0
dp/wifi3.0/dp_mscs.h

@@ -0,0 +1,28 @@
+
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DP_MSCS_H_
+#define _DP_MSCS_H_
+
+#if WLAN_SUPPORT_MSCS
+int dp_mscs_peer_lookup_n_get_priority(struct cdp_soc_t *soc_hdl,
+		        uint8_t *src_mac_addr, qdf_nbuf_t nbuf);
+#endif
+
+#endif /* QCA_MSCS_H*/

+ 32 - 0
qca_mscs/inc/qca_mscs.h

@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __qca_mscs_H_
+#define __qca_mscs_H_
+#include <qdf_module.h>
+#include <qdf_nbuf.h>
+#include <qdf_trace.h>
+#include <ol_if_athvar.h>
+
+#if WLAN_SUPPORT_MSCS
+void qca_mscs_module_init(ol_ath_soc_softc_t *soc);
+void qca_mscs_module_deinit(ol_ath_soc_softc_t *soc);
+#endif
+
+#endif /* qca_mscs_H*/

+ 24 - 0
qca_mscs/inc/qca_mscs_if.h

@@ -0,0 +1,24 @@
+
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __qca_mscs_if_H_
+#define __qca_mscs_if_H_
+
+int qca_mscs_peer_lookup_n_get_priority(uint8_t *src_mac, struct sk_buff *skb);
+#endif /* qca_mscs_if_H*/

+ 124 - 0
qca_mscs/src/qca_mscs.c

@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "qca_mscs.h"
+#include "qca_mscs_if.h"
+
+static int mscs_soc_attached_count;
+extern ol_ath_soc_softc_t *ol_global_soc[GLOBAL_SOC_SIZE];
+
+/**
+ * qca_mscs_peer_lookup_n_get_priority() - Find MSCS enabled peer and priority
+ * @src_mac - src mac address to be used for peer lookup
+ * @nbuf - network buffer
+ * @priority - priority/tid to be updated
+ *
+ * Return: QDF_STATUS_SUCCESS for successful peer lookup
+ */
+int qca_mscs_peer_lookup_n_get_priority(uint8_t *src_mac, struct sk_buff *skb)
+{
+	uint8_t i = 0;
+	ol_ath_soc_softc_t *soc = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	ol_txrx_soc_handle soc_txrx_handle = NULL;
+	qdf_nbuf_t nbuf = (qdf_nbuf_t)skb;
+
+	/*
+	 * Loop over all the attached soc for peer lookup
+	 * with given src mac address
+	 */
+	for (i = 0; i < GLOBAL_SOC_SIZE; i++) {
+		if (!ol_global_soc[i])
+			continue;
+
+		soc = ol_global_soc[i];
+		soc_txrx_handle = wlan_psoc_get_dp_handle(soc->psoc_obj);
+		status = cdp_mscs_peer_lookup_n_get_priority(soc_txrx_handle,
+				src_mac, nbuf);
+		/*
+		 * wifi peer is found with this mac address.there can
+		 * be 3 possiblities -
+		 * 1. peer has no active MSCS session.
+		 * 2. peer has active MSCS session but priority not valid.
+		 * 3. peer has active MSCS session and priority is valid.
+		 * return the status to ECM classifier.
+		 */
+		if (status >= QDF_STATUS_SUCCESS)
+			return status;
+		/*
+		 * no wifi peer exists in this soc with given src mac address
+		 * iterate over next soc
+		 */
+	}
+
+	if (i == GLOBAL_SOC_SIZE)
+		/*
+		 * No wlan peer is found in any of attached
+		 * soc with given mac address
+		 * return the status to ECM classifier.
+		 */
+		status = QDF_STATUS_E_FAILURE;
+
+	return status;
+}
+
+qdf_export_symbol(qca_mscs_peer_lookup_n_get_priority);
+
+/**
+ * qca_mscs_module_init() - Initialize the MSCS module
+ * @soc - Pointer to soc getting attached
+ *
+ * Return: void
+ */
+
+void qca_mscs_module_init(ol_ath_soc_softc_t *soc)
+{
+	/* Check if soc max init count is reached */
+	if (mscs_soc_attached_count >= GLOBAL_SOC_SIZE)
+		return;
+
+	QDF_TRACE(QDF_MODULE_ID_MSCS, QDF_TRACE_LEVEL_INFO,
+			     FL("\n****QCA MSCS Initialization Done**** SoC %pK"), soc);
+
+	mscs_soc_attached_count++;
+}
+
+qdf_export_symbol(qca_mscs_module_init);
+
+/**
+ * qca_mscs_module_deinit() - De-Initialize MSCS module
+ * @soc - Pointer to soc getting detached
+ *
+ * Return: void
+ */
+void qca_mscs_module_deinit(ol_ath_soc_softc_t *soc)
+{
+	if (!soc)
+		return;
+
+	/*
+	 * All soc are detached by now
+	 */
+	if (mscs_soc_attached_count < 0)
+		return;
+
+	QDF_TRACE(QDF_MODULE_ID_MSCS, QDF_TRACE_LEVEL_INFO,
+			FL("\n****QCA MSCS De-Initialization Done**** SoC %pK"), soc);
+	mscs_soc_attached_count--;
+}
+
+qdf_export_symbol(qca_mscs_module_deinit);