diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 9f76d1dc2d..a4d5813e34 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -485,6 +485,74 @@ struct cdp_rx_mic_err_info { uint16_t vdev_id; }; +#ifdef WLAN_SUPPORT_SCS +/* SCS Procedure data structures + */ +#define IEEE80211_SCS_MAX_SIZE 10 +#define IEEE80211_IPV4_LEN 4 +#define IEEE80211_IPV6_LEN 16 + +struct cdp_tclas_tuple_ipv4 { + u_int8_t version; + uint8_t src_ip[IEEE80211_IPV4_LEN]; + uint8_t dst_ip[IEEE80211_IPV4_LEN]; + u_int16_t src_port; + u_int16_t dst_port; + u_int8_t dscp; + u_int8_t protocol; + u_int8_t reserved; +} __packed; + +struct cdp_tclas_tuple_ipv6 { + u_int8_t version; + u_int8_t src_ip[IEEE80211_IPV6_LEN]; + u_int8_t dst_ip[IEEE80211_IPV6_LEN]; + u_int16_t src_port; + u_int16_t dst_port; + u_int8_t type4_dscp; + u_int8_t next_header; + u_int8_t flow_label[3]; +} __packed; + +struct cdp_tclas_tuple_ipsec { + u_int8_t protocol_number; + u_int8_t protocol_instance; + u_int8_t filter_len; + u_int8_t *filter_mask; + u_int8_t *filter_val; +} __packed; + +struct cdp_tclas_tuple { + uint8_t type; + uint8_t mask; + union { + union { + struct cdp_tclas_tuple_ipv4 v4; + struct cdp_tclas_tuple_ipv6 v6; + } type4; + struct cdp_tclas_tuple_ipsec ips; + } tclas; +} __packed; + +/** + * struct cdp_scs_params - SCS parameters + * obtained from handshake + * @scsid - SCS ID + * @access_priority - User Access Priority + * containing tid value. + * @tclas_elements - Number of TCLAS elements + * @tclas - TCLAS tuple parameters + * @tclas_processing - TCLAS processing value + */ +struct cdp_scs_params { + uint8_t scsid; + uint8_t access_priority; + uint8_t tclas_elements; + struct cdp_tclas_tuple tclas[IEEE80211_SCS_MAX_SIZE]; + uint8_t tclas_process; +}; +#endif + #ifdef WLAN_SUPPORT_MSCS /** * struct cdp_mscs_params - MSCS parameters obtained diff --git a/dp/inc/cdp_txrx_ctrl.h b/dp/inc/cdp_txrx_ctrl.h index 9b7aa63b71..8a94c3f03f 100644 --- a/dp/inc/cdp_txrx_ctrl.h +++ b/dp/inc/cdp_txrx_ctrl.h @@ -96,6 +96,76 @@ cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc, } #endif /* ATH_SUPPORT_NAC || ATH_SUPPORT_NAC_RSSI*/ +#ifdef WLAN_SUPPORT_SCS +/** + * @brief enable/disable the SCS feature. + * @details + * This defines interface function to enable/disable the SCS + * procedure based data parameters so that the data path layer + * can access it. + * @param soc - the pointer to soc object + * @param vdev_id - id of the pointer to vdev + * @param macaddr - the address of neighbour peer + * @param is_active - Bit to indicate SCS active/inactive + */ +static inline QDF_STATUS +cdp_enable_scs_params(ol_txrx_soc_handle soc, + struct qdf_mac_addr *macaddr, + uint8_t vdev_id, + bool is_active) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance:"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_enable_scs_params) + return QDF_STATUS_E_FAILURE; + return soc->ops->ctrl_ops->txrx_enable_scs_params + (soc, macaddr, vdev_id, is_active); +} + +/** + * @brief cdp_record_scs_params() - record the SCS data + * and send it to the data path + * + * @param soc - the pointer to soc object + * @param vdev_id - id of the pointer to vdev + * @param macaddr - the address of neighbour peer + * @param scs_params - Structure having SCS params + * obtained from handshake + * @param entry_ctr - Index # of the entry in the + * node database having a non-zero SCSID + * @param scs_sessions - Number of SCS sessions + * + * @details + * Interface function to record the SCS procedure + * based data parameters so that the data path layer can access it. + * @return - QDF_STATUS + */ +static inline QDF_STATUS +cdp_record_scs_params(ol_txrx_soc_handle soc, + struct qdf_mac_addr *macaddr, uint8_t vdev_id, + struct cdp_scs_params *scs_params, + uint8_t entry_ctr, uint8_t scs_sessions) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance:"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_record_scs_params) + return QDF_STATUS_E_FAILURE; + return soc->ops->ctrl_ops->txrx_record_scs_params + (soc, macaddr, vdev_id, scs_params, + entry_ctr, scs_sessions); +} +#endif + #ifdef WLAN_SUPPORT_MSCS /** * @brief record the MSCS data and send it to the Data path diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 724d95e6be..729d6eed19 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -719,6 +719,24 @@ struct cdp_ctrl_ops { uint8_t *rssi); #endif +#ifdef WLAN_SUPPORT_SCS + QDF_STATUS + (*txrx_enable_scs_params) ( + struct cdp_soc_t *soc, struct qdf_mac_addr + *macaddr, + uint8_t vdev_id, + bool is_active); + + QDF_STATUS + (*txrx_record_scs_params) ( + struct cdp_soc_t *soc, struct qdf_mac_addr + *macaddr, + uint8_t vdev_id, + struct cdp_scs_params *scs_params, + uint8_t entry_ctr, + uint8_t scs_sessions); +#endif + #ifdef WLAN_SUPPORT_MSCS QDF_STATUS (*txrx_record_mscs_params) ( diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 1f09cceb3a..36b5324e3e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -7518,6 +7518,140 @@ fail0: } #endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ +#ifdef WLAN_SUPPORT_SCS +/* + * dp_enable_scs_params - Enable/Disable SCS procedures + * @soc - Datapath soc handle + * @peer_mac - STA Mac address + * @vdev_id - ID of the vdev handle + * @active - Flag to set SCS active/inactive + * return type - QDF_STATUS - Success/Invalid + */ +static QDF_STATUS +dp_enable_scs_params(struct cdp_soc_t *soc_hdl, struct qdf_mac_addr + *peer_mac, + uint8_t vdev_id, + bool is_active) +{ + struct dp_peer *peer; + QDF_STATUS status = QDF_STATUS_E_INVAL; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + + peer = dp_peer_find_hash_find(soc, peer_mac->bytes, 0, vdev_id, + DP_MOD_ID_CDP); + + if (!peer) { + dp_err("Peer is NULL!"); + goto fail; + } + + peer->scs_is_active = is_active; + status = QDF_STATUS_SUCCESS; + +fail: + if (peer) + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + return status; +} + +/* + * @brief dp_copy_scs_params - SCS Parameters sent by STA + * is copied from the cdp layer to the dp layer + * These parameters are then used by the peer + * for traffic classification. + * + * @param peer - peer struct + * @param scs_params - cdp layer params + * @idx - SCS_entry index obtained from the + * node database with a given SCSID + * @return void + */ +void +dp_copy_scs_params(struct dp_peer *peer, + struct cdp_scs_params *scs_params, + uint8_t idx) +{ + uint8_t tidx = 0; + uint8_t tclas_elem; + + peer->scs[idx].scsid = scs_params->scsid; + peer->scs[idx].access_priority = + scs_params->access_priority; + peer->scs[idx].tclas_elements = + scs_params->tclas_elements; + peer->scs[idx].tclas_process = + scs_params->tclas_process; + + tclas_elem = peer->scs[idx].tclas_elements; + + while (tidx < tclas_elem) { + qdf_mem_copy(&peer->scs[idx].tclas[tidx], + &scs_params->tclas[tidx], + sizeof(struct cdp_tclas_tuple)); + tidx++; + } +} + +/* + * @brief dp_record_scs_params() - Copying the SCS params to a + * peer based database. + * + * @soc - Datapath soc handle + * @peer_mac - STA Mac address + * @vdev_id - ID of the vdev handle + * @scs_params - Structure having SCS parameters obtained + * from handshake + * @idx - SCS_entry index obtained from the + * node database with a given SCSID + * @scs_sessions - Total # of SCS sessions active + * + * @details + * SCS parameters sent by the STA in + * the SCS Request to the AP. The AP makes a note of these + * parameters while sending the MSDUs to the STA, to + * send the downlink traffic with correct User priority. + * + * return type - QDF_STATUS - Success/Invalid + */ +static QDF_STATUS +dp_record_scs_params(struct cdp_soc_t *soc_hdl, struct qdf_mac_addr + *peer_mac, + uint8_t vdev_id, + struct cdp_scs_params *scs_params, + uint8_t idx, + uint8_t scs_sessions) +{ + struct dp_peer *peer; + QDF_STATUS status = QDF_STATUS_E_INVAL; + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + + peer = dp_peer_find_hash_find(soc, peer_mac->bytes, 0, vdev_id, + DP_MOD_ID_CDP); + + if (!peer) { + dp_err("Peer is NULL!"); + goto fail; + } + + if (idx >= IEEE80211_SCS_MAX_NO_OF_ELEM) + goto fail; + + /* SCS procedure for the peer is activated + * as soon as we get this information from + * the control path, unless explicitly disabled. + */ + peer->scs_is_active = 1; + dp_copy_scs_params(peer, scs_params, idx); + status = QDF_STATUS_SUCCESS; + peer->no_of_scs_sessions = scs_sessions; + +fail: + if (peer) + dp_peer_unref_delete(peer, DP_MOD_ID_CDP); + return status; +} +#endif + #ifdef WLAN_SUPPORT_MSCS /* * dp_record_mscs_params - MSCS parameters sent by the STA in @@ -12266,6 +12400,10 @@ static struct cdp_ctrl_ops dp_ops_ctrl = { #endif #ifdef WLAN_SUPPORT_MSCS .txrx_record_mscs_params = dp_record_mscs_params, +#endif +#ifdef WLAN_SUPPORT_SCS + .txrx_enable_scs_params = dp_enable_scs_params, + .txrx_record_scs_params = dp_record_scs_params, #endif .set_key = dp_set_michael_key, .txrx_get_vdev_param = dp_get_vdev_param, diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index bd03482222..6357bfb21c 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -3112,6 +3112,16 @@ struct dp_peer_ast_params { uint8_t flowQ; }; +#ifdef WLAN_SUPPORT_SCS +/* SCS procedures macros */ +/* SCS Procedures - SCS parameters + * obtained from SCS request are stored + * in a peer based database for traffic + * classification. + */ +#define IEEE80211_SCS_MAX_NO_OF_ELEM 10 +#endif + #ifdef WLAN_SUPPORT_MSCS /*MSCS Procedure based macros */ #define IEEE80211_MSCS_MAX_ELEM_SIZE 5 @@ -3289,6 +3299,11 @@ struct dp_peer { uint8_t peer_state; qdf_spinlock_t peer_state_lock; +#ifdef WLAN_SUPPORT_SCS + struct cdp_scs_params scs[IEEE80211_SCS_MAX_NO_OF_ELEM]; + bool scs_is_active; + uint8_t no_of_scs_sessions; +#endif #ifdef WLAN_SUPPORT_MSCS struct dp_peer_mscs_parameter mscs_ipv4_parameter, mscs_ipv6_parameter; bool mscs_active;