diff --git a/dp/inc/cdp_txrx_ctrl.h b/dp/inc/cdp_txrx_ctrl.h index ec287ea04b..8d85653dea 100644 --- a/dp/inc/cdp_txrx_ctrl.h +++ b/dp/inc/cdp_txrx_ctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -762,4 +762,35 @@ cdp_get_pldev(ol_txrx_soc_handle soc, return soc->ops->ctrl_ops->txrx_get_pldev(pdev); } +#ifdef ATH_SUPPORT_NAC_RSSI +/** + * cdp_vdev_config_for_nac_rssi(): To invoke dp callback for nac rssi config + * @soc: soc pointer + * @vdev: vdev pointer + * @nac_cmd: specfies nac_rss config action add, del, list + * @bssid: Neighbour bssid + * @client_macaddr: Non-Associated client MAC + * @chan_num: channel number to scan + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS cdp_vdev_config_for_nac_rssi(ol_txrx_soc_handle soc, + struct cdp_vdev *vdev, enum cdp_nac_param_cmd nac_cmd, + char *bssid, char *client_macaddr, uint8_t chan_num) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi(vdev, + nac_cmd, bssid, client_macaddr, chan_num); +} +#endif #endif diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index deb8c60b29..9b8ea41a38 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -45,6 +45,15 @@ #define CDP_PEER_DELETE_NO_SPECIAL 0 #define CDP_PEER_DO_NOT_START_UNMAP_TIMER 1 +/* same as ieee80211_nac_param */ +enum cdp_nac_param_cmd { + /* IEEE80211_NAC_PARAM_ADD */ + CDP_NAC_PARAM_ADD = 1, + /* IEEE80211_NAC_PARAM_DEL */ + CDP_NAC_PARAM_DEL, + /* IEEE80211_NAC_PARAM_LIST */ + CDP_NAC_PARAM_LIST, +}; /****************************************************************************** * * Control Interface (A Interface) @@ -473,6 +482,12 @@ struct cdp_ctrl_ops { int (*txrx_wdi_event_handler)(struct cdp_pdev *pdev, uint32_t event, void *evt_data); void * (*txrx_get_pldev)(struct cdp_pdev *pdev); + +#ifdef ATH_SUPPORT_NAC_RSSI + QDF_STATUS (*txrx_vdev_config_for_nac_rssi)(struct cdp_vdev *vdev, + enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr, + uint8_t chan_num); +#endif }; struct cdp_me_ops { @@ -699,7 +714,13 @@ struct ol_if_ops { void (*record_act_change)(struct wlan_objmgr_pdev *pdev, u_int8_t *dstmac, bool active); - +#ifdef ATH_SUPPORT_NAC_RSSI + int (*config_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev, + u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid, + char *client_macaddr, uint8_t chan_num); + int (*config_bssid_in_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev, + u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid); +#endif /* TODO: Add any other control path calls required to OL_IF/WMA layer */ }; diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 70df6204d9..14b1918622 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -6303,6 +6303,43 @@ static void dp_peer_teardown_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl) } #endif +#ifdef ATH_SUPPORT_NAC_RSSI +static QDF_STATUS dp_config_for_nac_rssi(struct cdp_vdev *vdev_handle, + enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr, + uint8_t chan_num) +{ + + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; + struct dp_soc *soc = (struct dp_soc *) vdev->pdev->soc; + + pdev->nac_rssi_filtering = 1; + /* Store address of NAC (neighbour peer) which will be checked + * against TA of received packets. + */ + + if (cmd == CDP_NAC_PARAM_ADD) { + qdf_mem_copy(vdev->cdp_nac_rssi.client_mac, + client_macaddr, DP_MAC_ADDR_LEN); + vdev->cdp_nac_rssi_enabled = 1; + } else if (cmd == CDP_NAC_PARAM_DEL) { + if (!qdf_mem_cmp(vdev->cdp_nac_rssi.client_mac, + client_macaddr, DP_MAC_ADDR_LEN)) { + /* delete this peer from the list */ + qdf_mem_zero(vdev->cdp_nac_rssi.client_mac, + DP_MAC_ADDR_LEN); + } + vdev->cdp_nac_rssi_enabled = 0; + } + + if (soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi) + soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi + (vdev->pdev->osif_pdev, vdev->vdev_id, cmd, bssid); + + return QDF_STATUS_SUCCESS; +} +#endif + static struct cdp_cmn_ops dp_ops_cmn = { .txrx_soc_attach_target = dp_soc_attach_target_wifi3, .txrx_vdev_attach = dp_vdev_attach_wifi3, @@ -6391,6 +6428,9 @@ static struct cdp_ctrl_ops dp_ops_ctrl = { .txrx_get_pldev = dp_get_pldev, #endif .txrx_set_pdev_param = dp_set_pdev_param, +#ifdef ATH_SUPPORT_NAC_RSSI + .txrx_vdev_config_for_nac_rssi = dp_config_for_nac_rssi, +#endif }; static struct cdp_me_ops dp_ops_me = { @@ -7101,3 +7141,4 @@ static void dp_pktlogmod_exit(struct dp_pdev *handle) #else static void dp_pktlogmod_exit(struct dp_pdev *handle) { } #endif + diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 0d47c6ab18..628890a503 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -636,6 +636,45 @@ struct dp_vdev *dp_rx_nac_filter(struct dp_pdev *pdev, return NULL; } +/** + * dp_rx_process_nac_rssi_frames(): Store RSSI for configured NAC + * @pdev: DP pdev handle + * @rx_tlv_hdr: tlv hdr buf + * + * return: None + */ +#ifdef ATH_SUPPORT_NAC_RSSI +static void dp_rx_process_nac_rssi_frames(struct dp_pdev *pdev, uint8_t *rx_tlv_hdr) +{ + struct dp_vdev *vdev = NULL; + struct dp_soc *soc = pdev->soc; + uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr); + struct ieee80211_frame *wh = (struct ieee80211_frame *)rx_pkt_hdr; + + if (pdev->nac_rssi_filtering) { + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + if (vdev->cdp_nac_rssi_enabled && + (qdf_mem_cmp(vdev->cdp_nac_rssi.client_mac, + wh->i_addr1, DP_MAC_ADDR_LEN) == 0)) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_DEBUG, "RSSI updated"); + vdev->cdp_nac_rssi.vdev_id = vdev->vdev_id; + vdev->cdp_nac_rssi.client_rssi = + hal_rx_msdu_start_get_rssi(rx_tlv_hdr); + dp_wdi_event_handler(WDI_EVENT_NAC_RSSI, soc, + (void *)&vdev->cdp_nac_rssi, + HTT_INVALID_PEER, WDI_NO_VAL, + pdev->pdev_id); + } + } + } +} +#else +static void dp_rx_process_nac_rssi_frames(struct dp_pdev *pdev, uint8_t *rx_tlv_hdr) +{ +} +#endif + /** * dp_rx_process_invalid_peer(): Function to pass invalid peer list to umac * @soc: DP SOC handle @@ -650,10 +689,10 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu) struct dp_pdev *pdev = NULL; struct ieee80211_frame *wh; uint8_t i; - uint8_t *rx_pkt_hdr; qdf_nbuf_t curr_nbuf, next_nbuf; + uint8_t *rx_tlv_hdr = qdf_nbuf_data(mpdu); + uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr); - rx_pkt_hdr = hal_rx_pkt_hdr_get(qdf_nbuf_data(mpdu)); wh = (struct ieee80211_frame *)rx_pkt_hdr; if (!DP_FRAME_IS_DATA(wh)) { @@ -687,7 +726,12 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu) return 0; } } + + + dp_rx_process_nac_rssi_frames(pdev, rx_tlv_hdr); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw, DP_MAC_ADDR_LEN) == 0) { goto out; diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index b3d41b6707..7144dbdf54 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1129,6 +1129,10 @@ struct dp_pdev { bool pktlog_ppdu_stats; void *dp_txrx_handle; /* Advanced data path handle */ + +#ifdef ATH_SUPPORT_NAC_RSSI + bool nac_rssi_filtering; +#endif }; struct dp_peer; @@ -1268,6 +1272,17 @@ struct dp_vdev { enum cdp_sec_type sec_type; +#ifdef ATH_SUPPORT_NAC_RSSI + bool cdp_nac_rssi_enabled; + struct { + uint8_t bssid_mac[6]; + uint8_t client_mac[6]; + uint8_t chan_num; + uint8_t client_rssi_valid; + uint8_t client_rssi; + uint8_t vdev_id; + } cdp_nac_rssi; +#endif };