summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhishek Singh <absingh@qti.qualcomm.com>2016-04-19 18:19:05 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-05-05 13:05:22 +0530
commitc0c5595ff2cd45682de97ff1ec57183f733412df (patch)
treea0be1a777ac245db3026a015212d7006c58b14e3
parentad730e07a674ca5f8dca1e047f52b01a77e1e852 (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.h6
-rw-r--r--CORE/HDD/inc/wlan_hdd_includes.h7
-rw-r--r--CORE/HDD/inc/wlan_hdd_oemdata.h8
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c53
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c7
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c1
-rw-r--r--CORE/HDD/src/wlan_hdd_oemdata.c99
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c1
-rw-r--r--CORE/SERVICES/WMA/wma.c17
-rw-r--r--CORE/SERVICES/WMA/wma.h3
-rw-r--r--CORE/VOSS/inc/vos_nvitem.h37
-rw-r--r--CORE/VOSS/src/vos_nvitem.c365
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