Merge "qcacmn: Add support in wifi pos to send wru/ftmrr frames"
diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h
index 4062353..4d8a42d 100644
--- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h
+++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h
@@ -982,6 +982,8 @@
struct cur_regdmn_info *cur_regdmn);
QDF_STATUS (*reg_enable_dfs_channels)(struct wlan_objmgr_pdev *pdev,
bool dfs_enable);
+ QDF_STATUS (*reg_modify_pdev_chan_range)(struct
+ wlan_objmgr_pdev *pdev);
};
#ifdef CONVERGED_P2P_ENABLE
@@ -1253,8 +1255,10 @@
* @dfs_dfs_cac_complete_ind: Process cac complete indication.
* @dfs_agile_precac_start: Initiate Agile PreCAC run.
* @dfs_set_agile_precac_state: Set agile precac state.
+ * @dfs_reset_adfs_config: Reset agile dfs variables.
* @dfs_dfs_ocac_complete_ind: Process offchan cac complete indication.
* @dfs_stop: Clear dfs timers.
+ * @dfs_reinit_timers: Reinitialize DFS timers.
* @dfs_enable_stadfs: Enable/Disable STADFS capability.
* @dfs_is_stadfs_enabled: Get STADFS capability value.
* @dfs_process_phyerr_filter_offload:Process radar event.
@@ -1308,6 +1312,7 @@
QDF_STATUS (*dfs_agile_precac_start)(struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*dfs_set_agile_precac_state)(struct wlan_objmgr_pdev *pdev,
int agile_precac_state);
+ QDF_STATUS (*dfs_reset_adfs_config)(struct wlan_objmgr_psoc *psoc);
QDF_STATUS
(*dfs_dfs_ocac_complete_ind)(struct wlan_objmgr_pdev *pdev,
struct vdev_adfs_complete_status *ocac_st);
@@ -1348,6 +1353,7 @@
uint32_t vdev_id);
#endif
QDF_STATUS (*dfs_stop)(struct wlan_objmgr_pdev *pdev);
+ QDF_STATUS (*dfs_reinit_timers)(struct wlan_objmgr_pdev *pdev);
void (*dfs_enable_stadfs)(struct wlan_objmgr_pdev *pdev, bool val);
bool (*dfs_is_stadfs_enabled)(struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*dfs_process_phyerr_filter_offload)(
diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c
index c4d8433..f8a7d70 100644
--- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c
+++ b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c
@@ -323,6 +323,9 @@
rx_ops->reg_rx_ops.reg_enable_dfs_channels =
ucfg_reg_enable_dfs_channels;
+
+ rx_ops->reg_rx_ops.reg_modify_pdev_chan_range =
+ wlan_reg_modify_pdev_chan_range;
}
#ifdef CONVERGED_P2P_ENABLE
@@ -394,6 +397,7 @@
tgt_dfs_set_agile_precac_state;
dfs_rx_ops->dfs_start_precac_timer = utils_dfs_start_precac_timer;
dfs_rx_ops->dfs_cancel_precac_timer = utils_dfs_cancel_precac_timer;
+ dfs_rx_ops->dfs_reset_adfs_config = ucfg_dfs_reset_agile_config;
dfs_rx_ops->dfs_override_precac_timeout =
ucfg_dfs_override_precac_timeout;
dfs_rx_ops->dfs_set_precac_enable = ucfg_dfs_set_precac_enable;
@@ -405,6 +409,7 @@
dfs_rx_ops->dfs_dfs_cac_complete_ind = tgt_dfs_cac_complete;
dfs_rx_ops->dfs_dfs_ocac_complete_ind = tgt_dfs_ocac_complete;
dfs_rx_ops->dfs_stop = tgt_dfs_stop;
+ dfs_rx_ops->dfs_reinit_timers = ucfg_dfs_reinit_timers;
dfs_rx_ops->dfs_enable_stadfs = tgt_dfs_enable_stadfs;
dfs_rx_ops->dfs_is_stadfs_enabled = tgt_dfs_is_stadfs_enabled;
dfs_rx_ops->dfs_process_phyerr_filter_offload =
diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c
index c10a431..8cf19a0 100644
--- a/umac/regulatory/core/src/reg_services_common.c
+++ b/umac/regulatory/core/src/reg_services_common.c
@@ -2023,3 +2023,87 @@
return reg_en302_502_regdmn(cur_reg_dmn.regdmn_pair_id);
}
+
+QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev)
+{
+ struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+ struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
+ struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap_ptr;
+ uint32_t cnt;
+ uint32_t pdev_id;
+ enum direction dir;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+ pdev_priv_obj = reg_get_pdev_obj(pdev);
+ if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
+ reg_err("pdev reg component is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_pdev_get_psoc(pdev);
+ if (!psoc) {
+ reg_err("psoc is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc_priv_obj = reg_get_psoc_obj(psoc);
+ if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
+ reg_err("psoc reg component is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ reg_cap_ptr = psoc_priv_obj->reg_cap;
+
+ for (cnt = 0; cnt < PSOC_MAX_PHY_REG_CAP; cnt++) {
+ if (!reg_cap_ptr) {
+ qdf_mem_free(pdev_priv_obj);
+ reg_err("reg cap ptr is NULL");
+ return QDF_STATUS_E_FAULT;
+ }
+
+ if (reg_cap_ptr->phy_id == pdev_id)
+ break;
+ reg_cap_ptr++;
+ }
+
+ if (cnt == PSOC_MAX_PHY_REG_CAP) {
+ qdf_mem_free(pdev_priv_obj);
+ reg_err("extended capabilities not found for pdev");
+ return QDF_STATUS_E_FAULT;
+ }
+
+ if (psoc_priv_obj->offload_enabled) {
+ dir = NORTHBOUND;
+ } else {
+ dir = SOUTHBOUND;
+ }
+
+ pdev_priv_obj->range_2g_low = reg_cap_ptr->low_2ghz_chan;
+ pdev_priv_obj->range_2g_high = reg_cap_ptr->high_2ghz_chan;
+ pdev_priv_obj->range_5g_low = reg_cap_ptr->low_5ghz_chan;
+ pdev_priv_obj->range_5g_high = reg_cap_ptr->high_5ghz_chan;
+ pdev_priv_obj->wireless_modes = reg_cap_ptr->wireless_modes;
+
+ reg_compute_pdev_current_chan_list(pdev_priv_obj);
+
+ reg_tx_ops = reg_get_psoc_tx_ops(psoc);
+
+ /* Fill the ic channel list with the updated current channel
+ * chan list.
+ */
+ if (reg_tx_ops->fill_umac_legacy_chanlist) {
+ reg_tx_ops->fill_umac_legacy_chanlist(pdev,
+ pdev_priv_obj->cur_chan_list);
+
+ } else {
+ if (dir == NORTHBOUND)
+ status = reg_send_scheduler_msg_nb(psoc, pdev);
+ else
+ status = reg_send_scheduler_msg_sb(psoc, pdev);
+ }
+
+ return status;
+}
diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h
index d2ed228..52df9be 100644
--- a/umac/regulatory/core/src/reg_services_common.h
+++ b/umac/regulatory/core/src/reg_services_common.h
@@ -514,4 +514,13 @@
* Return: True if en302_502 is applicable, else false.
*/
bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * reg_modify_pdev_chan_range() - Compute current channel list
+ * in accordance with the modified reg caps.
+ * @pdev: The physical dev for which channel list must be built.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev);
#endif
diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h
index f7da9e3..b3a7d32 100644
--- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h
+++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h
@@ -703,4 +703,13 @@
* False: otherwise.
*/
bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the
+ * modified channel range in the regcap.
+ * @pdev: pointer to wlan_objmgr_pdev.
+ *
+ * Return : QDF_STATUS
+ */
+QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev);
#endif
diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c
index 67e5d74..5b91725 100644
--- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c
+++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c
@@ -713,3 +713,14 @@
{
return reg_is_regdmn_en302502_applicable(pdev);
}
+
+/**
+ * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the
+ * modified regcap.
+ * @pdev: pointer to struct wlan_objmgr_pdev
+ *
+ */
+QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev)
+{
+ return reg_modify_pdev_chan_range(pdev);
+}
diff --git a/umac/wifi_pos/inc/wifi_pos_api.h b/umac/wifi_pos/inc/wifi_pos_api.h
index 9841b15..72665e1 100644
--- a/umac/wifi_pos/inc/wifi_pos_api.h
+++ b/umac/wifi_pos/inc/wifi_pos_api.h
@@ -412,4 +412,33 @@
struct wlan_objmgr_psoc *psoc,
void (*handler)(uint8_t, uint32_t, uint32_t *));
+/**
+ * wifi_pos_register_send_action: API to register callback to send
+ * action frames
+ * @psoc: pointer to psoc object
+ * @handler: callback to be registered
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success, error codes in
+ * case of failure
+ */
+QDF_STATUS wifi_pos_register_send_action(
+ struct wlan_objmgr_psoc *psoc,
+ void (*handler)(struct wlan_objmgr_psoc *psoc,
+ uint32_t sub_type,
+ uint8_t *buf,
+ uint32_t buf_len));
+
+/**
+ * wifi_pos_send_report_resp: Send report to osif
+ * @psoc: pointer to psoc object
+ * @req_id: Request id
+ * @dest_mac: destination mac address
+ * @err_code: Error code to be sent
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success, error codes in
+ * case of failure
+ */
+QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc,
+ int req_id, uint8_t *dest_mac,
+ int err_code);
#endif
diff --git a/umac/wifi_pos/src/wifi_pos_api.c b/umac/wifi_pos/src/wifi_pos_api.c
index c421fa3..cbcf95c 100644
--- a/umac/wifi_pos/src/wifi_pos_api.c
+++ b/umac/wifi_pos/src/wifi_pos_api.c
@@ -350,3 +350,31 @@
return QDF_STATUS_SUCCESS;
}
+QDF_STATUS wifi_pos_register_send_action(
+ struct wlan_objmgr_psoc *psoc,
+ void (*handler)(struct wlan_objmgr_psoc *psoc,
+ uint32_t sub_type,
+ uint8_t *buf,
+ uint32_t buf_len))
+{
+ struct wifi_pos_psoc_priv_obj *wifi_pos_psoc;
+
+ if (!psoc) {
+ wifi_pos_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!handler) {
+ wifi_pos_err("Null callback");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+ wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc);
+ if (!wifi_pos_psoc) {
+ wifi_pos_err("wifi_pos priv obj is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ wifi_pos_psoc->wifi_pos_send_action = handler;
+
+ return QDF_STATUS_SUCCESS;
+}
diff --git a/umac/wifi_pos/src/wifi_pos_main.c b/umac/wifi_pos/src/wifi_pos_main.c
index de59510..b298cbf 100644
--- a/umac/wifi_pos/src/wifi_pos_main.c
+++ b/umac/wifi_pos/src/wifi_pos_main.c
@@ -99,6 +99,13 @@
struct oem_data_req data_req;
struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops;
struct wlan_objmgr_pdev *pdev;
+ struct wifi_pos_psoc_priv_obj *wifi_pos_obj =
+ wifi_pos_get_psoc_priv_obj(psoc);
+
+ if (!wifi_pos_obj) {
+ wifi_pos_err("wifi_pos priv obj is null");
+ return QDF_STATUS_E_INVAL;
+ }
wifi_pos_debug("Received data req pid(%d), len(%d)",
req->pid, req->buf_len);
@@ -151,10 +158,18 @@
/* TBD */
break;
case TARGET_OEM_CONFIGURE_FTMRR:
- /* TBD */
+ wifi_pos_debug("FTMRR request");
+ if (wifi_pos_obj->wifi_pos_send_action)
+ wifi_pos_obj->wifi_pos_send_action(psoc, sub_type,
+ req->buf,
+ req->buf_len);
break;
case TARGET_OEM_CONFIGURE_WRU:
- /* TBD */
+ wifi_pos_debug("WRU request");
+ if (wifi_pos_obj->wifi_pos_send_action)
+ wifi_pos_obj->wifi_pos_send_action(psoc, sub_type,
+ req->buf,
+ req->buf_len);
break;
default:
wifi_pos_debug("invalid sub type or not passed");
@@ -234,6 +249,40 @@
return QDF_STATUS_SUCCESS;
}
+QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc,
+ int req_id, uint8_t *dest_mac,
+ int err_code)
+{
+ struct wifi_pos_err_msg_report err_report = {0};
+ struct wifi_pos_psoc_priv_obj *wifi_pos_obj =
+ wifi_pos_get_psoc_priv_obj(psoc);
+
+ if (!wifi_pos_obj) {
+ wifi_pos_err("wifi_pos priv obj is null");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ err_report.msg_tag_len = OEM_MSG_RSP_HEAD_TAG_ID << 16;
+ err_report.msg_tag_len |= (sizeof(err_report) -
+ sizeof(err_report.err_rpt)) & 0x0000FFFF;
+ err_report.msg_subtype = TARGET_OEM_ERROR_REPORT_RSP;
+ err_report.req_id = req_id & 0xFFFF;
+ err_report.req_id |= ((err_code & 0xFF) << 16);
+ err_report.req_id |= (0x1 << 24);
+ err_report.time_left = 0xFFFFFFFF;
+ err_report.err_rpt.tag_len = OEM_MEAS_RSP_HEAD_TAG_ID << 16;
+ err_report.err_rpt.tag_len |=
+ (sizeof(struct wifi_pos_err_rpt)) & 0x0000FFFF;
+ memcpy(&err_report.err_rpt.dest_mac, dest_mac, QDF_MAC_ADDR_SIZE);
+
+ wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid,
+ ANI_MSG_OEM_DATA_RSP,
+ sizeof(err_report),
+ (uint8_t *)&err_report);
+
+ return QDF_STATUS_SUCCESS;
+}
+
static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
uint16_t chan,
diff --git a/umac/wifi_pos/src/wifi_pos_utils_i.h b/umac/wifi_pos/src/wifi_pos_utils_i.h
index 4c23460..c94269b 100644
--- a/umac/wifi_pos/src/wifi_pos_utils_i.h
+++ b/umac/wifi_pos/src/wifi_pos_utils_i.h
@@ -189,6 +189,42 @@
};
/**
+ * struct wifi_pos_err_rpt - Error report response for userspace.
+ * @tag_len: tlv header of the message.
+ * @info: Report info. Reserved for error report.
+ * @dest_mac: Mac address of the sta in the request.
+ * @reserved: Reserved in error report.
+ */
+struct qdf_packed wifi_pos_err_rpt {
+ uint32_t tag_len;
+ uint32_t info;
+ uint8_t dest_mac[QDF_MAC_ADDR_SIZE + 2];
+ uint32_t reserved;
+};
+
+#define OEM_MSG_RSP_HEAD_TAG_ID 33
+#define OEM_MEAS_RSP_HEAD_TAG_ID 41
+/**
+ * struct wifi_pos_err_msg_report - Error report message
+ * @msg_tag_len: Message tlv header
+ * @msg_subtype: Message subtype
+ * @req_id: id corresponding to the request.
+ * @fragment_info: Valid only for fragments.
+ * @pdev_id: pdev_id of radion.
+ * @time_left: time left in the measurment req.
+ * @err_rpt: Error report data.
+ */
+struct qdf_packed wifi_pos_err_msg_report {
+ uint32_t msg_tag_len;
+ uint32_t msg_subtype;
+ uint32_t req_id;
+ uint32_t fragment_info;
+ uint32_t pdev_id;
+ uint32_t time_left;
+ struct wifi_pos_err_rpt err_rpt;
+};
+
+/**
* struct wifi_pos_dma_rings_cap - capabilities requested by firmware.
* @pdev_id: pdev_id or mac_id of ring
* @min_num_ptr: minimum depth of ring required
@@ -306,6 +342,9 @@
struct wifi_pos_req_msg *req);
void (*wifi_pos_send_rsp)(uint32_t, uint32_t, uint32_t, uint8_t *);
void (*wifi_pos_get_phy_mode)(uint8_t, uint32_t, uint32_t *);
+ void (*wifi_pos_send_action)(struct wlan_objmgr_psoc *psoc,
+ uint32_t oem_subtype, uint8_t *buf,
+ uint32_t len);
};
/**