qcacld-3.0: Trigger MSCS action frame
Add logic to send MSCS action frame to AP based on voice tx packet. Change-Id: I272addfcb60e459043426950d00ba5957b594505 CRs-Fixed: 2791796
This commit is contained in:
parent
f797891003
commit
c526619159
3
Kbuild
3
Kbuild
@ -3400,6 +3400,9 @@ cppflags-$(CONFIG_ADAPTIVE_11R) += -DWLAN_ADAPTIVE_11R
|
||||
#Flag to enable/disable sae single pmk feature feature
|
||||
cppflags-$(CONFIG_SAE_SINGLE_PMK) += -DWLAN_SAE_SINGLE_PMK
|
||||
|
||||
#Flag to enable/disable mscs feature
|
||||
cppflags-$(CONFIG_FEATURE_MSCS) += -DWLAN_FEATURE_MSCS
|
||||
|
||||
#Flag to enable NUD tracking
|
||||
cppflags-$(CONFIG_WLAN_NUD_TRACKING) += -DWLAN_NUD_TRACKING
|
||||
|
||||
|
@ -144,6 +144,94 @@ struct wlan_mlme_roam {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/**
|
||||
* struct tclas_mask - TCLAS Mask Elements for mscs request
|
||||
* @classifier_type: specifies the type of classifier parameters
|
||||
* in TCLAS element. Currently driver supports classifier type = 4 only.
|
||||
* @classifier_mask: Mask for tclas elements. For example, if
|
||||
* classifier type = 4, value of classifier mask is 0x5F.
|
||||
* @info: information of classifier type
|
||||
*/
|
||||
struct tclas_mask {
|
||||
uint8_t classifier_type;
|
||||
uint8_t classifier_mask;
|
||||
union {
|
||||
struct {
|
||||
uint8_t version;
|
||||
union {
|
||||
struct {
|
||||
uint8_t source[4];
|
||||
uint8_t dest[4];
|
||||
uint16_t src_port;
|
||||
uint16_t dest_port;
|
||||
uint8_t dscp;
|
||||
uint8_t proto;
|
||||
uint8_t reserved;
|
||||
} ip_v4_params;
|
||||
struct {
|
||||
uint8_t source[16];
|
||||
uint8_t dest[16];
|
||||
uint16_t src_port;
|
||||
uint16_t dest_port;
|
||||
uint8_t DSCP;
|
||||
uint8_t next_header;
|
||||
uint8_t flow_label[3];
|
||||
} ip_v6_params;
|
||||
} params;
|
||||
} ip_params; /* classifier_type = 4 */
|
||||
} info;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum scs_request_type - scs request type to peer
|
||||
* @SCS_REQ_ADD: To set mscs parameters
|
||||
* @SCS_REQ_REMOVE: Remove mscs parameters
|
||||
* @SCS_REQ_CHANGE: Update mscs parameters
|
||||
*/
|
||||
enum scs_request_type {
|
||||
SCS_REQ_ADD = 0,
|
||||
SCS_REQ_REMOVE = 1,
|
||||
SCS_REQ_CHANGE = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct descriptor_element - mscs Descriptor element
|
||||
* @request_type: mscs request type defined in enum scs_request_type
|
||||
* @user_priority_control: To set user priority of tx packet
|
||||
* @stream_timeout: minimum timeout value, in TUs, for maintaining
|
||||
* variable user priority in the MSCS list.
|
||||
* @tclas_mask: to specify how incoming MSDUs are classified into
|
||||
* streams in MSCS
|
||||
* @status_code: status of mscs request
|
||||
*/
|
||||
struct descriptor_element {
|
||||
uint8_t request_type;
|
||||
uint16_t user_priority_control;
|
||||
uint64_t stream_timeout;
|
||||
struct tclas_mask tclas_mask;
|
||||
uint8_t status_code;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mscs_req_info - mscs request information
|
||||
* @vdev_id: session id
|
||||
* @bssid: peer bssid
|
||||
* @dialog_token: Token number of mscs req action frame
|
||||
* @dec: mscs Descriptor element defines information about
|
||||
* the parameters used to classify streams
|
||||
* @is_mscs_req_sent: To Save mscs req request if any (only
|
||||
* one can be outstanding at any time)
|
||||
*/
|
||||
struct mscs_req_info {
|
||||
uint8_t vdev_id;
|
||||
struct qdf_mac_addr bssid;
|
||||
uint8_t dialog_token;
|
||||
struct descriptor_element dec;
|
||||
bool is_mscs_req_sent;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct mlme_legacy_priv - VDEV MLME legacy priv object
|
||||
* @chan_switch_in_progress: flag to indicate that channel switch is in progress
|
||||
@ -170,6 +258,7 @@ struct wlan_mlme_roam {
|
||||
* @fils_con_info: Pointer to fils connection info from csr roam profile
|
||||
* @opr_rate_set: operational rates set
|
||||
* @ext_opr_rate_set: extended operational rates set
|
||||
* @mscs_req_info: Information related to mscs request
|
||||
*/
|
||||
struct mlme_legacy_priv {
|
||||
bool chan_switch_in_progress;
|
||||
@ -197,6 +286,9 @@ struct mlme_legacy_priv {
|
||||
#endif
|
||||
struct mlme_cfg_str opr_rate_set;
|
||||
struct mlme_cfg_str ext_opr_rate_set;
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
struct mscs_req_info mscs_req_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,6 +64,37 @@ QDF_STATUS mlme_unregister_vdev_mgr_ops(struct vdev_mlme_obj *vdev_mlme);
|
||||
QDF_STATUS mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev,
|
||||
bool val);
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/**
|
||||
* mlme_set_is_mscs_req_sent() - set mscs frame req flag
|
||||
* @vdev: vdev pointer
|
||||
* @val: value to be set
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS mlme_set_is_mscs_req_sent(struct wlan_objmgr_vdev *vdev, bool val);
|
||||
|
||||
/**
|
||||
* mlme_get_is_mscs_req_sent() - get mscs frame req flag
|
||||
* @vdev: vdev pointer
|
||||
*
|
||||
* Return: value of mscs flag
|
||||
*/
|
||||
bool mlme_get_is_mscs_req_sent(struct wlan_objmgr_vdev *vdev);
|
||||
#else
|
||||
static inline
|
||||
QDF_STATUS mlme_set_is_mscs_req_sent(struct wlan_objmgr_vdev *vdev, bool val)
|
||||
{
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool mlme_get_is_mscs_req_sent(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* mlme_is_chan_switch_in_progress() - get mlme priv restart in progress
|
||||
* @vdev: vdev pointer
|
||||
|
@ -588,6 +588,36 @@ QDF_STATUS mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
QDF_STATUS mlme_set_is_mscs_req_sent(struct wlan_objmgr_vdev *vdev, bool val)
|
||||
{
|
||||
struct mlme_legacy_priv *mlme_priv;
|
||||
|
||||
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
||||
if (!mlme_priv) {
|
||||
mlme_legacy_err("vdev legacy private object is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
mlme_priv->mscs_req_info.is_mscs_req_sent = val;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bool mlme_get_is_mscs_req_sent(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct mlme_legacy_priv *mlme_priv;
|
||||
|
||||
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
||||
if (!mlme_priv) {
|
||||
mlme_legacy_err("vdev legacy private object is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
return mlme_priv->mscs_req_info.is_mscs_req_sent;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool mlme_is_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct mlme_legacy_priv *mlme_priv;
|
||||
|
@ -300,6 +300,9 @@ CONFIG_ADAPTIVE_11R := y
|
||||
#Flag to enable sae single pmk feature
|
||||
CONFIG_SAE_SINGLE_PMK := y
|
||||
|
||||
#Flag to enable mscs feature
|
||||
CONFIG_FEATURE_MSCS := y
|
||||
|
||||
#Flag to enable FILS Feature (11ai)
|
||||
CONFIG_WLAN_FEATURE_FILS := y
|
||||
ifneq ($(CONFIG_QCA_CLD_WLAN),)
|
||||
|
@ -353,6 +353,65 @@
|
||||
|
||||
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/*
|
||||
* <ini>
|
||||
* mscs_pkt_threshold - Voice pkt count threshold
|
||||
*
|
||||
* @Min: 0
|
||||
* @Max: 10000
|
||||
* @Default: 1200
|
||||
*
|
||||
* This ini specifies the Voice pkt count threshold to
|
||||
* Send MSCS action frame to AP
|
||||
*
|
||||
* Usage: Internal
|
||||
*
|
||||
* </ini>
|
||||
*/
|
||||
#define CFG_VO_PKT_COUNT_THRESHOLD \
|
||||
CFG_INI_UINT( \
|
||||
"mscs_pkt_threshold", \
|
||||
0, \
|
||||
10000, \
|
||||
1200, \
|
||||
CFG_VALUE_OR_DEFAULT, \
|
||||
"Voice pkt count threshold")
|
||||
|
||||
/*
|
||||
* <ini>
|
||||
* mscs_voice_interval - mscs voice interval in sec
|
||||
*
|
||||
* @Min: 0
|
||||
* @Max: 300
|
||||
* @Default: 30
|
||||
*
|
||||
* This ini specifies the mscs voice interval to
|
||||
* monitor voice tx packet count to send MSCS action frame
|
||||
*
|
||||
* Related: mscs_pkt_threshold
|
||||
*
|
||||
* Usage: Internal
|
||||
*
|
||||
* </ini>
|
||||
*/
|
||||
#define CFG_MSCS_VOICE_INTERVAL \
|
||||
CFG_INI_UINT( \
|
||||
"mscs_voice_interval", \
|
||||
0, \
|
||||
300, \
|
||||
30, \
|
||||
CFG_VALUE_OR_DEFAULT, \
|
||||
"mscs voice interval")
|
||||
|
||||
#define CFG_MSCS_FEATURE_ALL \
|
||||
CFG(CFG_VO_PKT_COUNT_THRESHOLD) \
|
||||
CFG(CFG_MSCS_VOICE_INTERVAL)
|
||||
|
||||
#else
|
||||
#define CFG_MSCS_FEATURE_ALL
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
|
||||
/*
|
||||
* <ini>
|
||||
@ -1445,6 +1504,7 @@
|
||||
CFG(CFG_DP_RX_WAKELOCK_TIMEOUT) \
|
||||
CFG(CFG_DP_NUM_DP_RX_THREADS) \
|
||||
CFG(CFG_DP_HTC_WMI_CREDIT_CNT) \
|
||||
CFG_MSCS_FEATURE_ALL \
|
||||
CFG_DP_ENABLE_FASTPATH_ALL \
|
||||
CFG_HDD_DP_BUS_BANDWIDTH \
|
||||
CFG_DP_DRIVER_TCP_DELACK \
|
||||
|
@ -175,6 +175,11 @@ struct hdd_config {
|
||||
bool enable_latency_crit_clients;
|
||||
#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
uint32_t mscs_pkt_threshold;
|
||||
uint32_t mscs_voice_interval;
|
||||
#endif /* WLAN_FEATURE_MSCS */
|
||||
|
||||
#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
|
||||
bool del_ack_enable;
|
||||
uint32_t del_ack_threshold_high;
|
||||
|
@ -1316,6 +1316,11 @@ struct hdd_adapter {
|
||||
uint64_t prev_fwd_rx_packets;
|
||||
#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
unsigned long mscs_prev_tx_vo_pkts;
|
||||
uint32_t mscs_counter;
|
||||
#endif /* WLAN_FEATURE_MSCS */
|
||||
|
||||
#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
|
||||
defined(QCA_HL_NETDEV_FLOW_CONTROL)
|
||||
qdf_mc_timer_t tx_flow_control_timer;
|
||||
|
@ -20929,6 +20929,28 @@ wlan_hdd_cfg80211_indicate_disconnect(struct hdd_adapter *adapter,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/**
|
||||
* reset_mscs_params() - Reset mscs parameters
|
||||
* @adapter: pointer to adapter structure
|
||||
*
|
||||
* Reset mscs parameters whils disconnection
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void reset_mscs_params(struct hdd_adapter *adapter)
|
||||
{
|
||||
mlme_set_is_mscs_req_sent(adapter->vdev, false);
|
||||
adapter->mscs_counter = 0;
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
void reset_mscs_params(struct hdd_adapter *adapter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason,
|
||||
enum wlan_reason_code mac_reason)
|
||||
{
|
||||
@ -20940,6 +20962,7 @@ int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason,
|
||||
|
||||
/*stop tx queues */
|
||||
hdd_debug("Disabling queues");
|
||||
reset_mscs_params(adapter);
|
||||
wlan_hdd_netif_queue_control(adapter,
|
||||
WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH);
|
||||
|
||||
|
@ -10065,6 +10065,41 @@ void hdd_set_vdev_bundle_require_flag(uint16_t vdev_id,
|
||||
#endif
|
||||
|
||||
#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
static
|
||||
void hdd_send_mscs_action_frame(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter)
|
||||
{
|
||||
uint64_t mscs_vo_pkt_delta;
|
||||
unsigned long tx_vo_pkts;
|
||||
|
||||
tx_vo_pkts = adapter->hdd_stats.tx_rx_stats.tx_classified_ac[SME_AC_VO];
|
||||
|
||||
if (!adapter->mscs_counter)
|
||||
adapter->mscs_prev_tx_vo_pkts = tx_vo_pkts;
|
||||
|
||||
adapter->mscs_counter++;
|
||||
|
||||
if (adapter->mscs_counter * hdd_ctx->config->bus_bw_compute_interval >=
|
||||
hdd_ctx->config->mscs_voice_interval * 1000) {
|
||||
adapter->mscs_counter = 0;
|
||||
mscs_vo_pkt_delta =
|
||||
HDD_BW_GET_DIFF(tx_vo_pkts,
|
||||
adapter->mscs_prev_tx_vo_pkts);
|
||||
if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold &&
|
||||
!mlme_get_is_mscs_req_sent(adapter->vdev))
|
||||
sme_send_mscs_action_frame(adapter->vdev_id);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
void hdd_send_mscs_action_frame(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
|
||||
@ -10113,6 +10148,10 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
|
||||
tx_bytes = HDD_BW_GET_DIFF(adapter->stats.tx_bytes,
|
||||
adapter->prev_tx_bytes);
|
||||
|
||||
if (adapter->device_mode == QDF_STA_MODE &&
|
||||
hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
|
||||
hdd_send_mscs_action_frame(hdd_ctx, adapter);
|
||||
|
||||
if (adapter->device_mode == QDF_SAP_MODE ||
|
||||
adapter->device_mode == QDF_P2P_GO_MODE ||
|
||||
adapter->device_mode == QDF_NDI_MODE) {
|
||||
|
@ -3378,6 +3378,30 @@ static void hdd_ini_tx_flow_control(struct hdd_config *config,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/**
|
||||
* hdd_ini_mscs_params() - Initialize INIs related to MSCS feature
|
||||
* @config: pointer to hdd config
|
||||
* @psoc: pointer to psoc obj
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hdd_ini_mscs_params(struct hdd_config *config,
|
||||
struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
config->mscs_pkt_threshold =
|
||||
cfg_get(psoc, CFG_VO_PKT_COUNT_THRESHOLD);
|
||||
config->mscs_voice_interval =
|
||||
cfg_get(psoc, CFG_MSCS_VOICE_INTERVAL);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void hdd_ini_mscs_params(struct hdd_config *config,
|
||||
struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
|
||||
/**
|
||||
* hdd_ini_tx_flow_control() - Initialize INIs concerned about bus bandwidth
|
||||
@ -3581,6 +3605,7 @@ void hdd_dp_cfg_update(struct wlan_objmgr_psoc *psoc,
|
||||
hdd_ini_tx_flow_control(config, psoc);
|
||||
hdd_ini_bus_bandwidth(config, psoc);
|
||||
hdd_ini_tcp_settings(config, psoc);
|
||||
hdd_ini_mscs_params(config, psoc);
|
||||
|
||||
hdd_ini_tcp_del_ack_settings(config, psoc);
|
||||
|
||||
|
@ -67,8 +67,9 @@ enum eWniMsgTypes {
|
||||
eWNI_SME_DELTS_REQ = SIR_SME_MSG_TYPES_BEGIN + 30,
|
||||
eWNI_SME_DELTS_RSP = SIR_SME_MSG_TYPES_BEGIN + 31,
|
||||
eWNI_SME_DELTS_IND = SIR_SME_MSG_TYPES_BEGIN + 32,
|
||||
eWNI_SME_MSCS_REQ = SIR_SME_MSG_TYPES_BEGIN + 33,
|
||||
/*
|
||||
* unused SIR_SME_MSG_TYPES_BEGIN + 33 to
|
||||
* unused SIR_SME_MSG_TYPES_BEGIN + 34 to
|
||||
* to SIR_SME_MSG_TYPES_BEGIN + 35
|
||||
*/
|
||||
eWNI_SME_ASSOC_IND_UPPER_LAYER = SIR_SME_MSG_TYPES_BEGIN + 36,
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "dot11f.h"
|
||||
#include "lim_ft_defs.h"
|
||||
#include "lim_session.h"
|
||||
#include "wlan_mlme_main.h"
|
||||
|
||||
#define COUNTRY_STRING_LENGTH (3)
|
||||
#define COUNTRY_INFO_MAX_CHANNEL (84)
|
||||
@ -975,6 +976,12 @@ void populate_dot11f_tspec(struct mac_tspec_ie *pOld, tDot11fIETSPEC *pDot11f);
|
||||
void populate_dot11f_wmmtspec(struct mac_tspec_ie *pOld,
|
||||
tDot11fIEWMMTSPEC *pDot11f);
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
void
|
||||
populate_dot11f_mscs_dec_element(struct mscs_req_info *mscs_req,
|
||||
tDot11fmscs_request_action_frame *dot11f);
|
||||
#endif
|
||||
|
||||
QDF_STATUS
|
||||
populate_dot11f_tclas(struct mac_context *mac,
|
||||
tSirTclasInfo *pOld, tDot11fIETCLAS *pDot11f);
|
||||
|
@ -1742,6 +1742,7 @@ static void lim_process_messages(struct mac_context *mac_ctx,
|
||||
case eWNI_SME_DEAUTH_CNF:
|
||||
case eWNI_SME_ASSOC_CNF:
|
||||
case eWNI_SME_ADDTS_REQ:
|
||||
case eWNI_SME_MSCS_REQ:
|
||||
case eWNI_SME_DELTS_REQ:
|
||||
case eWNI_SME_SESSION_UPDATE_PARAM:
|
||||
case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
|
||||
|
@ -3064,6 +3064,63 @@ send_failure_addts_rsp:
|
||||
smesessionId);
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
static void
|
||||
__lim_process_sme_mscs_req(struct mac_context *mac, uint32_t *msg_buf)
|
||||
{
|
||||
struct qdf_mac_addr peer_mac;
|
||||
struct mscs_req_info *mscs_req;
|
||||
struct pe_session *pe_session;
|
||||
uint8_t pe_session_id;
|
||||
|
||||
if (!msg_buf) {
|
||||
pe_err("Buffer is Pointing to NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
mscs_req = (struct mscs_req_info *) msg_buf;
|
||||
pe_session = pe_find_session_by_bssid(mac, mscs_req->bssid.bytes,
|
||||
&pe_session_id);
|
||||
if (!pe_session) {
|
||||
pe_err("Session Does not exist for bssid: " QDF_MAC_ADDR_FMT,
|
||||
QDF_MAC_ADDR_REF(mscs_req->bssid.bytes));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!LIM_IS_STA_ROLE(pe_session)) {
|
||||
pe_err("MSCS req received on AP - ignoring");
|
||||
return;
|
||||
}
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(wlan_vdev_mlme_is_active(pe_session->vdev))) {
|
||||
pe_err("mscs req in unexpected vdev SM state:%d",
|
||||
wlan_vdev_mlme_get_state(pe_session->vdev));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mscs_req->is_mscs_req_sent) {
|
||||
pe_err("MSCS req already sent");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_mem_copy(peer_mac.bytes, pe_session->bssId, QDF_MAC_ADDR_SIZE);
|
||||
|
||||
/* save the mscs request */
|
||||
mscs_req->is_mscs_req_sent = true;
|
||||
|
||||
/* ship out the message now */
|
||||
lim_send_mscs_req_action_frame(mac, peer_mac, mscs_req,
|
||||
pe_session);
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
__lim_process_sme_mscs_req(struct mac_context *mac, uint32_t *msg_buf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
__lim_process_sme_delts_req(struct mac_context *mac, uint32_t *msg_buf)
|
||||
{
|
||||
@ -4651,6 +4708,11 @@ bool lim_process_sme_req_messages(struct mac_context *mac,
|
||||
__lim_process_sme_addts_req(mac, msg_buf);
|
||||
break;
|
||||
|
||||
case eWNI_SME_MSCS_REQ:
|
||||
pe_debug("Received MSCS_REQ message");
|
||||
__lim_process_sme_mscs_req(mac, msg_buf);
|
||||
break;
|
||||
|
||||
case eWNI_SME_DELTS_REQ:
|
||||
pe_debug("Received DELTS_REQ message");
|
||||
__lim_process_sme_delts_req(mac, msg_buf);
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "lim_process_fils.h"
|
||||
#include "wlan_utility.h"
|
||||
#include <wlan_mlme_api.h>
|
||||
#include <wlan_mlme_main.h>
|
||||
|
||||
/**
|
||||
*
|
||||
@ -1093,6 +1094,132 @@ lim_send_addts_req_action_frame(struct mac_context *mac,
|
||||
qdf_status);
|
||||
} /* End lim_send_addts_req_action_frame. */
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/**
|
||||
* lim_mscs_req_tx_complete_cnf()- Confirmation for mscs req sent over the air
|
||||
* @context: pointer to global mac
|
||||
* @buf: buffer
|
||||
* @tx_complete : Sent status
|
||||
* @params; tx completion params
|
||||
*
|
||||
* Return: This returns QDF_STATUS
|
||||
*/
|
||||
|
||||
static QDF_STATUS lim_mscs_req_tx_complete_cnf(void *context, qdf_nbuf_t buf,
|
||||
uint32_t tx_complete,
|
||||
void *params)
|
||||
{
|
||||
uint16_t mscs_ack_status;
|
||||
uint16_t reason_code;
|
||||
|
||||
pe_debug("mscs req TX: %s (%d)",
|
||||
(tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ?
|
||||
"success" : "fail", tx_complete);
|
||||
|
||||
if (tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) {
|
||||
mscs_ack_status = ACKED;
|
||||
reason_code = QDF_STATUS_SUCCESS;
|
||||
} else {
|
||||
mscs_ack_status = NOT_ACKED;
|
||||
reason_code = QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
if (buf)
|
||||
qdf_nbuf_free(buf);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void lim_send_mscs_req_action_frame(struct mac_context *mac,
|
||||
struct qdf_mac_addr peer_mac,
|
||||
struct mscs_req_info *mscs_req,
|
||||
struct pe_session *pe_session)
|
||||
{
|
||||
uint8_t *frame;
|
||||
tDot11fmscs_request_action_frame mscs_req_frame;
|
||||
uint32_t payload, bytes;
|
||||
tpSirMacMgmtHdr peer_mac_hdr;
|
||||
void *packet;
|
||||
QDF_STATUS qdf_status;
|
||||
tpSirMacMgmtHdr mac_hdr;
|
||||
|
||||
qdf_mem_zero(&mscs_req_frame, sizeof(mscs_req_frame));
|
||||
|
||||
mscs_req_frame.Action.action = MCSC_REQ;
|
||||
mscs_req_frame.DialogToken.token = mscs_req->dialog_token;
|
||||
mscs_req_frame.Category.category = ACTION_CATEGORY_RVS;
|
||||
populate_dot11f_mscs_dec_element(mscs_req, &mscs_req_frame);
|
||||
bytes = dot11f_get_packed_mscs_request_action_frameSize(mac,
|
||||
&mscs_req_frame, &payload);
|
||||
if (DOT11F_FAILED(bytes)) {
|
||||
pe_err("Failed to calculate the packed size for an MSCS Request (0x%08x)",
|
||||
bytes);
|
||||
/* We'll fall back on the worst case scenario: */
|
||||
payload = sizeof(tDot11fmscs_request_action_frame);
|
||||
} else if (DOT11F_WARNED(bytes)) {
|
||||
pe_warn("There were warnings while calculating the packed size for MSCS Request (0x%08x)",
|
||||
bytes);
|
||||
}
|
||||
|
||||
bytes = payload + sizeof(struct qdf_mac_addr);
|
||||
|
||||
qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
|
||||
(void **)&packet);
|
||||
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
||||
pe_err("Failed to allocate %d bytes for an mscs request",
|
||||
bytes);
|
||||
return;
|
||||
}
|
||||
/* Paranoia: */
|
||||
qdf_mem_zero(frame, bytes);
|
||||
|
||||
lim_populate_mac_header(mac, frame, SIR_MAC_MGMT_FRAME,
|
||||
SIR_MAC_MGMT_ACTION,
|
||||
peer_mac.bytes, pe_session->self_mac_addr);
|
||||
peer_mac_hdr = (tpSirMacMgmtHdr) frame;
|
||||
|
||||
qdf_mem_copy(peer_mac.bytes, pe_session->bssId, QDF_MAC_ADDR_SIZE);
|
||||
|
||||
lim_set_protected_bit(mac, pe_session, peer_mac.bytes, peer_mac_hdr);
|
||||
|
||||
bytes = dot11f_pack_mscs_request_action_frame(mac, &mscs_req_frame,
|
||||
frame +
|
||||
sizeof(tSirMacMgmtHdr),
|
||||
payload, &payload);
|
||||
if (DOT11F_FAILED(bytes)) {
|
||||
pe_err("Failed to pack an mscs Request " "(0x%08x)", bytes);
|
||||
cds_packet_free((void *)packet);
|
||||
return; /* allocated! */
|
||||
} else if (DOT11F_WARNED(bytes)) {
|
||||
pe_warn("There were warnings while packing an mscs Request (0x%08x)",
|
||||
bytes);
|
||||
}
|
||||
|
||||
mac_hdr = (tpSirMacMgmtHdr) frame;
|
||||
|
||||
pe_debug("mscs req TX: vdev id: %d to "QDF_MAC_ADDR_FMT" seq num[%d], frame subtype:%d ",
|
||||
mscs_req->vdev_id, peer_mac.bytes, mac->mgmtSeqNum,
|
||||
mac_hdr->fc.subType);
|
||||
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
|
||||
frame,
|
||||
(uint16_t)(sizeof(tSirMacMgmtHdr) + payload));
|
||||
qdf_status =
|
||||
wma_tx_frameWithTxComplete(mac, packet,
|
||||
(uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
|
||||
TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
|
||||
lim_tx_complete, frame, lim_mscs_req_tx_complete_cnf,
|
||||
HAL_USE_PEER_STA_REQUESTED_MASK, pe_session->vdev_id,
|
||||
false, 0, RATEID_DEFAULT);
|
||||
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
||||
mlme_set_is_mscs_req_sent(pe_session->vdev, true);
|
||||
} else {
|
||||
pe_err("Could not send an mscs Request (%X)", qdf_status);
|
||||
}
|
||||
|
||||
/* Pkt will be freed up by the callback */
|
||||
} /* End lim_send_mscs_req_action_frame */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* lim_assoc_rsp_tx_complete() - Confirmation for assoc rsp OTA
|
||||
* @context: pointer to global mac
|
||||
|
@ -642,6 +642,24 @@ void lim_send_delts_req_action_frame(struct mac_context *mac, tSirMacAddr peer,
|
||||
void lim_send_addts_req_action_frame(struct mac_context *mac, tSirMacAddr peerMacAddr,
|
||||
tSirAddtsReqInfo *addts, struct pe_session *);
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/**
|
||||
* lim_send_mscs_req_action_frame() - Send mscs req
|
||||
* @mac_ctx: Handle for mac context
|
||||
* @peer_mac: Mac address of requesting peer
|
||||
* @mscs_req: mscs request buffer
|
||||
* @pe_session: PE session id.
|
||||
*
|
||||
* Builds and sends mscs action frame to the peer.
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void lim_send_mscs_req_action_frame(struct mac_context *mac,
|
||||
struct qdf_mac_addr peer_mac,
|
||||
struct mscs_req_info *mscs_req,
|
||||
struct pe_session *pe_session);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* lim_send_assoc_rsp_mgmt_frame() - Send assoc response
|
||||
* @mac_ctx: Handle for mac context
|
||||
|
@ -255,6 +255,8 @@ char *lim_msg_str(uint32_t msgType)
|
||||
return "eWNI_SME_DEAUTH_CNF";
|
||||
case eWNI_SME_ADDTS_REQ:
|
||||
return "eWNI_SME_ADDTS_REQ";
|
||||
case eWNI_SME_MSCS_REQ:
|
||||
return "eWNI_SME_MSCS_REQ";
|
||||
case eWNI_SME_ADDTS_RSP:
|
||||
return "eWNI_SME_ADDTS_RSP";
|
||||
case eWNI_SME_DELTS_REQ:
|
||||
|
@ -238,6 +238,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
|
||||
CASE_RETURN_STRING(eWNI_SME_DEAUTH_CNF);
|
||||
CASE_RETURN_STRING(eWNI_SME_MIC_FAILURE_IND);
|
||||
CASE_RETURN_STRING(eWNI_SME_ADDTS_REQ);
|
||||
CASE_RETURN_STRING(eWNI_SME_MSCS_REQ);
|
||||
CASE_RETURN_STRING(eWNI_SME_ADDTS_RSP);
|
||||
CASE_RETURN_STRING(eWNI_SME_DELTS_REQ);
|
||||
CASE_RETURN_STRING(eWNI_SME_DELTS_RSP);
|
||||
|
@ -5057,6 +5057,28 @@ void populate_dot11f_tspec(struct mac_tspec_ie *pOld, tDot11fIETSPEC *pDot11f)
|
||||
|
||||
} /* End populate_dot11f_tspec. */
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
void
|
||||
populate_dot11f_mscs_dec_element(struct mscs_req_info *mscs_req,
|
||||
tDot11fmscs_request_action_frame *dot11f)
|
||||
{
|
||||
dot11f->decriptor_element.request_type =
|
||||
mscs_req->dec.request_type;
|
||||
dot11f->decriptor_element.user_priority_control =
|
||||
mscs_req->dec.user_priority_control;
|
||||
dot11f->decriptor_element.stream_timeout =
|
||||
mscs_req->dec.stream_timeout;
|
||||
dot11f->decriptor_element.tclas_mask.classifier_type =
|
||||
mscs_req->dec.tclas_mask.classifier_type;
|
||||
dot11f->decriptor_element.tclas_mask.classifier_mask =
|
||||
mscs_req->dec.tclas_mask.classifier_mask;
|
||||
|
||||
dot11f->decriptor_element.present = 1;
|
||||
dot11f->decriptor_element.tclas_mask.present = 1;
|
||||
|
||||
} /* End populate_dot11f_decriptor_element */
|
||||
#endif
|
||||
|
||||
void populate_dot11f_wmmtspec(struct mac_tspec_ie *pOld,
|
||||
tDot11fIEWMMTSPEC *pDot11f)
|
||||
{
|
||||
|
@ -2749,6 +2749,18 @@ struct mac_context *sme_get_mac_context(void);
|
||||
*/
|
||||
void sme_display_disconnect_stats(mac_handle_t mac_handle, uint8_t session_id);
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
/**
|
||||
* sme_send_mscs_action_frame() - Send MSCS action frame
|
||||
* @vdev_id: sme vdev_id
|
||||
*
|
||||
* This function is used to send down the mscs request to PE
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void sme_send_mscs_action_frame(uint8_t vdev_id);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* sme_process_msg_callback() - process callback message from LIM
|
||||
* @mac: global mac context
|
||||
|
@ -81,6 +81,14 @@
|
||||
/* The Dialog Token field shall be set [...] to a non-zero value */
|
||||
#define SME_QOS_MIN_DIALOG_TOKEN 1
|
||||
#define SME_QOS_MAX_DIALOG_TOKEN 0xFF
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
#define MSCS_USER_PRIORITY 0x07C0
|
||||
#define MSCS_STREAM_TIMEOUT 60 /* in sec */
|
||||
#define MSCS_TCLAS_CLASSIFIER_MASK 0x5F
|
||||
#define MSCS_TCLAS_CLASSIFIER_TYPE 4
|
||||
#endif
|
||||
|
||||
/* Type declarations */
|
||||
/* Enumeration of the various states in the QoS state m/c */
|
||||
enum sme_qos_states {
|
||||
@ -3813,6 +3821,47 @@ QDF_STATUS sme_qos_process_ft_reassoc_rsp_ev(struct mac_context *mac_ctx,
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_MSCS
|
||||
void sme_send_mscs_action_frame(uint8_t vdev_id)
|
||||
{
|
||||
struct mscs_req_info *mscs_req;
|
||||
struct sme_qos_sessioninfo *qos_session;
|
||||
struct scheduler_msg msg = {0};
|
||||
QDF_STATUS qdf_status;
|
||||
|
||||
qos_session = &sme_qos_cb.sessionInfo[vdev_id];
|
||||
if (!qos_session) {
|
||||
sme_debug("qos_session is NULL");
|
||||
return;
|
||||
}
|
||||
mscs_req = qdf_mem_malloc(sizeof(*mscs_req));
|
||||
if (!mscs_req)
|
||||
return;
|
||||
|
||||
mscs_req->vdev_id = vdev_id;
|
||||
qdf_mem_copy(&mscs_req->bssid.bytes[0],
|
||||
&qos_session->assocInfo.bss_desc->bssId[0],
|
||||
sizeof(struct qdf_mac_addr));
|
||||
|
||||
mscs_req->dialog_token = sme_qos_assign_dialog_token();
|
||||
mscs_req->dec.request_type = SCS_REQ_ADD;
|
||||
mscs_req->dec.user_priority_control = MSCS_USER_PRIORITY;
|
||||
mscs_req->dec.stream_timeout = (MSCS_STREAM_TIMEOUT * 1000);
|
||||
mscs_req->dec.tclas_mask.classifier_type = MSCS_TCLAS_CLASSIFIER_TYPE;
|
||||
mscs_req->dec.tclas_mask.classifier_mask = MSCS_TCLAS_CLASSIFIER_MASK;
|
||||
|
||||
msg.type = eWNI_SME_MSCS_REQ;
|
||||
msg.reserved = 0;
|
||||
msg.bodyptr = mscs_req;
|
||||
qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
|
||||
QDF_MODULE_ID_PE, &msg);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_status)) {
|
||||
sme_err("Fail to send mscs request to PE");
|
||||
qdf_mem_free(mscs_req);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* sme_qos_add_ts_req() - send ADDTS request.
|
||||
* @mac: Pointer to the global MAC parameter structure.
|
||||
|
Loading…
Reference in New Issue
Block a user