diff options
| author | Abhishek Singh <absingh@qti.qualcomm.com> | 2016-04-19 18:19:05 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-05-05 13:05:22 +0530 |
| commit | c0c5595ff2cd45682de97ff1ec57183f733412df (patch) | |
| tree | a0be1a777ac245db3026a015212d7006c58b14e3 | |
| parent | ad730e07a674ca5f8dca1e047f52b01a77e1e852 (diff) | |
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
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_assoc.h | 6 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_includes.h | 7 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_oemdata.h | 8 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 53 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_hostapd.c | 7 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 1 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_oemdata.c | 99 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 1 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 17 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.h | 3 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_nvitem.h | 37 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_nvitem.c | 365 |
12 files changed, 540 insertions, 64 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h index 26feb4442270..3f91faff1a97 100644 --- a/CORE/HDD/inc/wlan_hdd_assoc.h +++ b/CORE/HDD/inc/wlan_hdd_assoc.h @@ -163,12 +163,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, diff --git a/CORE/HDD/inc/wlan_hdd_includes.h b/CORE/HDD/inc/wlan_hdd_includes.h index 239e7920b911..d38ab67ab7a5 100644 --- a/CORE/HDD/inc/wlan_hdd_includes.h +++ b/CORE/HDD/inc/wlan_hdd_includes.h @@ -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__ ) diff --git a/CORE/HDD/inc/wlan_hdd_oemdata.h b/CORE/HDD/inc/wlan_hdd_oemdata.h index 8822ccebbff4..296b0d13b0cb 100644 --- a/CORE/HDD/inc/wlan_hdd_oemdata.h +++ b/CORE/HDD/inc/wlan_hdd_oemdata.h @@ -27,6 +27,8 @@ #ifdef FEATURE_OEM_DATA_SUPPORT +#include "wlan_hdd_main.h" + /**=========================================================================== \file wlan_hdd_oemdata.h @@ -178,6 +180,12 @@ struct oem_get_capability_rsp { struct sme_oem_capability cap; }; +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 diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 3cbb4fad133e..7443c2660928 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -71,6 +71,7 @@ #include <vos_sched.h> #include <wlan_logging_sock_svc.h> #include "tl_shim.h" +#include "wlan_hdd_oemdata.h" struct ether_addr { @@ -706,6 +707,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, @@ -759,25 +761,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) { @@ -825,15 +827,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 diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index f9209e8ddeaf..e004de69be22 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -96,6 +96,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)) @@ -1879,7 +1880,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); @@ -1996,7 +1998,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 diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 6e91219a29cd..e7f487671a0c 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -133,6 +133,7 @@ extern int hdd_hostapd_stop (struct net_device *dev); #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) diff --git a/CORE/HDD/src/wlan_hdd_oemdata.c b/CORE/HDD/src/wlan_hdd_oemdata.c index 0dde745ec8d2..b1ac539c23b9 100644 --- a/CORE/HDD/src/wlan_hdd_oemdata.c +++ b/CORE/HDD/src/wlan_hdd_oemdata.c @@ -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; /** @@ -449,6 +451,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 @@ -539,6 +590,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; } @@ -700,27 +753,25 @@ static int oem_process_get_cap_req_msg(void) 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; @@ -773,6 +824,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; @@ -802,7 +856,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, @@ -810,7 +864,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); diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c index f114a7ae5c20..7a6657834214 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -111,6 +111,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 diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 6f7688a11752..10a87b648316 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -11921,8 +11921,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; diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 65d3188fffcb..e6c2ff4a96b7 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -1801,4 +1801,7 @@ VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, ol_txrx_vdev_handle vdev, u8 peer_addr[6], u_int32_t peer_type, u_int8_t vdev_id, v_BOOL_t roam_synch_in_progress); +WLAN_PHY_MODE wma_chan_to_mode(uint8_t chan, ePhyChanBondState chan_offset, + uint8_t vht_capable, uint8_t dot11_mode); + #endif diff --git a/CORE/VOSS/inc/vos_nvitem.h b/CORE/VOSS/inc/vos_nvitem.h index 4709482918cf..9acc1d040a08 100644 --- a/CORE/VOSS/inc/vos_nvitem.h +++ b/CORE/VOSS/inc/vos_nvitem.h @@ -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 diff --git a/CORE/VOSS/src/vos_nvitem.c b/CORE/VOSS/src/vos_nvitem.c index 493b1397eb1e..82afaeb14140 100644 --- a/CORE/VOSS/src/vos_nvitem.c +++ b/CORE/VOSS/src/vos_nvitem.c @@ -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 |
