qcacld-3.0: add support to customize dscp-to-up map table
Add support to customize DSCP-to-UP map table and send the
customized map values to FW to update its corresponding
map table.
Change-Id: Ibe9704a90468c898dd2e60fdf83a271152f654ce
CRs-Fixed: 2616247
diff --git a/Kbuild b/Kbuild
index d128727..f09fa79 100644
--- a/Kbuild
+++ b/Kbuild
@@ -3140,6 +3140,9 @@
cppflags-$(CONFIG_WDI3_STATS_UPDATE) += -DWDI3_STATS_UPDATE
+cppflags-$(CONFIG_WLAN_CUSTOM_DSCP_UP_MAP) += -DWLAN_CUSTOM_DSCP_UP_MAP
+cppflags-$(CONFIG_WLAN_SEND_DSCP_UP_MAP_TO_FW) += -DWLAN_SEND_DSCP_UP_MAP_TO_FW
+
KBUILD_CPPFLAGS += $(cppflags-y)
# Currently, for versions of gcc which support it, the kernel Makefile
diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_public_structs.h b/components/fw_offload/dispatcher/inc/wlan_fwol_public_structs.h
index ea0863b..10f253a 100644
--- a/components/fw_offload/dispatcher/inc/wlan_fwol_public_structs.h
+++ b/components/fw_offload/dispatcher/inc/wlan_fwol_public_structs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-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
@@ -76,6 +76,7 @@
* @get_elna_bypass: get eLNA bypass
* @reg_evt_handler: register event handler
* @unreg_evt_handler: unregister event handler
+ * @send_dscp_up_map_to_fw: send dscp-to-up map values to FW
*/
struct wlan_fwol_tx_ops {
#ifdef WLAN_FEATURE_ELNA
@@ -88,6 +89,11 @@
void *arg);
QDF_STATUS (*unreg_evt_handler)(struct wlan_objmgr_psoc *psoc,
void *arg);
+#ifdef WLAN_SEND_DSCP_UP_MAP_TO_FW
+ QDF_STATUS (*send_dscp_up_map_to_fw)(
+ struct wlan_objmgr_psoc *psoc,
+ uint32_t *dscp_to_up_map);
+#endif
};
/**
diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
index 4eace38..9c9fa98 100644
--- a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
+++ b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-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
@@ -543,6 +543,27 @@
struct get_elna_bypass_response *response),
void *context);
#endif /* WLAN_FEATURE_ELNA */
+
+#ifdef WLAN_SEND_DSCP_UP_MAP_TO_FW
+/**
+ * ucfg_fwol_send_dscp_up_map_to_fw() - send dscp_up map to FW
+ * @vdev: vdev handle
+ * @dscp_to_up_map: DSCP to UP map array
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_fwol_send_dscp_up_map_to_fw(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t *dscp_to_up_map);
+#else
+static inline
+QDF_STATUS ucfg_fwol_send_dscp_up_map_to_fw(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t *dscp_to_up_map)
+{
+ return QDF_STATUS_SUCCESS;
+}
+#endif
#else
static inline QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
{
diff --git a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
index 5cabba3..e66c986 100644
--- a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
+++ b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-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
@@ -896,3 +896,34 @@
return status;
}
#endif /* WLAN_FEATURE_ELNA */
+
+#ifdef WLAN_SEND_DSCP_UP_MAP_TO_FW
+QDF_STATUS ucfg_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_vdev *vdev,
+ uint32_t *dscp_to_up_map)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_fwol_psoc_obj *fwol_obj;
+ struct wlan_fwol_tx_ops *tx_ops;
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ fwol_err("NULL pointer for psoc");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ fwol_obj = fwol_get_psoc_obj(psoc);
+ if (!fwol_obj) {
+ fwol_err("Failed to get FWOL Obj");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ tx_ops = &fwol_obj->tx_ops;
+ if (tx_ops && tx_ops->send_dscp_up_map_to_fw)
+ status = tx_ops->send_dscp_up_map_to_fw(psoc, dscp_to_up_map);
+ else
+ status = QDF_STATUS_E_IO;
+
+ return status;
+}
+#endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
diff --git a/components/target_if/fw_offload/src/target_if_fwol.c b/components/target_if/fw_offload/src/target_if_fwol.c
index 6aa936a..11b6510 100644
--- a/components/target_if/fw_offload/src/target_if_fwol.c
+++ b/components/target_if/fw_offload/src/target_if_fwol.c
@@ -201,6 +201,45 @@
}
#endif /* WLAN_FEATURE_ELNA */
+#ifdef WLAN_SEND_DSCP_UP_MAP_TO_FW
+/**
+ * target_if_fwol_send_dscp_up_map_to_fw() - send dscp up map to FW
+ * @psoc: pointer to PSOC object
+ * @dscp_to_up_map: DSCP to UP map array
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_psoc *psoc,
+ uint32_t *dscp_to_up_map)
+{
+ QDF_STATUS status;
+ wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+ if (!wmi_handle) {
+ target_if_err("Invalid wmi_handle");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_send_dscp_tip_map_cmd(wmi_handle, dscp_to_up_map);
+ if (status)
+ target_if_err("Failed to send dscp_up_map_to_fw %d", status);
+
+ return status;
+}
+
+static void
+target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+ tx_ops->send_dscp_up_map_to_fw = target_if_fwol_send_dscp_up_map_to_fw;
+}
+#else
+static void
+target_if_fwol_register_dscp_up_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+}
+#endif
+
QDF_STATUS target_if_fwol_register_event_handler(struct wlan_objmgr_psoc *psoc,
void *arg)
{
@@ -221,6 +260,7 @@
QDF_STATUS target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
{
target_if_fwol_register_elna_tx_ops(tx_ops);
+ target_if_fwol_register_dscp_up_tx_ops(tx_ops);
tx_ops->reg_evt_handler = target_if_fwol_register_event_handler;
tx_ops->unreg_evt_handler = target_if_fwol_unregister_event_handler;
diff --git a/configs/default_defconfig b/configs/default_defconfig
index 0f2438f..026158d 100644
--- a/configs/default_defconfig
+++ b/configs/default_defconfig
@@ -615,6 +615,12 @@
CONFIG_PKTLOG_LEGACY := y
endif
+#Customize DSCP_to-UP map based on RFC8325
+ifeq ($(CONFIG_HELIUMPLUS), y)
+CONFIG_WLAN_CUSTOM_DSCP_UP_MAP := y
+CONFIG_WLAN_SEND_DSCP_UP_MAP_TO_FW := y
+endif
+
ifeq ($(CONFIG_ROME_IF), sdio)
CONFIG_PKTLOG_LEGACY := y
endif
diff --git a/core/hdd/inc/wlan_hdd_wmm.h b/core/hdd/inc/wlan_hdd_wmm.h
index a78733c..a519f1f 100644
--- a/core/hdd/inc/wlan_hdd_wmm.h
+++ b/core/hdd/inc/wlan_hdd_wmm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012,2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012,2016-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
@@ -205,6 +205,17 @@
int hdd_wmmps_helper(struct hdd_adapter *adapter, uint8_t *ptr);
/**
+ * hdd_send_dscp_up_map_to_fw() - send dscp to up map to FW
+ * @adapter : [in] pointer to Adapter context
+ *
+ * This function will send the WMM DSCP configuration of an
+ * adapter to FW.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+QDF_STATUS hdd_send_dscp_up_map_to_fw(struct hdd_adapter *adapter);
+
+/**
* hdd_wmm_init() - initialize the WMM DSCP configuation
* @adapter : [in] pointer to Adapter context
*
diff --git a/core/hdd/src/wlan_hdd_wmm.c b/core/hdd/src/wlan_hdd_wmm.c
index dd4cfdf..759fdbd 100644
--- a/core/hdd/src/wlan_hdd_wmm.c
+++ b/core/hdd/src/wlan_hdd_wmm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-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
@@ -47,6 +47,7 @@
#include <linux/semaphore.h>
#include <linux/ipv6.h>
#include "osif_sync.h"
+#include "os_if_fwol.h"
#include <wlan_hdd_tx_rx.h>
#include <wlan_hdd_wmm.h>
#include <wlan_hdd_ether.h>
@@ -55,8 +56,10 @@
#include <cds_sched.h>
#include "sme_api.h"
#include "wlan_mlme_ucfg_api.h"
+#include "cfg_ucfg_api.h"
#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
+#define DSCP(x) x
const uint8_t hdd_wmm_up_to_ac_map[] = {
SME_AC_BE,
@@ -1456,6 +1459,92 @@
osif_vdev_sync_op_stop(vdev_sync);
}
+QDF_STATUS hdd_send_dscp_up_map_to_fw(struct hdd_adapter *adapter)
+{
+ uint32_t *dscp_to_up_map = adapter->dscp_to_up_map;
+ struct wlan_objmgr_vdev *vdev = adapter->vdev;
+ int ret;
+
+ if (vdev) {
+ /* Send DSCP to TID map table to FW */
+ ret = os_if_fwol_send_dscp_up_map_to_fw(vdev, dscp_to_up_map);
+ if (ret && ret != -EOPNOTSUPP)
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_fill_dscp_to_up_map() - Fill up dscp_to_up_map table with default values
+ * @dscp_to_up_map: Array of DSCP-to-UP map
+ *
+ * This function will fill up the DSCP-to-UP map table with default values.
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static inline void hdd_fill_dscp_to_up_map(
+ enum sme_qos_wmmuptype *dscp_to_up_map)
+{
+ uint8_t dscp;
+
+ /*
+ * DSCP to User Priority Lookup Table
+ * By default use the 3 Precedence bits of DSCP as the User Priority
+ *
+ * In case of changing the default map values, need to take care of
+ * hdd_custom_dscp_up_map as well.
+ */
+ for (dscp = 0; dscp <= WLAN_MAX_DSCP; dscp++)
+ dscp_to_up_map[dscp] = dscp >> 3;
+
+ /* Special case for Expedited Forwarding (DSCP 46) in default mapping */
+ dscp_to_up_map[DSCP(46)] = SME_QOS_WMM_UP_VO;
+}
+
+#ifdef WLAN_CUSTOM_DSCP_UP_MAP
+/**
+ * hdd_custom_dscp_up_map() - Customize dscp_to_up_map based on RFC8325
+ * @dscp_to_up_map: Array of DSCP-to-UP map
+ *
+ * This function will customize the DSCP-to-UP map table based on RFC8325..
+ *
+ * Return: QDF_STATUS enumeration
+ */
+static inline QDF_STATUS hdd_custom_dscp_up_map(
+ enum sme_qos_wmmuptype *dscp_to_up_map)
+{
+ /*
+ * Customizing few of DSCP to UP mapping based on RFC8325,
+ * those are different from default hdd_fill_dscp_to_up_map values.
+ * So, below changes are always relative to hdd_fill_dscp_to_up_map.
+ */
+ dscp_to_up_map[DSCP(10)] = SME_QOS_WMM_UP_BE;
+ dscp_to_up_map[DSCP(12)] = SME_QOS_WMM_UP_BE;
+ dscp_to_up_map[DSCP(14)] = SME_QOS_WMM_UP_BE;
+ dscp_to_up_map[DSCP(16)] = SME_QOS_WMM_UP_BE;
+
+ dscp_to_up_map[DSCP(18)] = SME_QOS_WMM_UP_EE;
+ dscp_to_up_map[DSCP(20)] = SME_QOS_WMM_UP_EE;
+ dscp_to_up_map[DSCP(22)] = SME_QOS_WMM_UP_EE;
+
+ dscp_to_up_map[DSCP(24)] = SME_QOS_WMM_UP_CL;
+ dscp_to_up_map[DSCP(26)] = SME_QOS_WMM_UP_CL;
+ dscp_to_up_map[DSCP(28)] = SME_QOS_WMM_UP_CL;
+ dscp_to_up_map[DSCP(30)] = SME_QOS_WMM_UP_CL;
+
+ dscp_to_up_map[DSCP(44)] = SME_QOS_WMM_UP_VO;
+
+ return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS hdd_custom_dscp_up_map(
+ enum sme_qos_wmmuptype *dscp_to_up_map)
+{
+ return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* WLAN_CUSTOM_DSCP_UP_MAP */
+
/**
* hdd_wmm_init() - initialize the WMM DSCP configuation
* @adapter : [in] pointer to Adapter context
@@ -1469,20 +1558,24 @@
QDF_STATUS hdd_wmm_init(struct hdd_adapter *adapter)
{
enum sme_qos_wmmuptype *dscp_to_up_map = adapter->dscp_to_up_map;
- uint8_t dscp;
+ struct wlan_objmgr_psoc *psoc = adapter->hdd_ctx->psoc;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
hdd_enter();
- /* DSCP to User Priority Lookup Table
- * By default use the 3 Precedence bits of DSCP as the User Priority
- */
- for (dscp = 0; dscp <= WLAN_MAX_DSCP; dscp++)
- dscp_to_up_map[dscp] = dscp >> 3;
+ if (!psoc) {
+ hdd_err("Invalid psoc handle");
+ return QDF_STATUS_E_FAILURE;
+ }
- /* Special case for Expedited Forwarding (DSCP 46) */
- dscp_to_up_map[46] = SME_QOS_WMM_UP_VO;
+ hdd_fill_dscp_to_up_map(dscp_to_up_map);
- return QDF_STATUS_SUCCESS;
+ if (hdd_custom_dscp_up_map(dscp_to_up_map) == QDF_STATUS_SUCCESS) {
+ /* Send DSCP to TID map table to FW */
+ status = hdd_send_dscp_up_map_to_fw(adapter);
+ }
+
+ return status;
}
/**
diff --git a/os_if/fw_offload/inc/os_if_fwol.h b/os_if/fw_offload/inc/os_if_fwol.h
index ec8a08f..8ecbc0f 100644
--- a/os_if/fw_offload/inc/os_if_fwol.h
+++ b/os_if/fw_offload/inc/os_if_fwol.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-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
@@ -64,4 +64,22 @@
}
#endif /* WLAN_FEATURE_ELNA */
+#ifdef WLAN_SEND_DSCP_UP_MAP_TO_FW
+/**
+ * os_if_fwol_send_dscp_up_map_to_fw() - Send DSCP to UP map to FW
+ * @vdev: Pointer to vdev
+ * @dscp_to_up_map: Array of DSCP to UP map values
+ *
+ * Return: 0 on success; error number otherwise
+ */
+int os_if_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_vdev *vdev,
+ uint32_t *dscp_to_up_map);
+#else
+static inline int os_if_fwol_send_dscp_up_map_to_fw(
+ struct wlan_objmgr_vdev *vdev, uint32_t *dscp_to_up_map)
+{
+ return -EOPNOTSUPP;
+}
+#endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
+
#endif /* __OS_IF_FWOL_H__ */
diff --git a/os_if/fw_offload/src/os_if_fwol.c b/os_if/fw_offload/src/os_if_fwol.c
index bcb4c7d..90ee997 100644
--- a/os_if/fw_offload/src/os_if_fwol.c
+++ b/os_if/fw_offload/src/os_if_fwol.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-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
@@ -131,3 +131,17 @@
return ret;
}
#endif /* #ifdef WLAN_FEATURE_ELNA */
+
+#ifdef WLAN_SEND_DSCP_UP_MAP_TO_FW
+int os_if_fwol_send_dscp_up_map_to_fw(struct wlan_objmgr_vdev *vdev,
+ uint32_t *dscp_to_up_map)
+{
+ QDF_STATUS status;
+
+ status = ucfg_fwol_send_dscp_up_map_to_fw(vdev, dscp_to_up_map);
+ if (!QDF_IS_STATUS_SUCCESS(status))
+ osif_err("Failed to send dscp_up_map to FW, %d", status);
+
+ return qdf_status_to_os_return(status);
+}
+#endif