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:
Abhinav Kumar 2020-10-06 15:07:22 +05:30 committed by snandini
parent f797891003
commit c526619159
22 changed files with 619 additions and 1 deletions

3
Kbuild
View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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;

View File

@ -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),)

View File

@ -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 \

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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.