summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-12-11 15:05:01 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2014-12-11 15:05:01 -0800
commitac9f925d6b033e37c430b9896569bd3299c2b796 (patch)
tree64cfd054689ff703005c24c72d37d27309349076
parenta8be39019d38606527fc70c976ec2dd648eb6411 (diff)
parent86ec3899544f873b3b18d38c2bd9a0a9a1925ad1 (diff)
Merge "Release 1.0.0.254 QCACLD WLAN Driver"
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c48
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_rx.c7
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_rx_reorder.c8
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_tx_classify.c3
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx.c39
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx_types.h2
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h14
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h39
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h6
-rw-r--r--CORE/HDD/inc/wlan_hdd_tx_rx.h4
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c11
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c243
-rwxr-xr-xCORE/HDD/src/wlan_hdd_main.c112
-rw-r--r--CORE/HDD/src/wlan_hdd_tx_rx.c38
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c397
-rw-r--r--CORE/MAC/inc/aniGlobal.h4
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/MAC/inc/sirApi.h47
-rw-r--r--CORE/MAC/src/include/sirParams.h2
-rw-r--r--CORE/SAP/src/sapChSelect.c4
-rw-r--r--CORE/SERVICES/COMMON/dbglog_id.h10
-rw-r--r--CORE/SERVICES/COMMON/ol_htt_api.h5
-rw-r--r--CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h18
-rw-r--r--CORE/SERVICES/COMMON/wdi_in.h5
-rw-r--r--CORE/SERVICES/COMMON/wmi_services.h1
-rw-r--r--CORE/SERVICES/COMMON/wmi_tlv_defs.h19
-rw-r--r--CORE/SERVICES/COMMON/wmi_unified.h64
-rw-r--r--CORE/SERVICES/WMA/wma.c239
-rw-r--r--CORE/SERVICES/WMA/wma.h13
-rw-r--r--CORE/SERVICES/WMI/wmi_unified.c1
-rw-r--r--CORE/SME/inc/csrApi.h2
-rw-r--r--CORE/SME/inc/sme_Api.h18
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c32
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c37
-rw-r--r--CORE/TL/inc/wlan_qct_tl.h28
-rw-r--r--CORE/VOSS/inc/vos_types.h1
-rw-r--r--CORE/VOSS/src/vos_api.c3
-rw-r--r--CORE/WDA/inc/wlan_qct_wda.h2
38 files changed, 1473 insertions, 57 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index 5da9cba8d39c..b20a57a1057f 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -2524,3 +2524,51 @@ void WLANTL_RegisterOPCbFnc(void *vos_ctx,
}
#endif /* IPA_UC_OFFLOAD */
+/*=============================================================================
+ FUNCTION WLANTL_RegisterOCBPeer
+
+ DESCRIPTION
+ Function to register the OCB Self Peer
+
+ PARAMETERS
+ IN
+ vos_ctx : Global OS context context
+ mac_addr : MAC address of self peer
+
+ OUT
+ peer_id : Peer ID
+
+ RETURN VALUE
+ VOS_STATUS_SUCCESS on success
+ VOS_STATUS_E_FAILURE on failure
+
+ SIDE EFFECTS
+
+==============================================================================*/
+VOS_STATUS WLANTL_RegisterOCBPeer(void *vos_ctx, uint8_t *mac_addr,
+ uint8_t *peer_id)
+{
+ ol_txrx_pdev_handle pdev;
+ ol_txrx_peer_handle peer;
+
+ pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_ctx);
+ if (!pdev) {
+ TLSHIM_LOGE("%s: Unable to find pdev!", __func__);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ peer = ol_txrx_find_peer_by_addr(pdev, mac_addr, peer_id);
+ if (!peer) {
+ TLSHIM_LOGE("%s: Unable to find OCB peer!", __func__);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ ol_txrx_set_ocb_peer(pdev, peer);
+
+ /* Set peer state to connected */
+ ol_txrx_peer_state_update(pdev, peer->mac_addr.raw,
+ ol_txrx_peer_state_auth);
+
+ return VOS_STATUS_SUCCESS;
+}
+
diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c
index fe1fe504dccf..f07e41aa0965 100644
--- a/CORE/CLD_TXRX/TXRX/ol_rx.c
+++ b/CORE/CLD_TXRX/TXRX/ol_rx.c
@@ -216,6 +216,13 @@ ol_rx_indication_handler(
htt_pdev = pdev->htt_pdev;
peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+ if (!peer) {
+ /* If we can't find a peer send this packet to OCB interface using
+ OCB self peer */
+ if (!ol_txrx_get_ocb_peer(pdev, &peer))
+ peer = NULL;
+ }
+
if (peer) {
vdev = peer->vdev;
OL_RX_IND_RSSI_UPDATE(peer, rx_ind_msg);
diff --git a/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c b/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c
index f5da6d44d47e..878dd064b9ed 100644
--- a/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c
+++ b/CORE/CLD_TXRX/TXRX/ol_rx_reorder.c
@@ -539,6 +539,14 @@ ol_rx_pn_ind_handler(
int seq_num, i=0;
peer = ol_txrx_peer_find_by_id(pdev, peer_id);
+
+ if (!peer) {
+ /* If we can't find a peer send this packet to OCB interface using
+ OCB self peer */
+ if (!ol_txrx_get_ocb_peer(pdev, &peer))
+ peer = NULL;
+ }
+
if (peer) {
vdev = peer->vdev;
} else {
diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_classify.c b/CORE/CLD_TXRX/TXRX/ol_tx_classify.c
index 2d8c75249ae5..0c523d90d42b 100644
--- a/CORE/CLD_TXRX/TXRX/ol_tx_classify.c
+++ b/CORE/CLD_TXRX/TXRX/ol_tx_classify.c
@@ -321,7 +321,8 @@ ol_tx_classify(
TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf);
- if (IEEE80211_IS_MULTICAST(dest_addr)) {
+ if ((IEEE80211_IS_MULTICAST(dest_addr))
+ || (vdev->opmode == wlan_op_mode_ocb)) {
txq = &vdev->txqs[OL_TX_VDEV_MCAST_BCAST];
tx_msdu_info->htt.info.ext_tid = HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST;
if (vdev->opmode == wlan_op_mode_sta) {
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c
index 227a40498147..3074edbd9d79 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx.c
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c
@@ -2172,6 +2172,45 @@ ol_txrx_ll_set_tx_pause_q_depth(
}
#endif /* QCA_LL_TX_FLOW_CT */
+/**
+ * @brief Setter function to store OCB Peer.
+ */
+void ol_txrx_set_ocb_peer(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer)
+{
+ if (pdev == NULL) {
+ return;
+ }
+
+ pdev->ocb_peer = peer;
+ pdev->ocb_peer_valid = (NULL != peer);
+}
+
+/**
+ * @brief Getter function to retrieve OCB peer.
+ * @details
+ * Returns A_TRUE if ocb_peer is valid
+ * Otherwise, returns A_FALSE
+ */
+a_bool_t ol_txrx_get_ocb_peer(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t **peer)
+{
+ int rc;
+
+ if ((pdev == NULL) || (peer == NULL)) {
+ rc = A_FALSE;
+ goto exit;
+ }
+
+ if (pdev->ocb_peer_valid) {
+ *peer = pdev->ocb_peer;
+ rc = A_TRUE;
+ } else {
+ rc = A_FALSE;
+ }
+
+exit:
+ return rc;
+}
+
#ifdef IPA_UC_OFFLOAD
void
ol_txrx_ipa_uc_get_resource(
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
index 94967c62901f..e1362eb04fdb 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
@@ -714,6 +714,8 @@ struct ol_txrx_pdev_t {
void *osif_dev;
#endif /* IPA_UC_OFFLOAD */
struct ol_tx_queue_group_t txq_grps[OL_TX_MAX_TXQ_GROUPS];
+ u_int8_t ocb_peer_valid;
+ struct ol_txrx_peer_t *ocb_peer;
};
struct ol_txrx_vdev_t {
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 0cb804d64cdf..7cf14541f523 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -2703,6 +2703,17 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_SAP_AUTH_OFL_KEY_DEFAULT ""
#endif /* SAP_AUTH_OFFLOAD */
+enum dot11p_mode {
+ WLAN_HDD_11P_DISABLED = 0,
+ WLAN_HDD_11P_STANDALONE,
+ WLAN_HDD_11P_CONCURRENT,
+};
+
+#define CFG_DOT11P_MODE_NAME "gDot11PMode"
+#define CFG_DOT11P_MODE_DEFAULT ( WLAN_HDD_11P_DISABLED )
+#define CFG_DOT11P_MODE_MIN ( WLAN_HDD_11P_DISABLED )
+#define CFG_DOT11P_MODE_MAX ( WLAN_HDD_11P_CONCURRENT )
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -3260,6 +3271,7 @@ typedef struct
uint32_t dhcp_client_start_ip;
v_U8_t dhcpServerIP[IPADDR_STRING_LENGTH];
#endif /* DHCP_SERVER_OFFLOAD */
+
bool enable_mac_spoofing;
#ifdef IPA_UC_STA_OFFLOAD
bool ipa_uc_sta_offload;
@@ -3289,6 +3301,8 @@ typedef struct
uint32_t sap_auth_offload_sec_type;
uint8_t sap_auth_offload_key[WLAN_PSK_STRING_LENGTH];
#endif /* SAP_AUTH_OFFLOAD */
+
+ uint8_t dot11p_mode;
} hdd_config_t;
#ifdef WLAN_FEATURE_MBSSID
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 5c9808f8723d..eb7adad18a17 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -176,6 +176,9 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42,
QCA_NL80211_VENDOR_SUBCMD_APFIND = 52,
+ /* OCB Set Schedule */
+ QCA_NL80211_VENDOR_SUBCMD_OCB_SET_SCHED = 53,
+
QCA_NL80211_VENDOR_SUBCMD_DO_ACS = 54,
};
@@ -854,6 +857,42 @@ enum qca_wlan_vendor_attr_get_concurrency_matrix {
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_AFTER_LAST - 1,
};
+/* OCB Commands */
+enum qca_wlan_vendor_attr_ocb_set_sched
+{
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_INVALID = 0,
+
+ /* Number of channels in schedule */
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_NUM_CHANS,
+
+ /* Attribute for nested array of channel attributes */
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN,
+
+ /* Attributes for each channel */
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_IDX,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_FREQ,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_PWR,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_RATE,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_DUR,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_START_GUARD_INT,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_END_GUARD_INT,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_NUM_QOS,
+
+ /* Attribute for nested array of QoS params*/
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM,
+
+ /* Attributes for each QoS Access Category */
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AC,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AIFSN,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMIN,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMAX,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX =
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_AFTER_LAST - 1,
+};
+
/* Feature defines */
#define WIFI_FEATURE_INFRA 0x0001 /* Basic infrastructure mode */
#define WIFI_FEATURE_INFRA_5G 0x0002 /* Support for 5 GHz Band */
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 68ece7964842..955c89abd309 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -517,7 +517,8 @@ typedef enum device_mode
WLAN_HDD_MONITOR,
WLAN_HDD_FTM,
WLAN_HDD_IBSS,
- WLAN_HDD_P2P_DEVICE
+ WLAN_HDD_P2P_DEVICE,
+ WLAN_HDD_OCB
}device_mode_t;
typedef enum rem_on_channel_request_type
@@ -1095,6 +1096,9 @@ struct hdd_adapter_s
/* variable for temperature in Celsius */
int temperature;
+
+ /* 802.11p */
+ struct completion hdd_ocb_set_sched_req_var;
};
#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h
index ae2a9e8d54cd..7f65dc9851e4 100644
--- a/CORE/HDD/inc/wlan_hdd_tx_rx.h
+++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h
@@ -75,6 +75,10 @@
#define SME_QOS_UAPSD_CFG_VI_CHANGED_MASK 0xF4
#define SME_QOS_UAPSD_CFG_VO_CHANGED_MASK 0xF8
+#define HDD_ETH_HEADER_LEN 14
+#define HDD_OCB_TX_HEADER_LEN 16
+#define HDD_ETHERTYPE_OCB_TX 0x8151
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 680097c1ef4e..5695fddb43a4 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -3515,6 +3515,13 @@ REG_TABLE_ENTRY g_registry_table[] =
VAR_FLAGS_OPTIONAL,
(void *) CFG_SAP_AUTH_OFL_KEY_DEFAULT ),
#endif /* SAP_AUTH_OFFLOAD */
+
+ REG_VARIABLE(CFG_DOT11P_MODE_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, dot11p_mode,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_DOT11P_MODE_DEFAULT,
+ CFG_DOT11P_MODE_MIN,
+ CFG_DOT11P_MODE_MAX),
};
#ifdef WLAN_FEATURE_MBSSID
@@ -5960,6 +5967,10 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
smeConfig->csrConfig.is_sta_connection_in_5gz_enabled =
pHddCtx->cfg_ini->is_sta_connection_in_5gz_enabled;
+ /* Update 802.11p config */
+ smeConfig->csrConfig.enable_dot11p = (pHddCtx->cfg_ini->dot11p_mode !=
+ WLAN_HDD_11P_DISABLED);
+
halStatus = sme_UpdateConfig( pHddCtx->hHal, smeConfig);
if ( !HAL_STATUS_SUCCESS( halStatus ) )
{
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 16aba7134411..63a35cda5ae9 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -4622,6 +4622,241 @@ out:
}
#endif
+static const struct
+nla_policy
+qca_wlan_vendor_ocb_set_sched_policy[
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX + 1] =
+{
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_NUM_CHANS] =
+ { .type = NLA_U32 },
+
+ /* Attributes for each channel */
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_IDX] =
+ { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_FREQ] =
+ { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_PWR] =
+ { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_RATE] =
+ { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_DUR] =
+ { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_START_GUARD_INT] =
+ { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_END_GUARD_INT] =
+ { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_NUM_QOS] =
+ { .type = NLA_U32 },
+
+ /* Attributes for QoS Params */
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AC] =
+ { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AIFSN] =
+ { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMIN] =
+ { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMAX] =
+ { .type = NLA_U8 },
+};
+
+static int wlan_hdd_cfg80211_ocb_set_schedule(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX + 1];
+ struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX + 1];
+ struct nlattr *qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX + 1];
+ struct nlattr *channels;
+ struct nlattr *qos_params;
+ int status;
+ sir_ocb_set_sched_request_t *sched_req = NULL;
+ sir_ocb_sched_t *sched = NULL;
+ int rem1, rem2;
+ int chan_idx;
+ int ac;
+ int rc = -EINVAL;
+
+ status = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != status) {
+ hddLog(LOGE, FL("HDD context is not valid"));
+ return -EINVAL;
+ }
+
+ if (adapter->device_mode != WLAN_HDD_OCB) {
+ hddLog(LOGE, FL("Device not in OCB mode!"));
+ return -EINVAL;
+ }
+
+ /* Parse the netlink message */
+ if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX,
+ data,
+ data_len, qca_wlan_vendor_ocb_set_sched_policy)) {
+ hddLog(LOGE, FL("OCB_SET_SCHEDULE_MAX is not present"));
+ return -EINVAL;
+ }
+
+ sched_req = vos_mem_malloc(sizeof(*sched_req));
+ if (sched_req == NULL) {
+ hddLog(LOGE, FL("Unable to allocate memory!"));
+ return -ENOMEM;
+
+ }
+ vos_mem_set((void *)sched_req, sizeof(*sched_req), 0);
+
+ sched_req->session_id = adapter->sessionId;
+ sched = &sched_req->sched;
+
+ /* Get the number of channels in schedule */
+ if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_NUM_CHANS]) {
+ hddLog(LOGE, FL("NUM_CHANS is not present"));
+ goto fail;
+ }
+
+ sched->num_channels = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_NUM_CHANS]);
+
+ /* Get the parameters for each channel in schedule */
+ if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN]) {
+ hddLog(LOGE, FL("CHAN not present"));
+ goto fail;
+ }
+
+ nla_for_each_nested(channels,
+ tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN],
+ rem1) {
+ if (nla_parse(channel,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX,
+ nla_data(channels), nla_len(channels), NULL)) {
+ hddLog(LOGE, FL("nla_parse failed"));
+ goto fail;
+ }
+
+ /* Parse and fetch parameters for each channel */
+ /* Channel index */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_IDX]) {
+ hddLog(LOGE, FL("CHAN_IDX not present"));
+ goto fail;
+ }
+ chan_idx = nla_get_u32(
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_IDX]);
+
+ /* Channel Number */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_FREQ]) {
+ hddLog(LOGE, FL("CHAN_FREQ not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].chan_freq = nla_get_u32(
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_FREQ]);
+
+ /* TX Power */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_PWR]) {
+ hddLog(LOGE, FL("CHAN_TX_PWR not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].tx_power = nla_get_u32(
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_PWR]);
+
+ /* TX Rate */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_RATE]) {
+ hddLog(LOGE, FL("CHAN_TX_RATE not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].tx_rate = nla_get_u32(
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_TX_RATE]);
+
+ /* Duration */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_DUR]) {
+ hddLog(LOGE, FL("DUR not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].duration = nla_get_u32(
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_DUR]);
+
+ /* Start Guard Interval */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_START_GUARD_INT]) {
+ hddLog(LOGE, FL("START_GUARD_INT not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].start_guard_interval = nla_get_u32(
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_START_GUARD_INT]);
+
+ /* End Guard Interval */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_END_GUARD_INT]) {
+ hddLog(LOGE, FL("END_GUARD_INT not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].end_guard_interval = nla_get_u32(
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_END_GUARD_INT]);
+
+ /* QoS Params */
+ if (!channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM]) {
+ hddLog(LOGE, FL("QOS_PARAM not present"));
+ goto fail;
+ }
+
+ nla_for_each_nested(qos_params,
+ channel[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM],
+ rem2) {
+ if (nla_parse(qos_param,
+ QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_MAX,
+ nla_data(qos_params), nla_len(qos_params), NULL)) {
+ hddLog(LOGE, FL("nla_parse failed"));
+ goto fail;
+ }
+
+ /* Access Category Index */
+ if (!qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AC]) {
+ hddLog(LOGE, FL("QOS_PARAM_AC not present"));
+ goto fail;
+ }
+ ac = nla_get_u8(
+ qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AC]);
+ if (ac >= NUM_AC) {
+ hddLog(LOGE, FL("QOS_PARAM_AIFSN is out of range"));
+ goto fail;
+ }
+
+ /* AIFSN */
+ if (!qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AIFSN]) {
+ hddLog(LOGE, FL("QOS_PARAM_AIFSN not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].qos_params[ac].aifsn = nla_get_u8(
+ qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_AIFSN]);
+
+ /* CWMIN */
+ if (!qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMIN]) {
+ hddLog(LOGE, FL("QOS_PARAM_CWMIN not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].qos_params[ac].cwmin = nla_get_u8(
+ qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMIN]);
+
+ /* CWMAX */
+ if (!qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMAX]) {
+ hddLog(LOGE, FL("QOS_PARAM_CWMAX not present"));
+ goto fail;
+ }
+ sched->channels[chan_idx].qos_params[ac].aifsn = nla_get_u8(
+ qos_param[QCA_WLAN_VENDOR_ATTR_OCB_SET_SCHED_CHAN_QOS_PARAM_CWMAX]);
+ }
+ }
+
+ /* TODO-OCB: Refactor common code path from WEXT and use here */
+
+ rc = 0;
+
+fail:
+ if (sched_req) {
+ vos_mem_free(sched_req);
+ }
+ return rc;
+}
+
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
{
@@ -4830,6 +5065,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
.doit = (void *)wlan_hdd_cfg80211_do_acs
},
#endif
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_SET_SCHED,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = (void *)wlan_hdd_cfg80211_ocb_set_schedule
+ },
};
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 75572214005a..db8ca30f6022 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -8980,6 +8980,7 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
/* fall through */
case WLAN_HDD_P2P_CLIENT:
case WLAN_HDD_P2P_DEVICE:
+ case WLAN_HDD_OCB:
{
pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
@@ -11424,6 +11425,21 @@ VOS_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx)
hdd_ctx->reg.cc_src);
}
+/**
+ * hdd_set_dot11p_config() - Set 802.11p config flag
+ * @hdd_ctx: HDD Context pointer
+ *
+ * TODO-OCB: This has been temporarily added to ensure this paramter
+ * is set in CSR when we init the channel list. This should be removed
+ * once the 5.9 GHz channels are added to the regulatory domain.
+ */
+void hdd_set_dot11p_config(hdd_context_t *hdd_ctx)
+{
+ sme_set_dot11p_config(hdd_ctx->hHal,
+ hdd_ctx->cfg_ini->dot11p_mode !=
+ WLAN_HDD_11P_DISABLED);
+}
+
/**---------------------------------------------------------------------------
\brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
@@ -11658,6 +11674,7 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
#endif
tANI_U8 rtnl_lock_enable;
tANI_U8 reg_netdev_notifier_done = FALSE;
+ hdd_adapter_t *dot11_adapter = NULL;
ENTER();
@@ -11899,6 +11916,13 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
goto err_vosclose;
}
+ /* Set 802.11p config
+ * TODO-OCB: This has been temporarily added here to ensure this paramter
+ * is set in CSR when we init the channel list. This should be removed
+ * once the 5.9 GHz channels are added to the regulatory domain.
+ */
+ hdd_set_dot11p_config(pHddCtx);
+
if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
{
pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
@@ -12042,53 +12066,65 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
rtnl_lock_enable = FALSE;
#endif
- pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
- wlan_hdd_get_intf_addr(pHddCtx), rtnl_lock_enable );
+ if (pHddCtx->cfg_ini->dot11p_mode == WLAN_HDD_11P_STANDALONE) {
+ /* Create only 802.11p interface */
+ pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_OCB,
+ "wlanocb%d", wlan_hdd_get_intf_addr(pHddCtx), rtnl_lock_enable);
+ } else {
+ pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
+ wlan_hdd_get_intf_addr(pHddCtx), rtnl_lock_enable );
#ifdef WLAN_OPEN_P2P_INTERFACE
- /* Open P2P device interface */
- if (pAdapter != NULL)
- {
- if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated)
- {
- vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
- pHddCtx->cfg_ini->intfMacAddr[0].bytes,
- sizeof(tSirMacAddr));
-
- /* Generate the P2P Device Address. This consists of the device's
- * primary MAC address with the locally administered bit set.
- */
- pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
- }
- else
- {
- tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
- if (p2p_dev_addr != NULL)
- {
- vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
- p2p_dev_addr, VOS_MAC_ADDR_SIZE);
+ /* Open P2P device interface */
+ if (pAdapter != NULL) {
+ if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated) {
+ vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
+ pHddCtx->cfg_ini->intfMacAddr[0].bytes,
+ sizeof(tSirMacAddr));
+
+ /* Generate the P2P Device Address. This consists of the device's
+ * primary MAC address with the locally administered bit set.
+ */
+ pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
+ } else {
+ uint8_t* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
+ if (p2p_dev_addr != NULL) {
+ vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
+ p2p_dev_addr, VOS_MAC_ADDR_SIZE);
+ } else {
+ hddLog(VOS_TRACE_LEVEL_FATAL,
+ FL("Failed to allocate mac_address for p2p_device"));
+ goto err_close_adapter;
+ }
}
- else
- {
+
+ pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
+ &pHddCtx->p2pDeviceAddress.bytes[0],
+ rtnl_lock_enable);
+
+ if (NULL == pP2pAdapter) {
hddLog(VOS_TRACE_LEVEL_FATAL,
- "%s: Failed to allocate mac_address for p2p_device",
- __func__);
+ FL("Failed to do hdd_open_adapter for P2P Device Interface"));
goto err_close_adapter;
}
}
-
- pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
- &pHddCtx->p2pDeviceAddress.bytes[0], rtnl_lock_enable );
-
- if ( NULL == pP2pAdapter )
- {
- hddLog(VOS_TRACE_LEVEL_FATAL,
- "%s: Failed to do hdd_open_adapter for P2P Device Interface",
- __func__);
- goto err_close_adapter;
+#endif /* WLAN_OPEN_P2P_INTERFACE */
+
+ /* Open 802.11p Interface */
+ if (pAdapter != NULL) {
+ if (pHddCtx->cfg_ini->dot11p_mode == WLAN_HDD_11P_CONCURRENT) {
+ dot11_adapter = hdd_open_adapter(pHddCtx, WLAN_HDD_OCB,
+ "wlanocb%d", wlan_hdd_get_intf_addr(pHddCtx),
+ rtnl_lock_enable);
+
+ if (dot11_adapter == NULL) {
+ hddLog(VOS_TRACE_LEVEL_FATAL,
+ FL("hdd_open_adapter() failed for 802.11p Interface"));
+ goto err_close_adapter;
+ }
+ }
}
}
-#endif
if( pAdapter == NULL )
{
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index a41dc0147bd1..f07843cd8eaf 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -713,6 +713,40 @@ void hdd_tx_resume_cb(void *adapter_context,
}
#endif /* QCA_LL_TX_FLOW_CT */
+/**
+ * hdd_remove_ocb_tx_header() - Function to check for OCB
+ * TX control header on a packet and extract it if present
+ *
+ * @skb: Pointer to OS packet (sk_buff)
+ */
+static void hdd_remove_ocb_tx_header(struct sk_buff *skb)
+{
+ struct ethhdr *eth_hdr_p;
+ struct ethhdr eth_hdr;
+
+ /* Check if TX control header is present */
+ eth_hdr_p = (struct ethhdr *) &skb->data[0];
+ if (eth_hdr_p->h_proto != htons(HDD_ETHERTYPE_OCB_TX)) {
+ /* TX control header is not present. Nothing to do.. */
+ return;
+ }
+
+ /* Copy and remove the ethernet header */
+ memcpy(&eth_hdr, eth_hdr_p, HDD_ETH_HEADER_LEN);
+ skb_pull(skb, HDD_ETH_HEADER_LEN);
+
+ /* Remove the TX control header */
+ skb_pull(skb, HDD_OCB_TX_HEADER_LEN);
+
+ /* Convert Ethernet header to 802.3 header by changing ethertype
+ field to length field */
+ eth_hdr.h_proto = htons(skb->len);
+
+ /* Push the now 802.3 header back */
+ skb_push(skb, HDD_ETH_HEADER_LEN);
+ memcpy(&skb->data[0], &eth_hdr, HDD_ETH_HEADER_LEN);
+}
+
/**============================================================================
@brief hdd_hard_start_xmit() - Function registered with the Linux OS for
transmitting packets. This version of the function directly passes the packet
@@ -776,6 +810,10 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
STAId = pHddStaCtx->conn_info.staId[0];
}
+ if (pAdapter->device_mode == WLAN_HDD_OCB) {
+ hdd_remove_ocb_tx_header(skb);
+ }
+
#ifdef QCA_LL_TX_FLOW_CT
if (VOS_FALSE ==
WLANTL_GetTxResource((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 0e0c0723c16d..5307a165cf5e 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -433,6 +433,9 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WLAN_SET_POWER_PARAMS (SIOCIWFIRSTPRIV + 29)
+/* 802.11p IOCTL */
+#define WLAN_SET_DOT11P_CHANNEL_SCHED (SIOCIWFIRSTPRIV + 30)
+
#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
/* Private ioctls and their sub-ioctls */
@@ -2997,6 +3000,399 @@ static int iw_get_linkspeed_priv(struct net_device *dev,
return 0;
}
+/* Structure definitions for WLAN_SET_DOT11P_CHANNEL_SCHED */
+#define NUM_AC (4)
+#define OCB_CHANNEL_MAX (5)
+#define DOT11P_TX_PWR_MAX (23)
+#define AIFSN_MIN (2)
+#define AIFSN_MAX (15)
+#define CW_MIN (1)
+#define CW_MAX (10)
+#define HDD_OCB_SET_SCHED_TIME_OUT (1500)
+
+#define NUM_DOT11P_CHANNELS 9
+static const uint32_t valid_dot11p_channels[NUM_DOT11P_CHANNELS] = {
+ 5860, 5870, 5880, 5890, 5900, 5910, 5920, 5875, 5905,
+};
+
+/**
+ * struct ocb_qos_params - QoS Parameters for each AC
+ * @aifsn: Arbitration Inter-Frame Spacing
+ * @cwmin: Contention Window (Min)
+ * @cwmax: Contention Window (Max)
+ */
+struct ocb_qos_params {
+ uint8_t aifsn;
+ uint8_t cwmin;
+ uint8_t cwmax;
+};
+
+/**
+ * struct ocb_channel - Parameters for each OCB channel
+ * @channel_freq: Channel Frequency (MHz)
+ * @duration: Channel Duration (ms)
+ * @start_guard_interval: Start Guard Interval (ms)
+ * @end_guard_interval: End Guard Interval (ms)
+ * @tx_power: Transmit Power (dBm)
+ * @tx_rate: Transmit Data Rate (mbit)
+ * @qos_params: Array of QoS Parameters
+ * @per_packet_rx_stats: Enable per packet RX statistics
+ */
+struct ocb_channel {
+ uint32_t channel_freq;
+ uint32_t duration;
+ uint32_t start_guard_interval;
+ uint32_t end_guard_interval;
+ uint32_t tx_power;
+ uint32_t tx_rate;
+ struct ocb_qos_params qos_params[NUM_AC];
+ uint32_t per_packet_rx_stats;
+};
+
+/**
+ * struct dot11p_channel_sched - OCB channel schedule
+ * @num_channels: Number of channels
+ * @channels: Array of channel parameters
+ * @off_channel_tx: Enable off channel TX
+ */
+struct dot11p_channel_sched {
+ uint32_t num_channels;
+ struct ocb_channel channels[OCB_CHANNEL_MAX];
+ uint32_t off_channel_tx;
+};
+
+/**
+ * dot11p_validate_channel() - Check if specified channel is valid
+ * @channel: Channel Frequency (MHz)
+ *
+ * Return: 0 on success. 1 on failure.
+ */
+static int dot11p_validate_channel(uint32_t channel)
+{
+ int i;
+
+ for (i = 0; i < NUM_DOT11P_CHANNELS; i++) {
+ if (channel == valid_dot11p_channels[i]) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * dot11p_validate_qos_params() - Check if QoS parameters are valid
+ * @qos_params: Array of QoS parameters
+ *
+ * Return: 0 on success. 1 on failure.
+ */
+static int dot11p_validate_qos_params(struct ocb_qos_params qos_params[])
+{
+ int i;
+
+ for (i = 0; i < NUM_AC; i++) {
+ if ((!qos_params[i].aifsn) && (!qos_params[i].cwmin)
+ && (!qos_params[i].cwmax)) {
+ continue;
+ }
+
+ /* Validate AIFSN */
+ if ((qos_params[i].aifsn < AIFSN_MIN)
+ || (qos_params[i].aifsn > AIFSN_MAX)) {
+ return 1;
+ }
+
+ /* Validate CWMin */
+ if ((qos_params[i].cwmin < CW_MIN)
+ || (qos_params[i].cwmin > CW_MAX)) {
+ return 1;
+ }
+
+ /* Validate CWMax */
+ if ((qos_params[i].cwmax < CW_MIN)
+ || (qos_params[i].cwmax > CW_MAX)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * dot11p_validate_sched() - Check if schedule is valid
+ * @sched: OCB channel schedule
+ *
+ * Return: 0 on success. 1 on failure.
+ */
+int dot11p_validate_sched(struct dot11p_channel_sched *sched)
+{
+ int i;
+
+ if ((sched->num_channels > OCB_CHANNEL_MAX)
+ || (sched->num_channels == 0)) {
+ goto error;
+ }
+
+ for (i = 0; i < sched->num_channels; i++) {
+ /* Validate channel frequency */
+ if (dot11p_validate_channel(sched->channels[i].channel_freq)) {
+ goto error;
+ }
+
+ /* Validate TX Power */
+ if (sched->channels[i].tx_power > DOT11P_TX_PWR_MAX) {
+ goto error;
+ }
+
+ /* Validate TX Rate */
+ switch (sched->channels[i].tx_rate) {
+ case 0:
+ case 6:
+ case 9:
+ case 12:
+ case 18:
+ case 24:
+ case 36:
+ case 48:
+ case 54:
+ break;
+ default:
+ goto error;
+ }
+
+ /* Validate QoS Params */
+ if (dot11p_validate_qos_params(sched->channels[i].qos_params)) {
+ goto error;
+ }
+
+ if ((sched->channels[i].per_packet_rx_stats != 0)
+ && (sched->channels[i].per_packet_rx_stats != 1)) {
+ goto error;
+ }
+ }
+
+ return 0;
+
+error:
+ return 1;
+}
+
+/**
+ * hdd_ocb_register_sta() - Register station with Transport Layer
+ * @adapter: Pointer to HDD Adapter
+ *
+ * This function should be invoked in the OCB Set Schedule callback
+ * to enable the data path in the TL by calling RegisterSTAClient
+ *
+ * Return: 0 on success. -1 on failure.
+ */
+static int hdd_ocb_register_sta(hdd_adapter_t *adapter)
+{
+ VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
+ WLAN_STADescType sta_desc = {0};
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ u_int8_t peer_id;
+ v_MACADDR_t wildcardBSSID = {
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ };
+
+ vos_status = WLANTL_RegisterOCBPeer(hdd_ctx->pvosContext,
+ adapter->macAddressCurrent.bytes,
+ &peer_id);
+ if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+ hddLog(LOGE, FL("Error registering OCB Self Peer!"));
+ return -1;
+ }
+
+ /* Register adapter for STA ID 0 */
+ /* TODO-OCB: This is for standalone 802.11p only. We need to change this
+ * for concurrent mode */
+ hdd_ctx->sta_to_adapter[0] = adapter;
+
+ sta_desc.ucSTAId = peer_id;
+ /* Fill in MAC addresses */
+ vos_copy_macaddr(&sta_desc.vSelfMACAddress, &adapter->macAddressCurrent);
+ vos_copy_macaddr(&sta_desc.vSTAMACAddress, &adapter->macAddressCurrent);
+ vos_copy_macaddr(&sta_desc.vBSSIDforIBSS, &wildcardBSSID);
+
+ sta_desc.wSTAType = WLAN_STA_OCB;
+ sta_desc.ucQosEnabled = 1;
+ sta_desc.ucInitState = WLANTL_STA_AUTHENTICATED;
+
+ vos_status = WLANTL_RegisterSTAClient(hdd_ctx->pvosContext,
+ hdd_rx_packet_cbk,
+ hdd_tx_complete_cbk,
+ hdd_tx_fetch_packet_cbk, &sta_desc,
+ 0);
+ if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+ hddLog(LOGE, FL("WLANTL_RegisterSTAClient() failed to register. "
+ "Status= %d [0x%08X]"), vos_status, vos_status);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * hdd_ocb_set_sched_callback() - OCB Set Schedule callback functions
+ * @callback_context: Pointer to HDD Adapter
+ * @rsp: Pointer to response structure
+ *
+ * This function is registered as a callback with the lower layers
+ * and is used to respond with the status of a OCB Set Schedule command.
+ */
+static void hdd_ocb_set_sched_callback(sir_ocb_set_sched_response_t *resp)
+{
+ hdd_adapter_t *adapter;
+
+ if (resp == NULL) {
+ return;
+ }
+
+ adapter = (hdd_adapter_t *)resp->adapter;
+
+ if (resp->status) {
+ /* OCB Set Schedule command failed */
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("OCB set schedule command failed! Status = %d"),
+ resp->status);
+ goto exit;
+ }
+
+ /* OCB Set Schedule command successful. Open TX data path */
+ if (hdd_ocb_register_sta(adapter)) {
+ resp->status = -1;
+ } else {
+ netif_carrier_on(adapter->dev);
+ netif_tx_start_all_queues(adapter->dev);
+ }
+
+exit:
+ complete(&adapter->hdd_ocb_set_sched_req_var);
+}
+
+/**
+ * iw_set_dot11p_channel_sched() - Handler for WLAN_SET_DOT11P_CHANNEL_SCHED
+ * ioctl
+ * @dev: Pointer to net_device structure
+ * @iw_request_info: IW Request Info
+ * @wrqu: IW Request Userspace Data Pointer
+ * @extra: IW Request Kernel Data Pointer
+ */
+static int iw_set_dot11p_channel_sched(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int rc = 0;
+ eHalStatus halStatus;
+ struct dot11p_channel_sched *sched;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ sir_ocb_set_sched_request_t *sched_req = NULL;
+ sir_ocb_set_sched_response_t *sched_resp = NULL;
+ sir_ocb_sched_t *sched_ptr;
+ int i;
+
+ if (wlan_hdd_validate_context(WLAN_HDD_GET_CTX(adapter))) {
+ hddLog(LOGE, FL("HDD context is not valid"));
+ return -EINVAL;
+ }
+
+ if (adapter->device_mode != WLAN_HDD_OCB) {
+ hddLog(LOGE, FL("Device not in OCB mode!"));
+ return -EINVAL;
+ }
+
+ if (extra == NULL) {
+ hddLog(LOGE, FL("No data in IOCTL!"));
+ return -EINVAL;
+ }
+
+ sched = (struct dot11p_channel_sched *)extra;
+ if (dot11p_validate_sched(sched)) {
+ hddLog(LOGE, FL("OCB schedule validation failed!"));
+ return -EINVAL;
+ }
+
+ /*
+ * Currently we support only single channel operation.
+ * Hence, we will only use the first channel in the schedule regardless
+ * of the number of channels specified. All duration parameters will also
+ * be ignored.
+ */
+ sched_req = vos_mem_malloc(sizeof(sir_ocb_set_sched_request_t));
+ if (sched_req == NULL) {
+ hddLog(LOGE, FL("Failed to allocate memory!"));
+ return -ENOMEM;
+ }
+ vos_mem_set(sched_req, sizeof(*sched_req), 0);
+
+ sched_resp = vos_mem_malloc(sizeof(sir_ocb_set_sched_response_t));
+ if (sched_resp == NULL) {
+ hddLog(LOGE, FL("Failed to allocate memory!"));
+ rc = -ENOMEM;
+ goto exit;
+ }
+ vos_mem_set(sched_resp, sizeof(*sched_resp), 0);
+
+ sched_req->session_id = adapter->sessionId;
+
+ sched_ptr = &sched_req->sched;
+ sched_ptr->num_channels = 1;
+ sched_ptr->channels[0].chan_freq = sched->channels[0].channel_freq;
+ sched_ptr->channels[0].tx_power = sched->channels[0].tx_power;
+ sched_ptr->channels[0].tx_rate = sched->channels[0].tx_rate;
+ for (i = 0; i < NUM_AC; i++) {
+ sched_ptr->channels[0].qos_params[i].aifsn =
+ sched->channels[0].qos_params[i].aifsn;
+ sched_ptr->channels[0].qos_params[i].cwmin =
+ sched->channels[0].qos_params[i].cwmin;
+ sched_ptr->channels[0].qos_params[i].cwmax =
+ sched->channels[0].qos_params[i].cwmax;
+ }
+ sched_ptr->channels[0].rx_stats = sched->channels[0].per_packet_rx_stats;
+
+ sched_resp->adapter = (void *)adapter;
+ sched_req->resp = sched_resp;
+ sched_req->callback = hdd_ocb_set_sched_callback;
+
+ netif_tx_disable(adapter->dev);
+ netif_carrier_off(adapter->dev);
+
+ init_completion(&adapter->hdd_ocb_set_sched_req_var);
+ halStatus = sme_ocb_set_sched_req(sched_req);
+ if (halStatus != eHAL_STATUS_SUCCESS) {
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ rc = wait_for_completion_timeout(&adapter->hdd_ocb_set_sched_req_var,
+ msecs_to_jiffies(HDD_OCB_SET_SCHED_TIME_OUT));
+ if (!rc) {
+ hddLog(LOGE, FL("Timeout waiting for OCB set sched to complete"));
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ /* Check the status code */
+ if (sched_resp->status) {
+ hddLog(LOGE, FL("Error while setting OCB Schedule"));
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ rc = 0;
+
+exit:
+ if (sched_req) {
+ vos_mem_free(sched_req);
+ }
+ if (sched_resp) {
+ vos_mem_free(sched_resp);
+ }
+ return rc;
+}
+
+
/*
* Support for the RSSI & RSSI-APPROX private commands
* Per the WiFi framework the response must be of the form
@@ -9778,6 +10174,7 @@ static const iw_handler we_private[] = {
[WLAN_SET_POWER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_power_params_priv,
[WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed_priv,
[WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_two_ints_getnone,
+ [WLAN_SET_DOT11P_CHANNEL_SCHED - SIOCIWFIRSTPRIV] = iw_set_dot11p_channel_sched,
};
/*Maximum command length can be only 15 */
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 0224b806ca3f..cc79bc36282d 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -1039,10 +1039,14 @@ typedef struct sAniSirGlobal
csrReadyToExtWoWCallback readyToExtWoWCallback;
void *readyToExtWoWContext;
#endif
+
#ifdef SAP_AUTH_OFFLOAD
bool sap_auth_offload;
uint32_t sap_auth_offload_sec_type;
#endif /* SAP_AUTH_OFFLOAD */
+
+ /* 802.11p enable */
+ bool enable_dot11p;
} tAniSirGlobal;
typedef enum
diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h
index 6125b3662b22..f120a4ee8fa3 100644
--- a/CORE/MAC/inc/qwlan_version.h
+++ b/CORE/MAC/inc/qwlan_version.h
@@ -42,9 +42,9 @@ BRIEF DESCRIPTION:
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 0
#define QWLAN_VERSION_EXTRA ""
-#define QWLAN_VERSION_BUILD 253
+#define QWLAN_VERSION_BUILD 254
-#define QWLAN_VERSIONSTR "1.0.0.253"
+#define QWLAN_VERSIONSTR "1.0.0.254"
#define AR6320_REV1_VERSION 0x5000000
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index b854adabca62..2504e1827f01 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4285,6 +4285,8 @@ typedef struct sSirUpdateChanParam
tANI_U8 chanId;
tANI_U8 pwr;
tANI_BOOLEAN dfsSet;
+ bool half_rate;
+ bool quarter_rate;
} tSirUpdateChanParam, *tpSirUpdateChanParam;
typedef struct sSirUpdateChan
@@ -5615,4 +5617,49 @@ struct tSirSapOffloadInfo
};
#endif /* SAP_AUTH_OFFLOAD */
+/* OCB Data Structures and defines */
+#define NUM_AC (4)
+#define OCB_CHANNEL_MAX (5)
+
+typedef struct sir_qos_params {
+ uint8_t aifsn;
+ uint8_t cwmin;
+ uint8_t cwmax;
+} sir_qos_params_t;
+
+typedef struct sir_ocb_channel
+{
+ uint32_t chan_freq;
+ uint32_t duration;
+ uint32_t start_guard_interval;
+ uint32_t end_guard_interval;
+ uint32_t tx_power;
+ uint32_t tx_rate;
+ sir_qos_params_t qos_params[NUM_AC];
+ uint32_t rx_stats;
+} sir_ocb_channel_t;
+
+typedef struct sir_ocb_sched
+{
+ uint32_t num_channels;
+ sir_ocb_channel_t channels[OCB_CHANNEL_MAX];
+ uint32_t off_channel_tx;
+} sir_ocb_sched_t;
+
+typedef struct sir_ocb_set_sched_response
+{
+ uint8_t status;
+ void *adapter;
+} sir_ocb_set_sched_response_t;
+
+typedef void (*ocb_callback_t)(sir_ocb_set_sched_response_t *);
+
+typedef struct sir_ocb_set_sched_request
+{
+ uint8_t session_id;
+ sir_ocb_sched_t sched;
+ sir_ocb_set_sched_response_t *resp;
+ ocb_callback_t callback;
+} sir_ocb_set_sched_request_t;
+
#endif /* __SIR_API_H */
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 2985779e5544..37bd57885816 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -692,6 +692,8 @@ typedef struct sSirMbMsgP2p
#define SIR_HAL_APFIND_SET_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 306)
#endif /* WLAN_FEATURE_APFIND */
+#define SIR_HAL_OCB_SET_SCHED_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 307)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
// CFG message types
diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c
index 7c3e8b5a0dd2..836ca58ac794 100644
--- a/CORE/SAP/src/sapChSelect.c
+++ b/CORE/SAP/src/sapChSelect.c
@@ -2351,8 +2351,8 @@ eChannelWidthInfo sapGetChannelWidthInfo(tHalHandle halHandle, ptSapContext pSap
else
chWidth = CHWIDTH_HT20;
}
- else if (pSapCtx->csrRoamProfile.phyMode == eSAP_DOT11_MODE_11ac ||
- pSapCtx->csrRoamProfile.phyMode == eSAP_DOT11_MODE_11ac_ONLY) {
+ else if (pSapCtx->csrRoamProfile.phyMode == eCSR_CFG_DOT11_MODE_11AC ||
+ pSapCtx->csrRoamProfile.phyMode == eCSR_CFG_DOT11_MODE_11AC_ONLY) {
chWidth = CHWIDTH_HT80;
}
else {
diff --git a/CORE/SERVICES/COMMON/dbglog_id.h b/CORE/SERVICES/COMMON/dbglog_id.h
index 593c0050e584..672f07ac7ea6 100644
--- a/CORE/SERVICES/COMMON/dbglog_id.h
+++ b/CORE/SERVICES/COMMON/dbglog_id.h
@@ -928,6 +928,16 @@ extern "C" {
#define DATA_TXRX_DBGID_DUP_CHECK 3
#define DATA_TXRX_DBGID_DEFINITION_END 4
+/* HTT module DBGIDs */
+#define HTT_DBGID_DEFINITION_START 0
+#define HTT_DBGID_INVALID_VDEVID_OR_GROUP 1
+#define HTT_DBGID_DISCARD_INTERNAL_PKTS 2
+#define HTT_DBGID_DISCARD_TX_PKTS 3
+#define HTT_DBGID_GROUP_CHANGE 4
+#define HTT_DBGID_GROUP_CREDIT_STATS 5
+#define HTT_DBGID_DISCARD_INTERNAL_PKTS_NUM 6
+#define HTT_DBGID_DEFINITION_END 7
+
/* TDLS module DBGIDs*/
#define TDLS_DBGID_DEFINITION_START 0
#define TDLS_DBGID_VDEV_CREATE 1
diff --git a/CORE/SERVICES/COMMON/ol_htt_api.h b/CORE/SERVICES/COMMON/ol_htt_api.h
index 3df24b466b39..52de3e4e96ac 100644
--- a/CORE/SERVICES/COMMON/ol_htt_api.h
+++ b/CORE/SERVICES/COMMON/ol_htt_api.h
@@ -96,8 +96,8 @@ htt_attach_target(htt_pdev_handle htt_pdev);
/**
* @brief modes that a virtual device can operate as
* @details
- * A virtual device can operate as an AP, an IBSS, or a STA (client).
- * or in monitor mode
+ * A virtual device can operate as an AP, an IBSS, a STA
+ * (client), in monitor mode or in OCB mode
*/
enum htt_op_mode {
htt_op_mode_unknown,
@@ -105,6 +105,7 @@ enum htt_op_mode {
htt_op_mode_ibss,
htt_op_mode_sta,
htt_op_mode_monitor,
+ htt_op_mode_ocb,
};
/* no-ops */
diff --git a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h
index af1904bd3468..9cd5f0ec1fa7 100644
--- a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h
+++ b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h
@@ -46,8 +46,8 @@
/**
* @brief modes that a virtual device can operate as
* @details
- * A virtual device can operate as an AP, an IBSS, or a STA (client).
- * or in monitor mode
+ * A virtual device can operate as an AP, an IBSS, a STA (client),
+ * in monitor mode or in OCB mode
*/
enum wlan_op_mode {
wlan_op_mode_unknown,
@@ -55,6 +55,7 @@ enum wlan_op_mode {
wlan_op_mode_ibss,
wlan_op_mode_sta,
wlan_op_mode_monitor,
+ wlan_op_mode_ocb,
};
#define OL_TXQ_PAUSE_REASON_FW (1 << 0)
@@ -1242,4 +1243,17 @@ void ol_txrx_ipa_uc_get_stat(ol_txrx_pdev_handle pdev);
#define ol_txrx_ipa_uc_get_stat(pdev) /* NO-OP */
#endif /* IPA_UC_OFFLOAD */
+/**
+ * @brief Setter function to store OCB Peer.
+ */
+void ol_txrx_set_ocb_peer(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer);
+
+/**
+ * @brief Getter function to retrieve OCB peer.
+ * @details
+ * Returns A_TRUE if ocb_peer is valid
+ * Otherwise, returns A_FALSE
+ */
+a_bool_t ol_txrx_get_ocb_peer(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t **peer);
+
#endif /* _OL_TXRX_CTRL_API__H_ */
diff --git a/CORE/SERVICES/COMMON/wdi_in.h b/CORE/SERVICES/COMMON/wdi_in.h
index 10fd92cb7144..74c6b2233688 100644
--- a/CORE/SERVICES/COMMON/wdi_in.h
+++ b/CORE/SERVICES/COMMON/wdi_in.h
@@ -105,8 +105,8 @@ void wdi_in_enable_host_ratectrl(ol_txrx_pdev_handle pdev, u_int32_t enable);
/**
* @brief modes that a virtual device can operate as
* @details
- * A virtual device can operate as an AP, an IBSS, or a STA (client).
- * or in monitor mode
+ * A virtual device can operate as an AP, an IBSS, a STA
+ * (client), in monitor mode or OCB mode
*/
enum wlan_op_mode {
wlan_op_mode_unknown,
@@ -114,6 +114,7 @@ enum wlan_op_mode {
wlan_op_mode_ibss,
wlan_op_mode_sta,
wlan_op_mode_monitor,
+ wlan_op_mode_ocb,
};
/**
diff --git a/CORE/SERVICES/COMMON/wmi_services.h b/CORE/SERVICES/COMMON/wmi_services.h
index 1ed0096c6666..f2eb51df6aad 100644
--- a/CORE/SERVICES/COMMON/wmi_services.h
+++ b/CORE/SERVICES/COMMON/wmi_services.h
@@ -116,6 +116,7 @@ typedef enum {
WMI_SERVICE_MDNS_OFFLOAD, /* mDNS responder offload support */
WMI_SERVICE_SAP_AUTH_OFFLOAD, /* softap auth offload */
WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT, /* Dual Band Simultaneous support */
+ WMI_SERVICE_OCB, /* OCB mode support */
WMI_MAX_SERVICE=128 /* max service */
} WMI_SERVICE;
diff --git a/CORE/SERVICES/COMMON/wmi_tlv_defs.h b/CORE/SERVICES/COMMON/wmi_tlv_defs.h
index 058ee257f24b..cdea12310af1 100644
--- a/CORE/SERVICES/COMMON/wmi_tlv_defs.h
+++ b/CORE/SERVICES/COMMON/wmi_tlv_defs.h
@@ -527,6 +527,8 @@ typedef enum {
WMITLV_TAG_STRUC_wmi_sap_ofl_del_sta_event_fixed_param,
WMITLV_TAG_STRUC_wmi_apfind_cmd_param,
WMITLV_TAG_STRUC_wmi_apfind_event_hdr,
+ WMITLV_TAG_STRUC_wmi_ocb_set_sched_cmd_fixed_param,
+ WMITLV_TAG_STRUC_wmi_ocb_set_sched_event_fixed_param,
} WMITLV_TAG_ID;
/*
@@ -726,8 +728,8 @@ typedef enum {
OP(WMI_MDNS_GET_STATS_CMDID) \
OP(WMI_SET_ANTENNA_DIVERSITY_CMDID) \
OP(WMI_SAP_OFL_ENABLE_CMDID) \
- OP(WMI_APFIND_CMDID)
-
+ OP(WMI_APFIND_CMDID) \
+ OP(WMI_OCB_SET_SCHED_CMDID)
/*
@@ -822,7 +824,8 @@ typedef enum {
OP(WMI_MDNS_STATS_EVENTID) \
OP(WMI_PDEV_RESUME_EVENTID) \
OP(WMI_SAP_OFL_ADD_STA_EVENTID) \
- OP(WMI_SAP_OFL_DEL_STA_EVENTID)
+ OP(WMI_SAP_OFL_DEL_STA_EVENTID) \
+ OP(WMI_OCB_SET_SCHED_EVENTID)
/* TLV definitions of WMI commands */
@@ -2025,6 +2028,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_SAP_OFL_ENABLE_CMDID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR)
WMITLV_CREATE_PARAM_STRUC(WMI_APFIND_CMDID);
+/* Set OCB schedule cmd */
+#define WMITLV_TABLE_WMI_OCB_SET_SCHED_CMDID(id,op,buf,len) \
+ WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_ocb_set_sched_cmd_fixed_param, wmi_ocb_set_sched_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX)
+WMITLV_CREATE_PARAM_STRUC(WMI_OCB_SET_SCHED_CMDID);
+
/************************** TLV definitions of WMI events *******************************/
/* Service Ready event */
@@ -2507,6 +2515,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_SAP_OFL_ADD_STA_EVENTID);
WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_sap_ofl_del_sta_event_fixed_param, wmi_sap_ofl_del_sta_event_fixed_param, fixed_param, WMITLV_SIZE_FIX)
WMITLV_CREATE_PARAM_STRUC(WMI_SAP_OFL_DEL_STA_EVENTID);
+/* Set OCB schedule event */
+#define WMITLV_TABLE_WMI_OCB_SET_SCHED_EVENTID(id,op,buf,len) \
+ WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_ocb_set_sched_event_fixed_param, wmi_ocb_set_sched_event_fixed_param, fixed_param, WMITLV_SIZE_FIX)
+WMITLV_CREATE_PARAM_STRUC(WMI_OCB_SET_SCHED_EVENTID);
+
#ifdef __cplusplus
}
#endif
diff --git a/CORE/SERVICES/COMMON/wmi_unified.h b/CORE/SERVICES/COMMON/wmi_unified.h
index 67e639e5eddd..092f6f12eb4b 100644
--- a/CORE/SERVICES/COMMON/wmi_unified.h
+++ b/CORE/SERVICES/COMMON/wmi_unified.h
@@ -580,6 +580,8 @@ typedef enum {
WMI_TPC_CHAINMASK_CONFIG_CMDID,
/** set Antenna diversity command */
WMI_SET_ANTENNA_DIVERSITY_CMDID,
+ /* Set OCB Sched Request */
+ WMI_OCB_SET_SCHED_CMDID,
/* GPIO Configuration */
WMI_GPIO_CONFIG_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_GPIO),
@@ -918,6 +920,9 @@ typedef enum {
WMI_DIAG_EVENTID,
+ /* Set OCB Sched Response */
+ WMI_OCB_SET_SCHED_EVENTID,
+
/* GPIO Event */
WMI_GPIO_INPUT_EVENTID=WMI_EVT_GRP_START_ID(WMI_GRP_GPIO),
/** upload H_CV info WMI event
@@ -1030,6 +1035,8 @@ WMI_CHANNEL_CHANGE_CAUSE_CSA,
#define WMI_CHAN_FLAG_ALLOW_HT 11 /* HT is allowed on this channel */
#define WMI_CHAN_FLAG_ALLOW_VHT 12 /* VHT is allowed on this channel */
#define WMI_CHANNEL_CHANGE_CAUSE_CSA 13 /*Indicate reason for channel switch */
+#define WMI_CHAN_FLAG_HALF_RATE 14 /* Indicates half rate channel */
+#define WMI_CHAN_FLAG_QUARTER_RATE 15 /* Indicates quarter rate channel */
#define WMI_SET_CHANNEL_FLAG(pwmi_channel,flag) do { \
(pwmi_channel)->info |= (1 << flag); \
@@ -3277,6 +3284,8 @@ typedef struct {
**/
#define WMI_VDEV_TYPE_NAN 0x5
+#define WMI_VDEV_TYPE_OCB 0x6
+
/** values for vdev_subtype */
#define WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE 0x1
#define WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT 0x2
@@ -9221,6 +9230,61 @@ typedef struct {
*/
} wmi_apfind_event_hdr;
+/** Number of access priorities. */
+#define NUM_AC (4)
+/** Max number of channels in the schedule. */
+#define OCB_CHANNEL_MAX (5)
+
+/* NOTE: Make sure these data structures are identical to those 9235
+* defined in sirApi.h */
+
+typedef struct
+{
+ /** Arbitration Inter-Frame Spacing. Range: 2-15 */
+ A_UINT32 aifsn;
+ /** Contention Window minimum. Range: 1 - 10 */
+ A_UINT32 cwmin;
+ /** Contention Window maximum. Range: 1 - 10 */
+ A_UINT32 cwmax;
+} wmi_qos_params_t;
+
+typedef struct
+{
+ /** Channel frequency in MHz */
+ A_UINT32 chan_freq;
+ /** Channel duration in ms */
+ A_UINT32 duration;
+ /** Start guard interval in ms */
+ A_UINT32 start_guard_interval;
+ /** End guard interval in ms */
+ A_UINT32 end_guard_interval;
+ /** Transmit power in dBm, range 0 - 23 */
+ A_UINT32 tx_power;
+ /** Transmit datarate in Mbps */
+ A_UINT32 tx_rate;
+ /** QoS parameters for each AC */
+ wmi_qos_params_t qos_params[NUM_AC];
+ /** 1 to enable RX stats for this channel, 0 otherwise */
+ A_UINT32 rx_stats;
+} wmi_ocb_channel_t;
+
+typedef struct {
+ /** TLV tag and len; tag equals
+ * WMITLV_TAG_STRUC_wmi_ocb_set_sched_cmd_fixed_param */
+ A_UINT32 tlv_header;
+ /** Number of valid channels in the channels array */
+ A_UINT32 num_channels;
+ /** The array of channels */
+ wmi_ocb_channel_t channels[OCB_CHANNEL_MAX];
+ /** 1 to allow off-channel tx, 0 otherwise */
+ A_UINT32 off_channel_tx; // Not supported
+} wmi_ocb_set_sched_cmd_fixed_param;
+
+typedef struct {
+ /** Return status. 0 for success, non-zero otherwise */
+ A_UINT32 status;
+} wmi_ocb_set_sched_event_fixed_param;
+
#ifdef __cplusplus
}
#endif
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 1346618c018e..60cf29b0835b 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -362,6 +362,8 @@ static int wma_roam_event_callback(WMA_HANDLE handle, u_int8_t *event_buf,
static VOS_STATUS wma_stop_scan(tp_wma_handle wma_handle,
tAbortScanParams *abort_scan_req);
+void wma_send_ocb_set_sched_req(void *wma_handle, sir_ocb_sched_t *sched);
+
static void *wma_find_vdev_by_addr(tp_wma_handle wma, u_int8_t *addr,
u_int8_t *vdev_id)
{
@@ -1018,6 +1020,26 @@ static int wma_vdev_start_rsp_ind(tp_wma_handle wma, u_int8_t *buf)
tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data;
vos_mem_copy(iface->bssid, bssParams->bssId, ETH_ALEN);
wma_vdev_start_rsp(wma, bssParams, resp_event);
+ } else if (req_msg->msg_type == WDA_OCB_SET_SCHED_REQUEST) {
+ sir_ocb_set_sched_response_t *ocb_sched_resp = wma->ocb_resp;
+
+ /* Send VDEV UP command to FW */
+ if (wmi_unified_vdev_up_send(wma->wmi_handle,
+ resp_event->vdev_id,
+ iface->aid,
+ iface->bssid) < 0) {
+ WMA_LOGE("%s : failed to send vdev up", __func__);
+ return -EEXIST;
+ }
+ iface->vdev_up = TRUE;
+
+ /* Invoke the callback function */
+ if (ocb_sched_resp) {
+ ocb_sched_resp->status = 0;
+ }
+ if (wma->ocb_callback) {
+ wma->ocb_callback(ocb_sched_resp);
+ }
}
vos_timer_destroy(&req_msg->event_timeout);
adf_os_mem_free(req_msg);
@@ -5589,6 +5611,9 @@ enum wlan_op_mode wma_get_txrx_vdev_type(u_int32_t type)
vdev_type = wlan_op_mode_ibss;
break;
#endif
+ case WMI_VDEV_TYPE_OCB:
+ vdev_type = wlan_op_mode_ocb;
+ break;
case WMI_VDEV_TYPE_MONITOR:
default:
WMA_LOGE("Invalid vdev type %u", type);
@@ -6428,9 +6453,10 @@ static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
adf_os_atomic_init(&wma_handle->interfaces
[self_sta_req->sessionId].bss_status);
- if ((self_sta_req->type == WMI_VDEV_TYPE_AP) &&
+ if (((self_sta_req->type == WMI_VDEV_TYPE_AP) &&
(self_sta_req->subType ==
- WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) {
+ WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE))
+ || (self_sta_req->type == WMI_VDEV_TYPE_OCB)) {
WMA_LOGA("P2P Device: creating self peer %pM, vdev_id %hu",
self_sta_req->selfMacAddr,
self_sta_req->sessionId);
@@ -7455,6 +7481,12 @@ VOS_STATUS wma_update_channel_list(WMA_HANDLE handle,
chan_list->chanParam[i].dfsSet);
}
+ if (chan_list->chanParam[i].half_rate) {
+ WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_HALF_RATE);
+ } else if (chan_list->chanParam[i].quarter_rate) {
+ WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_QUARTER_RATE);
+ }
+
if (chan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) {
WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
} else {
@@ -9441,6 +9473,13 @@ static WLAN_PHY_MODE wma_chan_to_mode(u8 chan, ePhyChanBondState chan_offset,
break;
}
}
+
+ /* 5.9 GHz Band */
+ if ((chan >= WMA_11P_CHANNEL_BEGIN) && (chan <= WMA_11P_CHANNEL_END)) {
+ /* Only Legacy Modulation Schemes are supported */
+ phymode = MODE_11A;
+ }
+
WMA_LOGD("%s: phymode %d channel %d offset %d vht_capable %d "
"dot11_mode %d", __func__, phymode, chan,
chan_offset, vht_capable, dot11_mode);
@@ -9530,6 +9569,14 @@ static VOS_STATUS wma_vdev_start(tp_wma_handle wma,
chan->band_center_freq1 -= 10;
}
chan->band_center_freq2 = 0;
+
+ /* Set half or quarter rate WMI flags */
+ if (req->is_half_rate) {
+ WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_HALF_RATE);
+ } else if (req->is_quarter_rate) {
+ WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_QUARTER_RATE);
+ }
+
/*
* If the channel has DFS set, flip on radar reporting.
*
@@ -9885,6 +9932,27 @@ error0:
tgt_req->vdev_id, peer,
VOS_FALSE);
wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)params, 0);
+ } else if (tgt_req->msg_type == WDA_OCB_SET_SCHED_REQUEST) {
+ struct wma_txrx_node *iface;
+ sir_ocb_set_sched_response_t *ocb_sched_resp = wma->ocb_resp;
+
+ WMA_LOGE("%s: WDA_OCB_SET_SCHED_REQUEST timed out", __func__);
+
+ /* Set vdev_up to FALSE */
+ iface = &wma->interfaces[tgt_req->vdev_id];
+ iface->vdev_up = FALSE;
+
+ /* Send callback to upper layers with error code */
+ if (ocb_sched_resp) {
+ ocb_sched_resp->status = VOS_STATUS_E_TIMEOUT;
+ }
+ /* Call HDD Callback */
+ if (wma->ocb_callback) {
+ wma->ocb_callback(ocb_sched_resp);
+ } else {
+ WMA_LOGE("%s: HDD callback is null for OCB Set Schedule\n",
+ __func__);
+ }
}
free_tgt_req:
vos_timer_destroy(&tgt_req->event_timeout);
@@ -22658,6 +22726,125 @@ static int wma_process_sap_auth_offload(tp_wma_handle wma_handle,
}
#endif /* SAP_AUTH_OFFLOAD */
+/* TODO-OCB: This function is currently not called. It should be used
+ * when firmware supports the OCB Set Schedule command
+ */
+/**
+ * wma_send_ocb_set_sched_req() - send the OCB schedule to the FW
+ *
+ * @wma_handle: context with which the handler is registered.
+ * @sched: the schedule to be set.
+ */
+void wma_send_ocb_set_sched_req(void *wma_handle, sir_ocb_sched_t *sched)
+{
+ int32_t ret;
+ tp_wma_handle wma = (tp_wma_handle)wma_handle;
+ wmi_ocb_set_sched_cmd_fixed_param *cmd;
+ wmi_buf_t buf;
+ int i;
+ int j;
+
+ buf = wmi_buf_alloc(wma->wmi_handle,
+ sizeof(wmi_ocb_set_sched_cmd_fixed_param));
+ if (!buf) {
+ WMA_LOGE("Failed to allocate memory");
+ return;
+ }
+
+ cmd = (wmi_ocb_set_sched_cmd_fixed_param *)wmi_buf_data(buf);
+
+ /* Populate the WMI TLV Header */
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_ocb_set_sched_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_ocb_set_sched_cmd_fixed_param));
+
+ /* Populate the WMI command */
+ cmd->num_channels = sched->num_channels;
+ cmd->off_channel_tx = sched->off_channel_tx;
+ for (i = 0; i < cmd->num_channels; i++) {
+ cmd->channels[i].chan_freq = sched->channels[i].chan_freq;
+ cmd->channels[i].duration = sched->channels[i].duration;
+ cmd->channels[i].start_guard_interval =
+ sched->channels[i].start_guard_interval;
+ cmd->channels[i].end_guard_interval =
+ sched->channels[i].end_guard_interval;
+ cmd->channels[i].tx_power = sched->channels[i].tx_power;
+ cmd->channels[i].tx_rate = sched->channels[i].tx_rate;
+ cmd->channels[i].rx_stats = sched->channels[i].rx_stats;
+ for (j = 0; j < NUM_AC; j++) {
+ cmd->channels[i].qos_params[j].aifsn =
+ sched->channels[i].qos_params[j].aifsn;
+ cmd->channels[i].qos_params[j].cwmin =
+ sched->channels[i].qos_params[j].cwmin;
+ cmd->channels[i].qos_params[j].cwmax =
+ sched->channels[i].qos_params[j].cwmax;
+ }
+ }
+
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf,
+ sizeof(wmi_ocb_set_sched_cmd_fixed_param),
+ WMI_OCB_SET_SCHED_CMDID);
+ if (ret != EOK) {
+ WMA_LOGE("%s: Failed to send notify cmd ret = %d", __func__, ret);
+ wmi_buf_free(buf);
+ }
+}
+
+#define OCB_FREQ_TO_CHAN(x) (((x) - 5000) / 5)
+
+static void wma_ocb_set_sched_req(void *wma_handle,
+ sir_ocb_set_sched_request_t *sched_req)
+{
+ tp_wma_handle wma = (tp_wma_handle)wma_handle;
+ struct wma_vdev_start_req req;
+ struct wma_target_req *msg;
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+ sir_ocb_sched_t *sched = &sched_req->sched;
+ u_int8_t vdev_id;
+
+ WMA_LOGD("%s: Enter", __func__);
+
+ /* Store callback function */
+ wma->ocb_callback = sched_req->callback;
+ wma->ocb_resp = sched_req->resp;
+
+ vos_mem_zero(&req, sizeof(req));
+
+ vdev_id = sched_req->session_id;
+
+ /* vdev not yet up. Send vdev start request and wait for response.
+ * OCB Set Schedule request should be sent on receiving
+ * vdev start response message */
+ req.vdev_id = vdev_id;
+
+ /* Enqueue OCB Set Schedule request message */
+ msg = wma_fill_vdev_req(wma, req.vdev_id, WDA_OCB_SET_SCHED_REQUEST,
+ WMA_TARGET_REQ_TYPE_VDEV_START,
+ (void *)sched_req, 1000);
+ if (!msg) {
+ WMA_LOGP("%s: Failed to fill OCB set schedule request for vdev %d",
+ __func__, req.vdev_id);
+ status = VOS_STATUS_E_NOMEM;
+ return;
+ }
+
+ req.chan = OCB_FREQ_TO_CHAN(sched->channels[0].chan_freq);
+ req.max_txpow = sched->channels[0].tx_power;
+ req.is_half_rate = TRUE;
+
+ if (wma->interfaces[vdev_id].vdev_up) {
+ wma->interfaces[vdev_id].vdev_up = FALSE;
+ }
+
+ status = wma_vdev_start(wma, &req, VOS_FALSE);
+ if (status != VOS_STATUS_SUCCESS) {
+ wma_remove_vdev_req(wma, req.vdev_id,
+ WMA_TARGET_REQ_TYPE_VDEV_START);
+ WMA_LOGP("%s: vdev start failed status = %d", __func__,
+ status);
+ }
+}
+
/*
* function : wma_mc_process_msg
* Description :
@@ -23298,6 +23485,13 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
vos_mem_free(msg->bodyptr);
break;
#endif /* WLAN_FEATURE_APFIND */
+
+ case WDA_OCB_SET_SCHED_REQUEST:
+ wma_ocb_set_sched_req(wma_handle,
+ (sir_ocb_set_sched_request_t *)(msg->bodyptr));
+ vos_mem_free(msg->bodyptr);
+ break;
+
default:
WMA_LOGD("unknow msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */
@@ -24552,7 +24746,6 @@ static int wma_sap_ofl_add_sta_handler(void *handle, u_int8_t *data,
__func__);
return 0;
}
-
vos_mem_set(add_sta_req, sizeof(*add_sta_req), 0);
add_sta_req->assoc_id = sta_add_event->assoc_id;
add_sta_req->conn_req_len = sta_add_event->data_len;
@@ -24592,6 +24785,36 @@ static int wma_sap_ofl_del_sta_handler(void *handle, u_int8_t *data,
}
#endif /* SAP_AUTH_OFFLOAD */
+static int wma_ocb_set_sched_event_handler(void *handle, u_int8_t *event_buf,
+ u_int32_t len)
+{
+ tp_wma_handle wma = (tp_wma_handle)handle;
+ WMI_OCB_SET_SCHED_EVENTID_param_tlvs *param_tlvs;
+ wmi_ocb_set_sched_event_fixed_param *fix_param;
+ sir_ocb_set_sched_response_t *ocb_sched_resp = wma->ocb_resp;
+
+ param_tlvs = (WMI_OCB_SET_SCHED_EVENTID_param_tlvs *)event_buf;
+ fix_param = param_tlvs->fixed_param;
+
+ if (ocb_sched_resp) {
+ ocb_sched_resp->status = fix_param->status;
+ } else {
+ WMA_LOGE("%s: OCB Sched Response is null for OCB Set Schedule\n",
+ __func__);
+ return 0;
+ }
+
+ /* Call HDD Callback */
+ if (wma->ocb_callback) {
+ wma->ocb_callback(ocb_sched_resp);
+ } else {
+ WMA_LOGE("%s: HDD callback is null for OCB Set Schedule\n",
+ __func__);
+ }
+
+ return 0;
+}
+
/* function : wma_start
* Description :
* Args :
@@ -24768,6 +24991,16 @@ VOS_STATUS wma_start(v_VOID_t *vos_ctx)
goto end;
}
+ /* Register event handler for OCB Set Schedule event */
+ status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_OCB_SET_SCHED_EVENTID,
+ wma_ocb_set_sched_event_handler);
+ if (status) {
+ WMA_LOGE("Failed to register OCB set schedule event cb");
+ vos_status = VOS_STATUS_E_FAILURE;
+ goto end;
+ }
+
vos_status = VOS_STATUS_SUCCESS;
#ifdef QCA_WIFI_FTM
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index 77e2c7e4f9c5..b2473525ad68 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -110,6 +110,9 @@
#define WMA_11G_CHANNEL_BEGIN 1
#define WMA_11G_CHANNEL_END 14
+#define WMA_11P_CHANNEL_BEGIN (172)
+#define WMA_11P_CHANNEL_END (184)
+
#define WMA_LOGD(args...) \
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, ## args)
#define WMA_LOGI(args...) \
@@ -216,6 +219,10 @@ static const t_probeTime_dwellTime
#define WMA_EXTSCAN_BURST_DURATION 150
#endif
+typedef void (*txFailIndCallback)(u_int8_t *peer_mac, u_int8_t seqNo);
+
+typedef void (*ocb_set_sched_callback_t)(sir_ocb_set_sched_response_t *resp);
+
typedef struct {
HTC_ENDPOINT_ID endpoint_id;
}t_cfg_nv_param;
@@ -736,6 +743,10 @@ typedef struct {
#ifdef FEATURE_WLAN_D0WOW
atomic_t in_d0wow;
#endif
+
+ /* OCB Set Schedule Response */
+ ocb_set_sched_callback_t ocb_callback;
+ sir_ocb_set_sched_response_t *ocb_resp;
}t_wma_handle, *tp_wma_handle;
struct wma_target_cap {
@@ -1166,6 +1177,8 @@ struct wma_vdev_start_req {
u_int8_t ht_capable;
int32_t dfs_pri_multiplier;
u_int8_t dot11_mode;
+ bool is_half_rate;
+ bool is_quarter_rate;
};
struct wma_set_key_params {
diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c
index aceb34238c2a..5e6da9d45337 100644
--- a/CORE/SERVICES/WMI/wmi_unified.c
+++ b/CORE/SERVICES/WMI/wmi_unified.c
@@ -604,6 +604,7 @@ static u_int8_t* get_wmi_cmd_string(WMI_CMD_ID wmi_command)
CASE_RETURN_STRING(WMI_SET_ANTENNA_DIVERSITY_CMDID);
CASE_RETURN_STRING(WMI_SAP_OFL_ENABLE_CMDID);
CASE_RETURN_STRING(WMI_APFIND_CMDID);
+ CASE_RETURN_STRING(WMI_OCB_SET_SCHED_CMDID);
}
return "Invalid WMI cmd";
}
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index e45fff854ca5..f8017dea351e 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1238,6 +1238,8 @@ typedef struct tagCsrConfigParam
v_U8_t conc_custom_rule1;
v_U8_t is_sta_connection_in_5gz_enabled;
+ /* 802.11p enable */
+ bool enable_dot11p;
}tCsrConfigParam;
//Tush
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index cfc06565d4f0..4e7240314e1b 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3832,6 +3832,24 @@ eHalStatus sme_StatsExtRequest(tANI_U8 session_id, tpStatsExtRequestReq input);
eHalStatus sme_StatsExtEvent (tHalHandle hHal, void* pMsg);
#endif
+
+/* -------------------------------------------------------------------------
+ \fn sme_set_dot11p_config
+ \brief API to Set 802.11p config
+ \param hal - The handle returned by macOpen
+ \param enable_dot11p - 802.11p config param
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+void sme_set_dot11p_config(tHalHandle hal, bool enable_dot11p);
+
+/* -------------------------------------------------------------------------
+ \fn sme_ocb_set_sched_req
+ \brief API to Indicate OCB Set Schedule Request
+ \param sched_req - Schedule Request
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+eHalStatus sme_ocb_set_sched_req(sir_ocb_set_sched_request_t *sched_req);
+
/* ---------------------------------------------------------------------------
\fn sme_UpdateDFSScanMode
\brief Update DFS roam scan mode
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index bb990b9807a2..e24e7c811bac 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -450,6 +450,7 @@ static tChannelPwrLimit csrFindChannelPwr(tChannelListWithPower * pdefaultPowerT
return 0;
}
+#define NUM_DOT11P_CHANNELS 9
eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
{
tSirUpdateChanList *pChanList;
@@ -461,6 +462,13 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
tANI_U8 i, j, social_channel[MAX_SOCIAL_CHANNELS] = {1,6,11};
tANI_U8 channel_state;
+ /* Temporarily add list of 802.11P channels statically */
+ /* TODO-OCB: Remove after channels are added to reg domain */
+ tANI_U8 dot11p_channels[NUM_DOT11P_CHANNELS] = {
+ 172, 174, 176, 178, 180, 182, 184, 175, 181,
+ };
+ tANI_U8 dot11p_power = 23;
+
if (CSR_IS_5G_BAND_ONLY(pMac))
{
for (i = 0; i < MAX_SOCIAL_CHANNELS; i++)
@@ -471,6 +479,10 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
}
}
+ if (pMac->enable_dot11p) {
+ numChan += NUM_DOT11P_CHANNELS;
+ }
+
bufLen = sizeof(tSirUpdateChanList) +
(sizeof(tSirUpdateChanParam) * (numChan));
@@ -482,6 +494,7 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
"Failed to allocate memory for tSirUpdateChanList");
return eHAL_STATUS_FAILED_ALLOC;
}
+ vos_mem_zero(pChanList, bufLen);
for (i = 0; i < pScan->base20MHzChannels.numChannels; i++)
{
@@ -522,6 +535,20 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
}
}
+ if (pMac->enable_dot11p) {
+ /* Add 5.9 GHz channels */
+ for (j = 0; j < NUM_DOT11P_CHANNELS; j++) {
+ pChanList->chanParam[num_channel].chanId = dot11p_channels[j];
+ pChanList->chanParam[num_channel].pwr = dot11p_power;
+ pChanList->chanParam[num_channel].dfsSet = VOS_FALSE;
+ if ((pChanList->chanParam[num_channel].chanId != 175)
+ && (pChanList->chanParam[num_channel].chanId != 181)) {
+ pChanList->chanParam[num_channel].half_rate = VOS_TRUE;
+ }
+ num_channel++;
+ }
+ }
+
msg.type = WDA_UPDATE_CHAN_LIST_REQ;
msg.reserved = 0;
msg.bodyptr = pChanList;
@@ -1908,7 +1935,9 @@ eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pPa
pMac->roam.configParam.is_sta_connection_in_5gz_enabled =
pParam->is_sta_connection_in_5gz_enabled;
+ pMac->enable_dot11p = pParam->enable_dot11p;
}
+
return status;
}
@@ -2054,6 +2083,9 @@ eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->isRoamOffloadEnabled =
pMac->roam.configParam.isRoamOffloadEnabled;
#endif
+
+ pParam->enable_dot11p = pMac->enable_dot11p;
+
csrSetChannels(pMac, pParam);
pParam->obssEnabled = pMac->roam.configParam.obssEnabled;
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index b6edd2e87987..d368ce0c3450 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -12295,6 +12295,43 @@ eHalStatus sme_StopBatchScanInd
#endif
+/* -------------------------------------------------------------------------
+ \fn sme_set_dot11p_config
+ \brief API to Set 802.11p config
+ \param hal - The handle returned by macOpen
+ \param enable_dot11p - 802.11p config param
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+void sme_set_dot11p_config(tHalHandle hal, bool enable_dot11p)
+{
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ mac->enable_dot11p = enable_dot11p;
+}
+
+/* -------------------------------------------------------------------------
+ \fn sme_ocb_set_sched_req
+ \brief API to Indicate OCB Set Schedule Request
+ \param sched_req - Schedule Request
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+eHalStatus sme_ocb_set_sched_req(sir_ocb_set_sched_request_t *sched_req)
+{
+ vos_msg_t msg;
+
+ msg.type = WDA_OCB_SET_SCHED_REQUEST;
+ msg.reserved = 0;
+ msg.bodyptr = sched_req;
+ if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to post WDA_OCB_SET_SCHED_REQUEST message to WDA",
+ __func__);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ return eHAL_STATUS_SUCCESS;
+}
+
void sme_getRecoveryStats(tHalHandle hHal) {
tANI_U8 i;
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index 277d1ae982e5..ef533516ad23 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -167,6 +167,8 @@ typedef enum
WLAN_STA_TDLS,
#endif
+ WLAN_STA_OCB,
+
/* Invalid link*/
WLAN_STA_MAX
@@ -201,7 +203,6 @@ typedef enum
WLANTL_STA_MAX_STATE
}WLANTL_STAStateType;
-
/*---------------------------------------------------------------------------
STA Descriptor Type
---------------------------------------------------------------------------*/
@@ -2936,4 +2937,29 @@ void WLANTL_SetUcActive(void *vos_ctx,
void WLANTL_RegisterOPCbFnc(void *vos_ctx,
void (*func)(v_U8_t *op_msg, void *usr_ctxt), void *usr_ctxt);
#endif /* IPA_UC_OFFLOAD */
+
+/*=============================================================================
+ FUNCTION WLANTL_RegisterOCBPeer
+
+ DESCRIPTION
+ Function to register the OCB Self Peer
+
+ PARAMETERS
+ IN
+ vos_ctx : Global OS context context
+ mac_addr : MAC address of self peer
+
+ OUT
+ peer_id : Peer ID
+
+ RETURN VALUE
+ VOS_STATUS_SUCCESS on success
+ VOS_STATUS_E_FAILURE on failure
+
+ SIDE EFFECTS
+
+==============================================================================*/
+VOS_STATUS WLANTL_RegisterOCBPeer(void *vos_ctx, uint8_t *mac_addr,
+ uint8_t *peer_id);
+
#endif /* #ifndef WLAN_QCT_WLANTL_H */
diff --git a/CORE/VOSS/inc/vos_types.h b/CORE/VOSS/inc/vos_types.h
index 8082bb09b7b8..69f2abe41f61 100644
--- a/CORE/VOSS/inc/vos_types.h
+++ b/CORE/VOSS/inc/vos_types.h
@@ -146,6 +146,7 @@ typedef enum
VOS_FTM_MODE = 5,
VOS_IBSS_MODE,
VOS_P2P_DEVICE_MODE,
+ VOS_OCB_MODE,
VOS_MAX_NO_OF_MODE
} tVOS_CON_MODE;
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index da273fbb80c7..725b0eb28207 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -2337,6 +2337,9 @@ VOS_STATUS vos_get_vdev_types(tVOS_CON_MODE mode, tANI_U32 *type,
*type = WMI_VDEV_TYPE_AP;
*sub_type = WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO;
break;
+ case VOS_OCB_MODE:
+ *type = WMI_VDEV_TYPE_OCB;
+ break;
default:
hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid device mode %d", mode);
status = VOS_STATUS_E_INVAL;
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index f07fff3a1201..8a4b7bc0eb7b 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1021,6 +1021,8 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#define WDA_APFIND_SET_CMD SIR_HAL_APFIND_SET_CMD
#endif /* WLAN_FEATURE_APFIND */
+#define WDA_OCB_SET_SCHED_REQUEST SIR_HAL_OCB_SET_SCHED_REQUEST
+
tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames