diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index 804eeaef65..c489f143c1 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -2666,4 +2666,43 @@ cdp_rx_get_pending(ol_txrx_soc_handle soc) return soc->ol_ops->dp_rx_get_pending(soc); } + +#ifdef QCA_SUPPORT_WDS_EXTENDED +static inline uint16_t +cdp_wds_ext_get_peer_id(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *mac) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance", __func__); + QDF_BUG(0); + return 0; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->get_wds_ext_peer_id) + return 0; + + return soc->ops->cmn_drv_ops->get_wds_ext_peer_id + (soc, vdev_id, mac); +} + +static inline QDF_STATUS +cdp_wds_ext_set_peer_rx(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *mac, ol_txrx_rx_fp rx) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAULT; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->set_wds_ext_peer_rx) + return QDF_STATUS_E_FAULT; + + return soc->ops->cmn_drv_ops->set_wds_ext_peer_rx + (soc, vdev_id, mac, rx); +} +#endif /* QCA_SUPPORT_WDS_EXTENDED */ #endif /* _CDP_TXRX_CMN_H_ */ diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index ffb9eb41dd..49630a60cd 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -625,6 +625,11 @@ struct ol_txrx_nbuf_classify { struct ol_osif_vdev_t; typedef struct ol_osif_vdev_t *ol_osif_vdev_handle; +#ifdef QCA_SUPPORT_WDS_EXTENDED +struct ol_osif_peer_t; +typedef struct ol_osif_peer_t *ol_osif_peer_handle; +#endif + /** * wlan_op_mode - Virtual device operation mode * @wlan_op_mode_unknown: Unknown mode @@ -1162,6 +1167,7 @@ typedef union cdp_config_param_t { uint32_t cdp_vdev_param_safe_mode; uint32_t cdp_vdev_param_drop_unenc; uint8_t cdp_vdev_param_hlos_tid_override; + bool cdp_vdev_param_wds_ext; /* pdev params */ bool cdp_pdev_param_cptr_latcy; @@ -1272,6 +1278,7 @@ enum cdp_pdev_bpr_param { * @CDP_DROP_UNENC: set drop unencrypted flag * @CDP_ENABLE_IGMP_MCAST_EN: enable/disable igmp multicast enhancement * @CDP_ENABLE_HLOS_TID_OVERRIDE: set hlos tid override flag + * @CDP_CFG_WDS_EXT: enable/disable wds ext feature */ enum cdp_vdev_param_type { CDP_ENABLE_NAWDS, @@ -1299,6 +1306,9 @@ enum cdp_vdev_param_type { CDP_ENABLE_CSUM, CDP_ENABLE_IGMP_MCAST_EN, CDP_ENABLE_HLOS_TID_OVERRIDE, +#ifdef QCA_SUPPORT_WDS_EXTENDED + CDP_CFG_WDS_EXT, +#endif /* QCA_SUPPORT_WDS_EXTENDED */ }; /* diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 348d42a229..34e53b71b8 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -556,6 +556,15 @@ struct cdp_cmn_ops { (ol_txrx_soc_handle soc, uint8_t vdev_id, u_int8_t newmac[][QDF_MAC_ADDR_SIZE], uint16_t mac_cnt, bool limit); +#ifdef QCA_SUPPORT_WDS_EXTENDED + uint16_t (*get_wds_ext_peer_id)(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *mac); + QDF_STATUS (*set_wds_ext_peer_rx)(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *mac, + ol_txrx_rx_fp rx); +#endif /* QCA_SUPPORT_WDS_EXTENDED */ }; struct cdp_ctrl_ops { @@ -1130,6 +1139,11 @@ struct ol_if_ops { uint8_t vdev_id); int (*dp_rx_get_pending)(ol_txrx_soc_handle soc); /* TODO: Add any other control path calls required to OL_IF/WMA layer */ +#ifdef QCA_SUPPORT_WDS_EXTENDED + void (*rx_wds_ext_peer_learn)(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + uint16_t peer_id, uint8_t vdev_id, + uint8_t *peer_macaddr); +#endif /* QCA_SUPPORT_WDS_EXTENDED */ }; #ifdef DP_PEER_EXTENDED_API diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 434dad7b4f..4318a5dba6 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -410,6 +410,17 @@ static inline void dp_set_peer_isolation(struct dp_peer *peer, bool val) } #endif /* QCA_SUPPORT_PEER_ISOLATION */ +#ifdef QCA_SUPPORT_WDS_EXTENDED +static inline void dp_wds_ext_peer_init(struct dp_peer *peer) +{ + peer->wds_ext.init = 0; +} +#else +static inline void dp_wds_ext_peer_init(struct dp_peer *peer) +{ +} +#endif /* QCA_SUPPORT_WDS_EXTENDED */ + /** * The lmac ID for a particular channel band is fixed. * 2.4GHz band uses lmac_id = 1 @@ -2424,4 +2435,38 @@ static inline QDF_STATUS dp_soc_swlm_detach(struct dp_soc *soc) } #endif /* !WLAN_DP_FEATURE_SW_LATENCY_MGR */ +#ifdef QCA_SUPPORT_WDS_EXTENDED +/** + * dp_wds_ext_get_peer_id(): function to get peer id by mac + * This API is called from control path when wds extended + * device is created, hence it also updates wds extended + * peer state to up, which will be referred in rx processing. + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @mac: Peer mac address + * + * return: valid peer id on success + * HTT_INVALID_PEER on failure + */ +uint16_t dp_wds_ext_get_peer_id(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *mac); + +/** + * dp_wds_ext_set_peer_state(): function to set peer state + * @soc: Datapath soc handle + * @vdev_id: vdev id + * @mac: Peer mac address + * @rx: rx function pointer + * + * return: QDF_STATUS_SUCCESS on success + * QDF_STATUS_E_INVAL if peer is not found + * QDF_STATUS_E_ALREADY if rx is already set/unset + */ +QDF_STATUS dp_wds_ext_set_peer_rx(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *mac, + ol_txrx_rx_fp rx); +#endif /* QCA_SUPPORT_WDS_EXTENDED */ + #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 193d61ad1b..031a0dfae4 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -5729,6 +5729,8 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, dp_set_peer_isolation(peer, false); + dp_wds_ext_peer_init(peer); + dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT); dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP); @@ -5775,6 +5777,7 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, } dp_peer_add_ast(soc, peer, peer_mac_addr, ast_type, 0); qdf_spinlock_create(&peer->peer_info_lock); + dp_wds_ext_peer_init(peer); dp_peer_rx_bufq_resources_init(peer); @@ -8773,6 +8776,11 @@ dp_set_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, dp_vdev_set_hlos_tid_override(vdev, val.cdp_vdev_param_hlos_tid_override); break; +#ifdef QCA_SUPPORT_WDS_EXTENDED + case CDP_CFG_WDS_EXT: + vdev->wds_ext_enabled = val.cdp_vdev_param_wds_ext; + break; +#endif default: break; } @@ -10721,6 +10729,10 @@ static struct cdp_cmn_ops dp_ops_cmn = { #endif .get_peer_mac_list = dp_get_peer_mac_list, .tx_send_exc = dp_tx_send_exception, +#ifdef QCA_SUPPORT_WDS_EXTENDED + .get_wds_ext_peer_id = dp_wds_ext_get_peer_id, + .set_wds_ext_peer_rx = dp_wds_ext_set_peer_rx, +#endif /* QCA_SUPPORT_WDS_EXTENDED */ }; static struct cdp_ctrl_ops dp_ops_ctrl = { @@ -12506,6 +12518,65 @@ uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id, return new_mac_cnt; } +#ifdef QCA_SUPPORT_WDS_EXTENDED +uint16_t dp_wds_ext_get_peer_id(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *mac) +{ + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + mac, 0, vdev_id, + DP_MOD_ID_CDP); + uint16_t peer_id = HTT_INVALID_PEER; + + if (!peer) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + return peer_id; + } + + peer_id = peer->peer_id; + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + return peer_id; +} + +QDF_STATUS dp_wds_ext_set_peer_rx(ol_txrx_soc_handle soc, + uint8_t vdev_id, + uint8_t *mac, + ol_txrx_rx_fp rx) +{ + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + mac, 0, vdev_id, + DP_MOD_ID_CDP); + QDF_STATUS status = QDF_STATUS_E_INVAL; + + if (!peer) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "%s: Peer is NULL!\n", __func__); + return status; + } + + if (rx) { + if (peer->osif_rx) { + status = QDF_STATUS_E_ALREADY; + } else { + peer->osif_rx = rx; + status = QDF_STATUS_SUCCESS; + } + } else { + if (peer->osif_rx) { + peer->osif_rx = NULL; + status = QDF_STATUS_SUCCESS; + } else { + status = QDF_STATUS_E_ALREADY; + } + } + + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + + return status; +} +#endif /* QCA_SUPPORT_WDS_EXTENDED */ + /** * dp_pdev_srng_deinit() - de-initialize all pdev srng ring including * monitor rings @@ -13279,7 +13350,6 @@ static inline QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc, nss_cfg = wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx); wlan_cfg_set_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx, (nss_cfg & (1 << pdev_id))); - pdev->target_pdev_id = dp_calculate_target_pdev_id_from_host_pdev_id(soc, pdev_id); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 2090fc378c..78ac9e43ab 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2515,6 +2515,9 @@ struct dp_vdev { qdf_atomic_t ref_cnt; qdf_atomic_t mod_refs[DP_MOD_ID_MAX]; uint8_t num_latency_critical_conn; +#ifdef QCA_SUPPORT_WDS_EXTENDED + bool wds_ext_enabled; +#endif /* QCA_SUPPORT_WDS_EXTENDED */ }; @@ -2617,6 +2620,24 @@ struct dp_peer_mscs_parameter { }; #endif +#ifdef QCA_SUPPORT_WDS_EXTENDED +#define WDS_EXT_PEER_INIT_BIT 0 + +/** + * struct dp_wds_ext_peer - wds ext peer structure + * This is used when wds extended feature is enabled + * both compile time and run time. It is created + * when 1st 4 address frame is received from + * wds backhaul. + * @osif_vdev: Handle to the OS shim SW's virtual device + * @init: wds ext netdev state + */ +struct dp_wds_ext_peer { + ol_osif_vdev_handle osif_vdev; + unsigned long init; +}; +#endif /* QCA_SUPPORT_WDS_EXTENDED */ + /* Peer structure for data path state */ struct dp_peer { /* VDEV to which this peer is associated */ @@ -2738,6 +2759,10 @@ struct dp_peer { struct dp_peer_mscs_parameter mscs_ipv4_parameter, mscs_ipv6_parameter; bool mscs_active; #endif +#ifdef QCA_SUPPORT_WDS_EXTENDED + struct dp_wds_ext_peer wds_ext; + ol_txrx_rx_fp osif_rx; +#endif }; /*