qcacld-2.0: Set wlan phy mode in OEM channel info response

Calculate and add wlan phy mode for each channel in OEM channel
info response.

Also send ANI_MSG_PEER_STATUS_IND indication for STA mode when
STA gets connected.

Change-Id: I91363e90698cabda72028135eb7fe9adeb1fbc86
CRs-Fixed: 1007004
This commit is contained in:
Abhishek Singh 2016-04-19 18:19:05 +05:30 committed by syphyr
parent 016c46eb01
commit fe1d26c502
12 changed files with 539 additions and 63 deletions

View File

@ -158,12 +158,6 @@ void hdd_PerformRoamSetKeyComplete(hdd_adapter_t *pAdapter);
VOS_STATUS hdd_roamDeregisterTDLSSTA(hdd_adapter_t *adapter, uint8_t staId);
void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac,
tANI_U8 peerStatus,
tANI_U8 peerTimingMeasCap,
tANI_U8 sessionId,
tSirSmeChanInfo *chan_info);
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
void hdd_indicateEseBcnReportNoResults(const hdd_adapter_t *pAdapter,
const tANI_U16 measurementToken,

View File

@ -63,11 +63,4 @@
#include "wlan_hdd_wext.h"
#include "wlan_hdd_main.h"
#include "wlan_hdd_tx_rx.h"
#ifdef FEATURE_OEM_DATA_SUPPORT
/*include for oem data req specific structures*/
/*and function declarations*/
#include "wlan_hdd_oemdata.h"
#endif
#endif // end #if !defined( HDD_INCLUDES_H__ )

View File

@ -27,6 +27,8 @@
#ifdef FEATURE_OEM_DATA_SUPPORT
#include "wlan_hdd_main.h"
/**===========================================================================
\file wlan_hdd_oemdata.h
@ -150,6 +152,12 @@ typedef PACKED_PRE struct PACKED_POST
tHddChannelInfo peer_chan_info;
} tPeerStatusInfo;
void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac,
uint8_t peerStatus,
uint8_t peerTimingMeasCap,
uint8_t sessionId,
tSirSmeChanInfo *chan_info,
device_mode_t dev_mode);
#endif //__WLAN_HDD_OEM_DATA_H__
#endif //FEATURE_OEM_DATA_SUPPORT

View File

@ -69,6 +69,7 @@
#include <wlan_hdd_ipa.h>
#endif
#include <vos_sched.h>
#include "wlan_hdd_oemdata.h"
struct ether_addr
{
@ -644,6 +645,7 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo
#endif
if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */
{
tSirSmeChanInfo chan_info;
if (!pCsrRoamInfo)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
@ -697,25 +699,25 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo
hdd_SendFTAssocResponse(dev, pAdapter, pCsrRoamInfo);
}
#endif
if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
{
tSirSmeChanInfo chan_info;
vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId,
sizeof(pHddStaCtx->conn_info.bssId));
chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
chan_info.info = pCsrRoamInfo->chan_info.info;
chan_info.band_center_freq1 = pCsrRoamInfo->chan_info.band_center_freq1;
chan_info.band_center_freq2 = pCsrRoamInfo->chan_info.band_center_freq2;
chan_info.reg_info_1 = pCsrRoamInfo->chan_info.reg_info_1;
chan_info.reg_info_2 = pCsrRoamInfo->chan_info.reg_info_2;
/* send peer status indication to oem app */
hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerConnected,
pCsrRoamInfo->timingMeasCap,
pAdapter->sessionId,
&chan_info);
}
vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId,
VOS_MAC_ADDR_SIZE);
chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
chan_info.info = pCsrRoamInfo->chan_info.info;
chan_info.band_center_freq1 =
pCsrRoamInfo->chan_info.band_center_freq1;
chan_info.band_center_freq2 =
pCsrRoamInfo->chan_info.band_center_freq2;
chan_info.reg_info_1 = pCsrRoamInfo->chan_info.reg_info_1;
chan_info.reg_info_2 = pCsrRoamInfo->chan_info.reg_info_2;
/* send peer status indication to oem app */
hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerConnected,
pCsrRoamInfo->timingMeasCap,
pAdapter->sessionId,
&chan_info,
pAdapter->device_mode);
#ifdef FEATURE_WLAN_TDLS
if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) {
@ -761,15 +763,16 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo
wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE);
#endif
if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
{
vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId,
if ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
(WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) {
vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId,
sizeof(pHddStaCtx->conn_info.bssId));
/* send peer status indication to oem app */
hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerDisconnected,
/* send peer status indication to oem app */
hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerDisconnected,
0, pAdapter->sessionId,
NULL);
NULL,
pAdapter->device_mode);
}
#ifdef WLAN_FEATURE_LPSS

View File

@ -94,6 +94,7 @@ extern int process_wma_set_command(int sessid, int paramid,
#include "wlan_hdd_cfg.h"
#include <wlan_hdd_wowl.h>
#include "wlan_hdd_tsf.h"
#include "wlan_hdd_oemdata.h"
#define IS_UP(_dev) \
(((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
@ -1923,7 +1924,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
ePeerConnected,
pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.timingMeasCap,
pHostapdAdapter->sessionId,
&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.chan_info);
&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.chan_info,
pHostapdAdapter->device_mode);
}
hdd_wlan_green_ap_add_sta(pHddCtx);
@ -2040,7 +2042,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
hdd_SendPeerStatusIndToOemApp(
&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
ePeerDisconnected, 0,
pHostapdAdapter->sessionId, NULL);
pHostapdAdapter->sessionId, NULL,
pHostapdAdapter->device_mode);
}
#ifdef FEATURE_BUS_BANDWIDTH

View File

@ -134,6 +134,7 @@ void hdd_ch_avoid_cb(void *hdd_context,void *indi_param);
#include "wlan_hdd_ocb.h"
#include "wlan_hdd_tsf.h"
#include "tl_shim.h"
#include "wlan_hdd_oemdata.h"
#if defined(LINUX_QCMBR)
#define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13)

View File

@ -47,6 +47,8 @@
#include "qwlan_version.h"
#include "vos_utils.h"
#include "wma.h"
#include "wlan_hdd_oemdata.h"
static struct hdd_context_s *pHddCtx;
@ -429,6 +431,55 @@ static eHalStatus oem_process_data_req_msg(int oemDataLen, char *oemData)
return status;
}
/**
* update_channel_bw_info() - set bandwidth info for the chan
* @hdd_ctx: hdd context
* @chan: channel for which info are required
* @hdd_chan_info: struct where the bandwidth info is filled
*
* This function find the maximum bandwidth allowed, secondary
* channel offset and center freq for the channel as per regulatory
* domain and using these info calculate the phy mode for the
* channel.
*
* Return: void
*/
static inline void hdd_update_channel_bw_info(hdd_context_t *hdd_ctx,
uint16_t chan, tHddChannelInfo *hdd_chan_info)
{
struct ch_params_s ch_params = {0};
uint16_t sec_ch_2g = 0;
uint8_t vht_capable;
WLAN_PHY_MODE phy_mode;
uint8_t dot11_mode = hdd_ctx->cfg_ini->dot11Mode;
vht_capable = IS_DOT11_MODE_VHT(dot11_mode);
if (chan <= SIR_11B_CHANNEL_END) {
if (chan <= 5)
sec_ch_2g = chan + 4;
else
sec_ch_2g = chan - 4;
if (!hdd_ctx->cfg_ini->enableVhtFor24GHzBand)
vht_capable = false;
}
/* Passing CH_WIDTH_MAX will give the max bandwidth supported */
ch_params.ch_width = CH_WIDTH_MAX;
vos_set_channel_params(chan, sec_ch_2g, &ch_params);
if (ch_params.center_freq_seg0)
hdd_chan_info->band_center_freq1 = ch_params.center_freq_seg0;
hddLog(LOG1,
FL("chan %d ch_width %d sec offset %d center_freq_seg0 %d"),
chan, ch_params.ch_width, ch_params.sec_ch_offset,
ch_params.center_freq_seg0);
phy_mode = wma_chan_to_mode(chan, ch_params.sec_ch_offset,
vht_capable, dot11_mode);
WMI_SET_CHANNEL_MODE(hdd_chan_info, phy_mode);
}
/**---------------------------------------------------------------------------
\brief oem_process_channel_info_req_msg() - process oem channel_info request
@ -519,6 +570,8 @@ static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList)
if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(chanId))
WMI_SET_CHANNEL_FLAG(&hddChanInfo, WMI_CHAN_FLAG_DFS);
hdd_update_channel_bw_info(pHddCtx, chanId, &hddChanInfo);
hddChanInfo.reg_info_1 = reg_info_1;
hddChanInfo.reg_info_2 = reg_info_2;
}
@ -553,27 +606,25 @@ static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList)
return 0;
}
/**---------------------------------------------------------------------------
\brief hdd_SendPeerStatusIndToOemApp()
This function sends peer status indication to registered oem application
\param -
- peerMac : MAC address of peer
- peerStatus : ePeerConnected or ePeerDisconnected
- peerTimingMeasCap : 0: RTT/RTT2, 1: RTT3. Default is 0
- sessionId : SME session id, i.e. vdev_id
- chanId: operating channel id
\return - None
--------------------------------------------------------------------------*/
/**
* hdd_SendPeerStatusIndToOemApp() - sends peer status indication to OEM
* @peerMac : MAC address of peer
* @peerStatus : ePeerConnected or ePeerDisconnected
* @peerTimingMeasCap : 0: RTT/RTT2, 1: RTT3. Default is 0
* @sessionId : SME session id, i.e. vdev_id
* @chanId: operating channel id
* @dev_mode: dev mode for which indication is sent
*
* This function sends peer status indication to registered oem application.
*
* Return: void
*/
void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac,
tANI_U8 peerStatus,
tANI_U8 peerTimingMeasCap,
tANI_U8 sessionId,
tSirSmeChanInfo *chan_info)
uint8_t peerStatus,
uint8_t peerTimingMeasCap,
uint8_t sessionId,
tSirSmeChanInfo *chan_info,
device_mode_t dev_mode)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
@ -626,6 +677,9 @@ void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac,
/* peerTimingMeasCap - bit mask for timing and fine timing Meas Cap */
pPeerInfo->peer_capability = peerTimingMeasCap;
pPeerInfo->reserved0 = 0;
/* Set 0th bit of reserved0 for STA mode */
if (WLAN_HDD_INFRA_STATION == dev_mode)
pPeerInfo->reserved0 |= 0x01;
if (chan_info) {
pPeerInfo->peer_chan_info.chan_id = chan_info->chan_id;
@ -655,7 +709,7 @@ void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac,
" status(%d), peerTimingMeasCap(%d), vdevId(%d), chanId(%d)"
" to oem app pid(%d), center freq 1 (%d), center freq 2 (%d),"
" info (0x%x), frequency (%d),reg info 1 (0x%x),"
" reg info 2 (0x%x)",__func__, MAC_ADDR_ARRAY(peerMac->bytes),
" reg info 2 (0x%x) reserved0 %d",__func__, MAC_ADDR_ARRAY(peerMac->bytes),
peerStatus, peerTimingMeasCap, sessionId,
pPeerInfo->peer_chan_info.chan_id, pHddCtx->oem_pid,
pPeerInfo->peer_chan_info.band_center_freq1,
@ -663,7 +717,8 @@ void hdd_SendPeerStatusIndToOemApp(v_MACADDR_t *peerMac,
pPeerInfo->peer_chan_info.info,
pPeerInfo->peer_chan_info.mhz,
pPeerInfo->peer_chan_info.reg_info_1,
pPeerInfo->peer_chan_info.reg_info_2);
pPeerInfo->peer_chan_info.reg_info_2,
pPeerInfo->reserved0);
(void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT);

View File

@ -110,6 +110,7 @@
#include "wlan_hdd_ocb.h"
#include "wlan_hdd_tsf.h"
#include "vos_nvitem.h"
#include "wlan_hdd_oemdata.h"
#define HDD_FINISH_ULA_TIME_OUT 800
#define HDD_SET_MCBC_FILTERS_TO_FW 1

View File

@ -11798,8 +11798,21 @@ VOS_STATUS wma_process_dhcp_ind(tp_wma_handle wma_handle,
return VOS_STATUS_SUCCESS;
}
static WLAN_PHY_MODE wma_chan_to_mode(u8 chan, ePhyChanBondState chan_offset,
u8 vht_capable, u8 dot11_mode)
/**
* wma_chan_to_mode() - calculate phy mode corresponding to channel
* @chan: channel
* @chan_offset: secondary channel offset
* @vht_capable: If vht capable
* @dot11_mode: dot11 mode
*
* calculate phy mode corresponding to channel, dot11 mode, vht capability
* and secondary channel offset.
*
* Return: WLAN_PHY_MODE
*/
WLAN_PHY_MODE wma_chan_to_mode(uint8_t chan, ePhyChanBondState chan_offset,
uint8_t vht_capable, uint8_t dot11_mode)
{
WLAN_PHY_MODE phymode = MODE_UNKNOWN;

View File

@ -1743,4 +1743,7 @@ void wma_stop_radar_delay_timer(void);
*/
void wma_ignore_radar_soon_after_assoc(void);
WLAN_PHY_MODE wma_chan_to_mode(uint8_t chan, ePhyChanBondState chan_offset,
uint8_t vht_capable, uint8_t dot11_mode);
#endif

View File

@ -103,9 +103,46 @@ struct chan_to_ht_40_index_map {
uint16 ht_40_plus_index;
};
/**
* enum phy_ch_width - physical layer channel width
* @CH_WIDTH_20MHZ: channel width 20 mhz
* @CH_WIDTH_40MHZ: channel width 40 mhz
* @CH_WIDTH_80MHZ: channel width 80 mhz
* @CH_WIDTH_5MHZ: channel width 5 mhz
* @CH_WIDTH_10MHZ: channel width 10 mhz
* @CH_WIDTH_INVALID: invalid channel width
* @CH_WIDTH_MAX: maximum channel width
*/
enum phy_ch_width {
CH_WIDTH_20MHZ = 0,
CH_WIDTH_40MHZ,
CH_WIDTH_80MHZ,
CH_WIDTH_5MHZ,
CH_WIDTH_10MHZ,
CH_WIDTH_INVALID,
CH_WIDTH_MAX
};
/**
* struct ch_params_s
* @ch_width: channel width
* @sec_ch_offset: secondary channel offset
* @center_freq_seg0: center freq for segment 0
* @center_freq_seg1: center freq for segment 1
*/
struct ch_params_s {
enum phy_ch_width ch_width;
uint8_t sec_ch_offset;
uint32_t center_freq_seg0;
uint32_t center_freq_seg1;
};
// country code type
typedef v_U8_t v_COUNTRYCODE_t[VOS_COUNTRY_CODE_LEN];
void vos_set_channel_params(uint16_t oper_ch, uint16_t sec_ch_2g,
struct ch_params_s *ch_params);
/**------------------------------------------------------------------------
\brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of

View File

@ -118,6 +118,48 @@ static v_BOOL_t init_by_reg_core = VOS_FALSE;
#define WORLD_SKU_MASK 0x00F0
#define WORLD_SKU_PREFIX 0x0060
/**
* struct bonded_chan
* @start_ch: start channel
* @end_ch: end channel
*/
struct bonded_chan {
uint16_t start_ch;
uint16_t end_ch;
};
static const struct bonded_chan bonded_chan_40mhz_array[] = {
{36, 40},
{44, 48},
{52, 56},
{60, 64},
{100, 104},
{108, 112},
{116, 120},
{124, 128},
{132, 136},
{140, 144},
{149, 153},
{157, 161}
};
static const struct bonded_chan bonded_chan_80mhz_array[] = {
{36, 48},
{52, 64},
{100, 112},
{116, 128},
{132, 144},
{149, 161}
};
static const enum phy_ch_width next_lower_bw[] = {
[CH_WIDTH_80MHZ] = CH_WIDTH_40MHZ,
[CH_WIDTH_40MHZ] = CH_WIDTH_20MHZ,
[CH_WIDTH_20MHZ] = CH_WIDTH_10MHZ,
[CH_WIDTH_10MHZ] = CH_WIDTH_5MHZ,
[CH_WIDTH_5MHZ] = CH_WIDTH_INVALID
};
static const struct ieee80211_regdomain vos_world_regdom_60_61_62 = {
.n_reg_rules = 6,
.alpha2 = "00",
@ -494,6 +536,13 @@ const tRfChannelProps rfChannels[NUM_RF_CHANNELS] =
{ 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
};
#define VOS_IS_CHANNEL_5GHZ(chan_num) \
((chan_num >= rfChannels[RF_CHAN_36].channelNum) && \
(chan_num <= rfChannels[RF_CHAN_184].channelNum))
#define VOS_IS_CHANNEL_24GHZ(chan_num) \
((chan_num >= rfChannels[RF_CHAN_1].channelNum) && \
(chan_num <= rfChannels[RF_CHAN_14].channelNum))
extern const sHalNv nvDefaults;
const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels;
@ -707,6 +756,322 @@ VOS_STATUS vos_nv_close(void)
return VOS_STATUS_SUCCESS;
}
/**
* vos_search_5g_bonded_chan_array() - get ptr to bonded channel
* @oper_ch: operating channel number
* @bonded_chan_ar: bonded channel array
* @bonded_chan_ptr_ptr: bonded channel ptr ptr
*
* Return: eNVChannelEnabledType
*/
static eNVChannelEnabledType vos_search_5g_bonded_chan_array(
uint32_t oper_chan, const struct bonded_chan bonded_chan_ar[],
uint16_t array_size, const struct bonded_chan
**bonded_chan_ptr_ptr)
{
int i;
uint8_t chan_num;
const struct bonded_chan *bonded_chan_ptr = NULL;
eNVChannelEnabledType chan_state = NV_CHANNEL_INVALID;
eNVChannelEnabledType temp_chan_state;
for (i = 0; i < array_size; i++) {
if ((oper_chan >= bonded_chan_ar[i].start_ch) &&
(oper_chan <= bonded_chan_ar[i].end_ch)) {
bonded_chan_ptr = &(bonded_chan_ar[i]);
break;
}
}
if (NULL == bonded_chan_ptr)
return chan_state;
*bonded_chan_ptr_ptr = bonded_chan_ptr;
chan_num = bonded_chan_ptr->start_ch;
while (chan_num <= bonded_chan_ptr->end_ch) {
temp_chan_state = vos_nv_getChannelEnabledState(chan_num);
if (temp_chan_state < chan_state)
chan_state = temp_chan_state;
chan_num = chan_num + 4;
}
return chan_state;
}
/**
* vos_search_5g_bonded_channel() - get the 5G bonded channel state
* @chan_num: channel number
* @ch_width: channel width
* @bonded_chan_ptr_ptr: bonded channel ptr ptr
*
* Return: channel state
*/
static eNVChannelEnabledType vos_search_5g_bonded_channel(uint32_t chan_num,
enum phy_ch_width ch_width,
const struct bonded_chan
**bonded_chan_ptr_ptr)
{
if (CH_WIDTH_80MHZ == ch_width)
return vos_search_5g_bonded_chan_array(chan_num,
bonded_chan_80mhz_array,
ARRAY_SIZE(bonded_chan_80mhz_array),
bonded_chan_ptr_ptr);
else if (CH_WIDTH_40MHZ == ch_width)
return vos_search_5g_bonded_chan_array(chan_num,
bonded_chan_40mhz_array,
ARRAY_SIZE(bonded_chan_40mhz_array),
bonded_chan_ptr_ptr);
else
return vos_nv_getChannelEnabledState(chan_num);
}
/**
* vos_get_5g_bonded_channel_state() - get the 5G bonded channel state
* @chan_num: channel number
* @ch_width: channel width
*
* Return: channel state
*/
eNVChannelEnabledType vos_get_5g_bonded_channel_state(
uint16_t chan_num,
enum phy_ch_width ch_width,
const struct bonded_chan *bonded_chan_ptr)
{
bool bw_enabled = false;
uint32_t flags;
if (CH_WIDTH_80MHZ < ch_width)
return NV_CHANNEL_INVALID;
flags = vos_nv_get_channel_flags(chan_num);
if (CH_WIDTH_5MHZ == ch_width) {
bw_enabled = true;
} else if (CH_WIDTH_10MHZ == ch_width) {
bw_enabled = !(flags &
IEEE80211_CHAN_NO_10MHZ);
} else if (CH_WIDTH_20MHZ == ch_width) {
bw_enabled = !(flags &
IEEE80211_CHAN_NO_20MHZ);
} else if (CH_WIDTH_40MHZ == ch_width) {
if (chan_num == bonded_chan_ptr->start_ch)
bw_enabled =
!(flags & IEEE80211_CHAN_NO_HT40PLUS);
else
bw_enabled =
!(flags & IEEE80211_CHAN_NO_HT40MINUS);
} else if (CH_WIDTH_80MHZ == ch_width) {
bw_enabled = !(flags &
IEEE80211_CHAN_NO_80MHZ);
}
if (bw_enabled)
return NV_CHANNEL_ENABLE;
else
return NV_CHANNEL_DISABLE;
}
/**
* vos_set_sec_chan_offset_vht80() - set sec channel offset for vht80
* @oper_ch: operating channel
* @center_chan: center channel for operating channel
* @ch_params: channel parameters
*
* Return: void
*/
static inline void vos_set_sec_chan_offset_vht80(uint16_t oper_ch,
uint16_t center_chan, struct ch_params_s *ch_params)
{
if ((oper_ch + 2 ) == center_chan)
ch_params->sec_ch_offset =
PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
else if ((oper_ch + 6 ) == center_chan)
ch_params->sec_ch_offset =
PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
else if ((oper_ch - 2 ) == center_chan)
ch_params->sec_ch_offset =
PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
else if ((oper_ch - 6 ) == center_chan)
ch_params->sec_ch_offset =
PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
}
/**
* vos_set_5g_channel_params() - set the 5G bonded channel parameters
* @oper_ch: operating channel
* @ch_params: channel parameters
*
* Return: void
*/
static void vos_set_5g_channel_params(uint16_t oper_ch,
struct ch_params_s *ch_params)
{
eNVChannelEnabledType chan_state = NV_CHANNEL_ENABLE;
const struct bonded_chan *bonded_chan_ptr;
uint16_t center_chan;
if (CH_WIDTH_MAX <= ch_params->ch_width)
ch_params->ch_width = CH_WIDTH_80MHZ;
while (ch_params->ch_width < CH_WIDTH_INVALID) {
chan_state = vos_search_5g_bonded_channel(oper_ch,
ch_params->ch_width, &bonded_chan_ptr);
if (((NV_CHANNEL_ENABLE != chan_state) &&
(NV_CHANNEL_DFS != chan_state)))
goto next;
chan_state = vos_get_5g_bonded_channel_state(oper_ch,
ch_params->ch_width, bonded_chan_ptr);
if (((NV_CHANNEL_ENABLE != chan_state) &&
(NV_CHANNEL_DFS != chan_state)))
goto next;
if (CH_WIDTH_20MHZ >= ch_params->ch_width) {
ch_params->sec_ch_offset
= PHY_SINGLE_CHANNEL_CENTERED;
break;
} else if (CH_WIDTH_40MHZ == ch_params->ch_width) {
if (oper_ch == bonded_chan_ptr->start_ch)
ch_params->sec_ch_offset =
PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
else
ch_params->sec_ch_offset =
PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
}
center_chan = (bonded_chan_ptr->start_ch +
bonded_chan_ptr->end_ch) / 2;
ch_params->center_freq_seg0 =
vos_chan_to_freq(center_chan);
if (CH_WIDTH_80MHZ == ch_params->ch_width)
vos_set_sec_chan_offset_vht80(oper_ch,
center_chan, ch_params);
break;
next:
ch_params->ch_width = next_lower_bw[ch_params->ch_width];
}
}
/**
* vos_get_2g_bonded_channel_state() - get the 2G bonded channel state
* @oper_ch: operating channel
* @ch_width: channel width
* @sec_ch: secondary channel
*
* Return: channel state
*/
eNVChannelEnabledType vos_get_2g_bonded_channel_state(uint16_t oper_ch,
enum phy_ch_width ch_width,
uint16_t sec_ch)
{
eNVChannelEnabledType chan_state;
bool bw_enabled = false;
uint32_t flags;
bool ht_40_plus = false;
if (CH_WIDTH_40MHZ < ch_width)
return NV_CHANNEL_INVALID;
if (CH_WIDTH_40MHZ == ch_width) {
if ((sec_ch + 4 != oper_ch) &&
(oper_ch + 4 != sec_ch))
return NV_CHANNEL_INVALID;
ht_40_plus = (oper_ch < sec_ch)? true : false;
}
chan_state = vos_nv_getChannelEnabledState(oper_ch);
if ((NV_CHANNEL_INVALID == chan_state) ||
(NV_CHANNEL_DISABLE == chan_state))
return chan_state;
flags = vos_nv_get_channel_flags(oper_ch);
if (CH_WIDTH_5MHZ == ch_width) {
bw_enabled = true;
} else if (CH_WIDTH_10MHZ == ch_width) {
bw_enabled = !(flags &
IEEE80211_CHAN_NO_10MHZ);
} else if (CH_WIDTH_20MHZ == ch_width) {
bw_enabled = !(flags &
IEEE80211_CHAN_NO_20MHZ);
} else if (CH_WIDTH_40MHZ == ch_width) {
if (ht_40_plus)
bw_enabled =
!(flags & IEEE80211_CHAN_NO_HT40PLUS);
else
bw_enabled =
!(flags & IEEE80211_CHAN_NO_HT40MINUS);
}
if (bw_enabled)
return chan_state;
else
return NV_CHANNEL_DISABLE;
}
/**
* vos_set_2g_channel_params() - set the 2.4G bonded channel parameters
* @oper_ch: operating channel
* @ch_params: channel parameters
* @sec_ch_2g: 2.4G secondary channel
*
* Return: void
*/
static void vos_set_2g_channel_params(uint16_t oper_ch,
struct ch_params_s *ch_params,
uint16_t sec_ch_2g)
{
eNVChannelEnabledType chan_state = NV_CHANNEL_ENABLE;
if (CH_WIDTH_MAX <= ch_params->ch_width)
ch_params->ch_width = CH_WIDTH_40MHZ;
while (ch_params->ch_width < CH_WIDTH_INVALID) {
chan_state = vos_get_2g_bonded_channel_state(oper_ch,
ch_params->ch_width,
sec_ch_2g);
if (NV_CHANNEL_ENABLE == chan_state) {
if (CH_WIDTH_40MHZ == ch_params->ch_width) {
if (oper_ch < sec_ch_2g)
ch_params->sec_ch_offset =
PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
else
ch_params->sec_ch_offset =
PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
ch_params->center_freq_seg0 =
vos_chan_to_freq(
(oper_ch + sec_ch_2g) / 2);
} else {
ch_params->sec_ch_offset =
PHY_SINGLE_CHANNEL_CENTERED;
}
break;
}
ch_params->ch_width = next_lower_bw[ch_params->ch_width];
}
}
/**
* vos_set_channel_params() - set the bonded channel parameters
* @oper_ch: operating channel
* @sec_ch_2g: 2.4G secondary channel
* @ch_params: chanel parameters
*
* Return: void
*/
void vos_set_channel_params(uint16_t oper_ch, uint16_t sec_ch_2g,
struct ch_params_s *ch_params)
{
if (VOS_IS_CHANNEL_5GHZ(oper_ch))
vos_set_5g_channel_params(oper_ch, ch_params);
else if (VOS_IS_CHANNEL_24GHZ(oper_ch))
vos_set_2g_channel_params(oper_ch, ch_params, sec_ch_2g);
}
/**------------------------------------------------------------------------
\brief vos_nv_getSupportedCountryCode() - get the list of supported
country codes