Merge "qca-wifi: MSCS module implementation"
diff --git a/dp/wifi3.0/dp_mscs.c b/dp/wifi3.0/dp_mscs.c
new file mode 100644
index 0000000..a69beaf
--- /dev/null
+++ b/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);
diff --git a/dp/wifi3.0/dp_mscs.h b/dp/wifi3.0/dp_mscs.h
new file mode 100644
index 0000000..911fe5c
--- /dev/null
+++ b/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*/
diff --git a/qca_mscs/inc/qca_mscs.h b/qca_mscs/inc/qca_mscs.h
new file mode 100644
index 0000000..e8c8339
--- /dev/null
+++ b/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*/
diff --git a/qca_mscs/inc/qca_mscs_if.h b/qca_mscs/inc/qca_mscs_if.h
new file mode 100644
index 0000000..002f05e
--- /dev/null
+++ b/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*/
diff --git a/qca_mscs/src/qca_mscs.c b/qca_mscs/src/qca_mscs.c
new file mode 100644
index 0000000..2110bbb
--- /dev/null
+++ b/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);