mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
qcacld-3.0: Involve VDEV SM when STA switch channel width
When found AP channel width change from beacon:
1. Set channel switch in progress with reason
LIM_SWITCH_CHANNEL_HT_WIDTH, Send
WLAN_VDEV_SM_EV_FW_VDEV_RESTART.
2. Call lim_ht_switch_chnl_params in
mlme_vdev_restart_send if reason is
LIM_SWITCH_CHANNEL_HT_WIDTH, set ht width switch
callback.
3. Send WLAN_VDEV_SM_EV_RESTART_RESP in
wma_vdev_start_resp_handler and clear channel switch in
progress.
4. Send WMA_SWITCH_CHANNEL_RSP in mlme_vdev_start_continue.
5. Send WLAN_VDEV_SM_EV_START_SUCCESS in ht width switch
callback to up vdev.
Change-Id: I46651e9aa17ebe049e44179d3a8fcc5a214762be
CRs-Fixed: 2372486
This commit is contained in:
parent
4177948219
commit
f2de84f371
3 changed files with 160 additions and 51 deletions
|
|
@ -3242,6 +3242,7 @@ void lim_process_switch_channel_rsp(struct mac_context *mac, void *body)
|
|||
break;
|
||||
|
||||
case LIM_SWITCH_CHANNEL_OPERATION:
|
||||
case LIM_SWITCH_CHANNEL_HT_WIDTH:
|
||||
/*
|
||||
* The above code should also use the callback.
|
||||
* mechanism below, there is scope for cleanup here.
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ enum eChannelChangeReasonCodes {
|
|||
LIM_SWITCH_CHANNEL_JOIN,
|
||||
LIM_SWITCH_CHANNEL_OPERATION, /* Generic change channel */
|
||||
LIM_SWITCH_CHANNEL_SAP_DFS, /* DFS channel change */
|
||||
LIM_SWITCH_CHANNEL_HT_WIDTH /* HT channel width change */
|
||||
};
|
||||
|
||||
typedef struct sLimAuthRspTimeout {
|
||||
|
|
|
|||
|
|
@ -1953,18 +1953,21 @@ lim_decide_sta_protection(struct mac_context *mac_ctx,
|
|||
*
|
||||
*
|
||||
***NOTE:
|
||||
* @param mac - Pointer to Global MAC structure
|
||||
* @param pe_session - Pointer to pe session
|
||||
* @return None
|
||||
*/
|
||||
static void __lim_process_channel_switch_timeout(struct mac_context *mac)
|
||||
static void __lim_process_channel_switch_timeout(struct pe_session *pe_session)
|
||||
{
|
||||
struct pe_session *pe_session = NULL;
|
||||
struct mac_context *mac;
|
||||
uint8_t channel; /* This is received and stored from channelSwitch Action frame */
|
||||
|
||||
pe_session = pe_find_session_by_session_id(mac,
|
||||
mac->lim.limTimers.gLimChannelSwitchTimer.sessionId);
|
||||
if (pe_session == NULL) {
|
||||
pe_err("Session Does not exist for given sessionID");
|
||||
if (!pe_session) {
|
||||
pe_err("Invalid pe session");
|
||||
return;
|
||||
}
|
||||
mac = pe_session->mac_ctx;
|
||||
if (!mac) {
|
||||
pe_err("Invalid mac context");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2072,18 +2075,24 @@ void lim_disconnect_complete(struct pe_session *session, bool del_bss)
|
|||
|
||||
void lim_process_channel_switch_timeout(struct mac_context *mac_ctx)
|
||||
{
|
||||
struct pe_session *session_entry = NULL;
|
||||
struct pe_session *session_entry;
|
||||
QDF_STATUS status;
|
||||
|
||||
session_entry = pe_find_session_by_session_id(
|
||||
mac_ctx,
|
||||
mac_ctx->lim.limTimers.gLimChannelSwitchTimer.sessionId);
|
||||
if (!session_entry) {
|
||||
pe_err("Session does not exist for given sessionID");
|
||||
return;
|
||||
}
|
||||
|
||||
session_entry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
|
||||
mlme_set_chan_switch_in_progress(session_entry->vdev, true);
|
||||
status = wlan_vdev_mlme_sm_deliver_evt(
|
||||
session_entry->vdev,
|
||||
WLAN_VDEV_SM_EV_FW_VDEV_RESTART,
|
||||
sizeof(*mac_ctx),
|
||||
mac_ctx);
|
||||
sizeof(*session_entry),
|
||||
session_entry);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("Failed to post WLAN_VDEV_SM_EV_FW_VDEV_RESTART for vdevid %d",
|
||||
session_entry->smeSessionId);
|
||||
|
|
@ -2103,9 +2112,19 @@ void lim_disconnect_complete(struct pe_session *session, bool del_bss)
|
|||
*
|
||||
* Return: none
|
||||
*/
|
||||
void lim_process_channel_switch_timeout(struct mac_context *mac)
|
||||
void lim_process_channel_switch_timeout(struct mac_context *mac_ctx)
|
||||
{
|
||||
__lim_process_channel_switch_timeout(mac);
|
||||
struct pe_session *session_entry;
|
||||
|
||||
session_entry = pe_find_session_by_session_id(
|
||||
mac_ctx,
|
||||
mac_ctx->lim.limTimers.gLimChannelSwitchTimer.sessionId);
|
||||
if (!session_entry) {
|
||||
pe_err("Session does not exist for given sessionID");
|
||||
return;
|
||||
}
|
||||
|
||||
__lim_process_channel_switch_timeout(session_entry);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3993,6 +4012,103 @@ QDF_STATUS lim_tx_complete(void *context, qdf_nbuf_t buf, bool free)
|
|||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VDEV_SM
|
||||
static void lim_ht_width_switch_cback(struct mac_context *mac,
|
||||
QDF_STATUS status, uint32_t *data,
|
||||
struct pe_session *pe_session)
|
||||
{
|
||||
pe_debug("status %d for ht width switch for vdev %d", status,
|
||||
pe_session->smeSessionId);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
lim_switch_channel_vdev_started(pe_session);
|
||||
}
|
||||
#else
|
||||
static void lim_ht_width_switch_cback(struct mac_context *mac,
|
||||
QDF_STATUS status, uint32_t *data,
|
||||
struct pe_session *pe_session)
|
||||
{
|
||||
pe_debug("status %d for ht width switch for vdev %d", status,
|
||||
pe_session->smeSessionId);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void lim_ht_switch_chnl_params(struct pe_session *pe_session)
|
||||
{
|
||||
uint8_t center_freq = 0;
|
||||
enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
|
||||
struct mac_context *mac;
|
||||
uint8_t primary_channel;
|
||||
|
||||
mac = pe_session->mac_ctx;
|
||||
if (!mac) {
|
||||
pe_err("Invalid mac_ctx");
|
||||
return;
|
||||
}
|
||||
|
||||
primary_channel = pe_session->gLimChannelSwitch.primaryChannel;
|
||||
if (eHT_CHANNEL_WIDTH_40MHZ ==
|
||||
pe_session->htRecommendedTxWidthSet) {
|
||||
ch_width = CH_WIDTH_40MHZ;
|
||||
if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
|
||||
pe_session->htSecondaryChannelOffset)
|
||||
center_freq = primary_channel + 2;
|
||||
else if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY ==
|
||||
pe_session->htSecondaryChannelOffset)
|
||||
center_freq = primary_channel - 2;
|
||||
else
|
||||
ch_width = CH_WIDTH_20MHZ;
|
||||
}
|
||||
|
||||
/* notify HAL */
|
||||
pe_debug("HT IE changed: Primary Channel: %d Secondary Channel Offset: %d Channel Width: %d",
|
||||
primary_channel, center_freq,
|
||||
pe_session->htRecommendedTxWidthSet);
|
||||
pe_session->channelChangeReasonCode =
|
||||
LIM_SWITCH_CHANNEL_HT_WIDTH;
|
||||
mac->lim.gpchangeChannelCallback = lim_ht_width_switch_cback;
|
||||
mac->lim.gpchangeChannelData = NULL;
|
||||
|
||||
lim_send_switch_chnl_params(mac, primary_channel,
|
||||
center_freq, 0, ch_width,
|
||||
pe_session->maxTxPower,
|
||||
pe_session->peSessionId,
|
||||
true, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VDEV_SM
|
||||
static void lim_ht_switch_chnl_req(struct pe_session *session)
|
||||
{
|
||||
struct mac_context *mac;
|
||||
QDF_STATUS status;
|
||||
|
||||
mac = session->mac_ctx;
|
||||
if (!mac) {
|
||||
pe_err("Invalid mac context");
|
||||
return;
|
||||
}
|
||||
|
||||
session->channelChangeReasonCode =
|
||||
LIM_SWITCH_CHANNEL_HT_WIDTH;
|
||||
mlme_set_chan_switch_in_progress(session->vdev, true);
|
||||
status = wlan_vdev_mlme_sm_deliver_evt(
|
||||
session->vdev,
|
||||
WLAN_VDEV_SM_EV_FW_VDEV_RESTART,
|
||||
sizeof(*session),
|
||||
session);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("Failed to post WLAN_VDEV_SM_EV_FW_VDEV_RESTART for vdevid %d",
|
||||
session->smeSessionId);
|
||||
mlme_set_chan_switch_in_progress(session->vdev, false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void lim_ht_switch_chnl_req(struct pe_session *session)
|
||||
{
|
||||
lim_ht_switch_chnl_params(session);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief This function updates lim global structure, if CB parameters in the BSS
|
||||
* have changed, and sends an indication to HAL also with the
|
||||
|
|
@ -4018,9 +4134,6 @@ void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac,
|
|||
uint8_t bssIdx,
|
||||
struct pe_session *pe_session)
|
||||
{
|
||||
uint8_t center_freq = 0;
|
||||
enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
|
||||
|
||||
/* If self capability is set to '20Mhz only', then do not change the CB mode. */
|
||||
if (!lim_get_ht_capability
|
||||
(mac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, pe_session))
|
||||
|
|
@ -4047,51 +4160,29 @@ void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac,
|
|||
return;
|
||||
}
|
||||
|
||||
/* If channel mismatch the CSA will take care of this change */
|
||||
if (pHTInfo->primaryChannel != pe_session->currentOperChannel) {
|
||||
pe_debug("Current channel doesnt match HT info ignore");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pe_session->htSecondaryChannelOffset !=
|
||||
(uint8_t) pHTInfo->secondaryChannelOffset
|
||||
|| pe_session->htRecommendedTxWidthSet !=
|
||||
(uint8_t) pHTInfo->recommendedTxWidthSet) {
|
||||
pe_session->gLimChannelSwitch.primaryChannel =
|
||||
pHTInfo->primaryChannel;
|
||||
pe_session->htSecondaryChannelOffset =
|
||||
(ePhyChanBondState) pHTInfo->secondaryChannelOffset;
|
||||
pe_session->htRecommendedTxWidthSet =
|
||||
(uint8_t) pHTInfo->recommendedTxWidthSet;
|
||||
if (eHT_CHANNEL_WIDTH_40MHZ ==
|
||||
pe_session->htRecommendedTxWidthSet) {
|
||||
ch_width = CH_WIDTH_40MHZ;
|
||||
if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
|
||||
pHTInfo->secondaryChannelOffset)
|
||||
center_freq = pHTInfo->primaryChannel + 2;
|
||||
else if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY ==
|
||||
pHTInfo->secondaryChannelOffset)
|
||||
center_freq = pHTInfo->primaryChannel - 2;
|
||||
else
|
||||
ch_width = CH_WIDTH_20MHZ;
|
||||
}
|
||||
|
||||
/* notify HAL */
|
||||
pe_debug("Channel Information in HT IE change"
|
||||
"d; sending notification to HAL.");
|
||||
pe_debug("Primary Channel: %d Secondary Chan"
|
||||
"nel Offset: %d Channel Width: %d",
|
||||
pHTInfo->primaryChannel, center_freq,
|
||||
pe_session->htRecommendedTxWidthSet);
|
||||
pe_session->channelChangeReasonCode =
|
||||
LIM_SWITCH_CHANNEL_OPERATION;
|
||||
mac->lim.gpchangeChannelCallback = NULL;
|
||||
mac->lim.gpchangeChannelData = NULL;
|
||||
|
||||
lim_send_switch_chnl_params(mac, (uint8_t) pHTInfo->primaryChannel,
|
||||
center_freq, 0, ch_width,
|
||||
pe_session->maxTxPower,
|
||||
pe_session->peSessionId,
|
||||
true, 0, 0);
|
||||
lim_ht_switch_chnl_req(pe_session);
|
||||
|
||||
/* In case of IBSS, if STA should update HT Info IE in its beacons. */
|
||||
if (LIM_IS_IBSS_ROLE(pe_session)) {
|
||||
if (LIM_IS_IBSS_ROLE(pe_session))
|
||||
sch_set_fixed_beacon_fields(mac, pe_session);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} /* End limUpdateStaRunTimeHTParams. */
|
||||
|
||||
/**
|
||||
|
|
@ -7981,6 +8072,13 @@ QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
|
|||
QDF_STATUS lim_sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
|
||||
uint16_t data_len, void *data)
|
||||
{
|
||||
struct pe_session *session;
|
||||
|
||||
session = (struct pe_session *)data;
|
||||
if (!session) {
|
||||
pe_err("Invalid session");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
if (!vdev_mlme) {
|
||||
pe_err("vdev_mlme is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
|
@ -7989,9 +8087,18 @@ QDF_STATUS lim_sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
|
|||
pe_err("event_data is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev))
|
||||
__lim_process_channel_switch_timeout((struct mac_context *)data);
|
||||
|
||||
if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev)) {
|
||||
switch (session->channelChangeReasonCode) {
|
||||
case LIM_SWITCH_CHANNEL_OPERATION:
|
||||
__lim_process_channel_switch_timeout(session);
|
||||
break;
|
||||
case LIM_SWITCH_CHANNEL_HT_WIDTH:
|
||||
lim_ht_switch_chnl_params(session);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue