mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-01 02:21:16 +00:00
qcacld-2.0: Add support for default TX params in OCB mode
When OCB mode is configured, default TX parameters can be provided. These default TX parameters are used if a packet is sent without a TX control header. Change-Id: I72b3799cb0a9e00a60548facf25e57be241d82d7 CRs-Fixed: 964279
This commit is contained in:
parent
a6cf2de288
commit
29164f263f
9 changed files with 206 additions and 9 deletions
|
@ -552,11 +552,14 @@ ol_tx_non_std_ll(
|
|||
*/
|
||||
#define OCB_HEADER_VERSION 1
|
||||
static bool parse_ocb_tx_header(adf_nbuf_t msdu,
|
||||
struct ocb_tx_ctrl_hdr_t *tx_ctrl)
|
||||
struct ocb_tx_ctrl_hdr_t *tx_ctrl,
|
||||
bool *tx_ctrl_header_found)
|
||||
{
|
||||
struct ether_header *eth_hdr_p;
|
||||
struct ocb_tx_ctrl_hdr_t *tx_ctrl_hdr;
|
||||
|
||||
*tx_ctrl_header_found = false;
|
||||
|
||||
/* Check if TX control header is present */
|
||||
eth_hdr_p = (struct ether_header *) adf_nbuf_data(msdu);
|
||||
if (eth_hdr_p->ether_type != adf_os_htons(ETHERTYPE_OCB_TX))
|
||||
|
@ -570,6 +573,7 @@ static bool parse_ocb_tx_header(adf_nbuf_t msdu,
|
|||
tx_ctrl_hdr = (struct ocb_tx_ctrl_hdr_t*) adf_nbuf_data(msdu);
|
||||
|
||||
if (tx_ctrl_hdr->version == OCB_HEADER_VERSION) {
|
||||
*tx_ctrl_header_found = true;
|
||||
if (tx_ctrl)
|
||||
adf_os_mem_copy(tx_ctrl, tx_ctrl_hdr, sizeof(*tx_ctrl_hdr));
|
||||
} else {
|
||||
|
@ -582,6 +586,49 @@ static bool parse_ocb_tx_header(adf_nbuf_t msdu,
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* merge_ocb_tx_ctrl_hdr() - merge the default TX ctrl parameters into
|
||||
* @tx_ctrl: The destination TX control header.
|
||||
* @def_ctrl_hdr: The default TX control header.
|
||||
*
|
||||
* For each parameter in tx_ctrl, if the parameter is unspecified, the
|
||||
* equivalent parameter in def_ctrl_hdr will be copied to tx_ctrl.
|
||||
*/
|
||||
static void merge_ocb_tx_ctrl_hdr(struct ocb_tx_ctrl_hdr_t *tx_ctrl,
|
||||
struct ocb_tx_ctrl_hdr_t *def_ctrl_hdr)
|
||||
{
|
||||
if (!tx_ctrl || !def_ctrl_hdr)
|
||||
return;
|
||||
|
||||
if (!tx_ctrl->channel_freq && def_ctrl_hdr->channel_freq)
|
||||
tx_ctrl->channel_freq = def_ctrl_hdr->channel_freq;
|
||||
if (!tx_ctrl->valid_pwr && def_ctrl_hdr->valid_pwr) {
|
||||
tx_ctrl->pwr = def_ctrl_hdr->pwr;
|
||||
tx_ctrl->valid_pwr = 1;
|
||||
}
|
||||
if (!tx_ctrl->valid_datarate && def_ctrl_hdr->valid_datarate) {
|
||||
tx_ctrl->datarate = def_ctrl_hdr->datarate;
|
||||
tx_ctrl->valid_datarate = 1;
|
||||
}
|
||||
if (!tx_ctrl->valid_retries && def_ctrl_hdr->valid_retries) {
|
||||
tx_ctrl->retry_limit = def_ctrl_hdr->retry_limit;
|
||||
tx_ctrl->valid_retries = 1;
|
||||
}
|
||||
if (!tx_ctrl->valid_chain_mask && def_ctrl_hdr->valid_chain_mask) {
|
||||
tx_ctrl->chain_mask = def_ctrl_hdr->chain_mask;
|
||||
tx_ctrl->valid_chain_mask = 1;
|
||||
}
|
||||
if (!tx_ctrl->valid_expire_tsf && def_ctrl_hdr->valid_expire_tsf) {
|
||||
tx_ctrl->expire_tsf_hi = def_ctrl_hdr->expire_tsf_hi;
|
||||
tx_ctrl->expire_tsf_lo = def_ctrl_hdr->expire_tsf_lo;
|
||||
tx_ctrl->valid_expire_tsf = 1;
|
||||
}
|
||||
if (!tx_ctrl->valid_tid && def_ctrl_hdr->valid_tid) {
|
||||
tx_ctrl->ext_tid = def_ctrl_hdr->ext_tid;
|
||||
tx_ctrl->valid_tid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline adf_nbuf_t
|
||||
ol_tx_hl_base(
|
||||
ol_txrx_vdev_handle vdev,
|
||||
|
@ -669,10 +716,18 @@ ol_tx_hl_base(
|
|||
|
||||
/* If the vdev is in OCB mode, parse the tx control header. */
|
||||
if (vdev->opmode == wlan_op_mode_ocb) {
|
||||
if (!parse_ocb_tx_header(msdu, &tx_ctrl)) {
|
||||
bool tx_ctrl_header_found = false;
|
||||
|
||||
if (!parse_ocb_tx_header(msdu, &tx_ctrl, &tx_ctrl_header_found)) {
|
||||
/* There was an error parsing the header. Skip this packet. */
|
||||
goto MSDU_LOOP_BOTTOM;
|
||||
}
|
||||
/* If the TX control header was not found, just use the defaults */
|
||||
if (!tx_ctrl_header_found && vdev->ocb_def_tx_param)
|
||||
vos_mem_copy(&tx_ctrl, vdev->ocb_def_tx_param, sizeof(tx_ctrl));
|
||||
/* If the TX control header was found, merge the defaults into it */
|
||||
else if (tx_ctrl_header_found && vdev->ocb_def_tx_param)
|
||||
merge_ocb_tx_ctrl_hdr(&tx_ctrl, vdev->ocb_def_tx_param);
|
||||
}
|
||||
|
||||
txq = ol_tx_classify(vdev, tx_desc, msdu, &tx_msdu_info);
|
||||
|
|
|
@ -2634,6 +2634,92 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define MAX_TID 15
|
||||
#define MAX_DATARATE 7
|
||||
#define OCB_HEADER_VERSION 1
|
||||
|
||||
/**
|
||||
* ol_txrx_set_ocb_def_tx_param() - Set the default OCB TX parameters
|
||||
* @vdev: The OCB vdev that will use these defaults.
|
||||
* @_def_tx_param: The default TX parameters.
|
||||
* @def_tx_param_size: The size of the _def_tx_param buffer.
|
||||
*
|
||||
* Return: true if the default parameters were set correctly, false if there
|
||||
* is an error, for example an invalid parameter. In the case that false is
|
||||
* returned, see the kernel log for the error description.
|
||||
*/
|
||||
bool ol_txrx_set_ocb_def_tx_param(ol_txrx_vdev_handle vdev,
|
||||
void *_def_tx_param, uint32_t def_tx_param_size)
|
||||
{
|
||||
struct ocb_tx_ctrl_hdr_t *def_tx_param =
|
||||
(struct ocb_tx_ctrl_hdr_t *)_def_tx_param;
|
||||
|
||||
if (def_tx_param) {
|
||||
/*
|
||||
* Default TX parameters are provided.
|
||||
* Validate the contents and
|
||||
* save them in the vdev.
|
||||
*/
|
||||
if (def_tx_param_size != sizeof(struct ocb_tx_ctrl_hdr_t)) {
|
||||
VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
|
||||
"Invalid size of OCB default TX params");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (def_tx_param->version != OCB_HEADER_VERSION) {
|
||||
VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
|
||||
"Invalid version of OCB default TX params");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (def_tx_param->channel_freq) {
|
||||
int i;
|
||||
for (i = 0; i < vdev->ocb_channel_count; i++) {
|
||||
if (vdev->ocb_channel_info[i].chan_freq ==
|
||||
def_tx_param->channel_freq)
|
||||
break;
|
||||
}
|
||||
if (i == vdev->ocb_channel_count) {
|
||||
VOS_TRACE(VOS_MODULE_ID_TXRX,
|
||||
VOS_TRACE_LEVEL_ERROR,
|
||||
"Invalid default channel frequency");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (def_tx_param->valid_datarate &&
|
||||
def_tx_param->datarate > MAX_DATARATE) {
|
||||
VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
|
||||
"Invalid default datarate");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (def_tx_param->valid_tid &&
|
||||
def_tx_param->ext_tid > MAX_TID) {
|
||||
VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
|
||||
"Invalid default TID");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vdev->ocb_def_tx_param == NULL)
|
||||
vdev->ocb_def_tx_param =
|
||||
vos_mem_malloc(sizeof(*vdev->ocb_def_tx_param));
|
||||
vos_mem_copy(vdev->ocb_def_tx_param, def_tx_param,
|
||||
sizeof(*vdev->ocb_def_tx_param));
|
||||
} else {
|
||||
/*
|
||||
* Default TX parameters are not provided.
|
||||
* Delete the old defaults.
|
||||
*/
|
||||
if (vdev->ocb_def_tx_param) {
|
||||
vos_mem_free(vdev->ocb_def_tx_param);
|
||||
vdev->ocb_def_tx_param = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef IPA_UC_OFFLOAD
|
||||
void
|
||||
ol_txrx_ipa_uc_get_resource(
|
||||
|
|
|
@ -967,6 +967,9 @@ struct ol_txrx_vdev_t {
|
|||
/* Information about the schedules in the schedule */
|
||||
struct ol_txrx_ocb_chan_info *ocb_channel_info;
|
||||
uint32_t ocb_channel_count;
|
||||
|
||||
/* Default OCB TX parameter */
|
||||
struct ocb_tx_ctrl_hdr_t *ocb_def_tx_param;
|
||||
};
|
||||
|
||||
struct ol_rx_reorder_array_elem_t {
|
||||
|
|
|
@ -753,6 +753,9 @@ static const struct nla_policy qca_wlan_vendor_ocb_set_config_policy[
|
|||
[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS] = {
|
||||
.type = NLA_U32
|
||||
},
|
||||
[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM] = {
|
||||
.type = NLA_BINARY
|
||||
},
|
||||
};
|
||||
|
||||
static const struct nla_policy qca_wlan_vendor_ocb_set_utc_time_policy[
|
||||
|
@ -899,6 +902,8 @@ static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
|
|||
struct nlattr *ndl_active_state_list;
|
||||
uint32_t ndl_active_state_list_len;
|
||||
uint32_t flags = 0;
|
||||
void *def_tx_param = NULL;
|
||||
uint32_t def_tx_param_size = 0;
|
||||
int i;
|
||||
uint32_t channel_count, schedule_size;
|
||||
struct sir_ocb_config *config;
|
||||
|
@ -956,11 +961,19 @@ static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
|
|||
ndl_active_state_list_len = (ndl_active_state_list ?
|
||||
nla_len(ndl_active_state_list) : 0);
|
||||
|
||||
/* Get the flags */
|
||||
/* Get the flags. This parameter is optional. */
|
||||
if (tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS])
|
||||
flags = nla_get_u32(tb[
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS]);
|
||||
|
||||
/* Get the default TX parameters. This parameter is optional. */
|
||||
if (tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM]) {
|
||||
def_tx_param_size = nla_len(tb[
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM]);
|
||||
def_tx_param = nla_data(tb[
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM]);
|
||||
}
|
||||
|
||||
config = hdd_ocb_config_new(channel_count, schedule_size,
|
||||
ndl_chan_list_len,
|
||||
ndl_active_state_list_len);
|
||||
|
@ -972,6 +985,8 @@ static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy,
|
|||
config->channel_count = channel_count;
|
||||
config->schedule_size = schedule_size;
|
||||
config->flags = flags;
|
||||
config->def_tx_param = def_tx_param;
|
||||
config->def_tx_param_size = def_tx_param_size;
|
||||
|
||||
/* Read the channel array */
|
||||
channel_array = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
|
@ -90,7 +90,12 @@ struct dot11p_channel_sched {
|
|||
* @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY:
|
||||
* array of NDL channel information
|
||||
* @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY:
|
||||
* array of NDL active state configuration
|
||||
* array of NDL active state configuration
|
||||
* @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS:
|
||||
* configuration flags such as OCB_CONFIG_FLAG_80211_FRAME_MODE
|
||||
* @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM:
|
||||
* default TX parameters to use in the case that a packet is sent without
|
||||
* a TX control header
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_ocb_set_config {
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_INVALID = 0,
|
||||
|
@ -101,6 +106,7 @@ enum qca_wlan_vendor_attr_ocb_set_config {
|
|||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY,
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY,
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS,
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM,
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST - 1,
|
||||
|
|
|
@ -6298,8 +6298,8 @@ struct sir_ocb_config_sched {
|
|||
* @dcc_ndl_chan_list: array of dcc channel info
|
||||
* @dcc_ndl_active_state_list_len: size of the active state array
|
||||
* @dcc_ndl_active_state_list: array of active states
|
||||
* @adapter: the OCB adapter
|
||||
* @dcc_stats_callback: callback for the response event
|
||||
* @def_tx_param: default TX parameters
|
||||
* @def_tx_param_size: size of the default TX parameters
|
||||
*/
|
||||
struct sir_ocb_config {
|
||||
uint8_t session_id;
|
||||
|
@ -6312,6 +6312,8 @@ struct sir_ocb_config {
|
|||
void *dcc_ndl_chan_list;
|
||||
uint32_t dcc_ndl_active_state_list_len;
|
||||
void *dcc_ndl_active_state_list;
|
||||
void *def_tx_param;
|
||||
uint32_t def_tx_param_size;
|
||||
};
|
||||
|
||||
/* The size of the utc time in bytes. */
|
||||
|
|
|
@ -1429,6 +1429,19 @@ void ol_txrx_set_ocb_peer(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *pe
|
|||
*/
|
||||
a_bool_t ol_txrx_get_ocb_peer(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t **peer);
|
||||
|
||||
/**
|
||||
* ol_txrx_set_ocb_def_tx_param() - Set the default OCB TX parameters
|
||||
* @vdev: The OCB vdev that will use these defaults.
|
||||
* @_def_tx_param: The default TX parameters.
|
||||
* @def_tx_param_size: The size of the _def_tx_param buffer.
|
||||
*
|
||||
* Return: true if the default parameters were set correctly, false if there
|
||||
* is an error, for example an invalid parameter. In the case that false is
|
||||
* returned, see the kernel log for the error description.
|
||||
*/
|
||||
bool ol_txrx_set_ocb_def_tx_param(ol_txrx_vdev_handle vdev,
|
||||
void *def_tx_param, uint32_t def_tx_param_size);
|
||||
|
||||
void ol_txrx_display_stats(struct ol_txrx_pdev_t *pdev, uint16_t bitmap);
|
||||
void ol_txrx_clear_stats(struct ol_txrx_pdev_t *pdev, uint16_t bitmap);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
|
@ -55,6 +55,7 @@ int wma_ocb_set_config_resp(tp_wma_handle wma_handle, uint8_t status)
|
|||
*/
|
||||
if (status == VOS_STATUS_SUCCESS) {
|
||||
if (vdev && req) {
|
||||
/* Save the channel info in the vdev */
|
||||
if (vdev->ocb_channel_info)
|
||||
vos_mem_free(vdev->ocb_channel_info);
|
||||
vdev->ocb_channel_count =
|
||||
|
@ -79,6 +80,14 @@ int wma_ocb_set_config_resp(tp_wma_handle wma_handle, uint8_t status)
|
|||
} else {
|
||||
vdev->ocb_channel_info = 0;
|
||||
}
|
||||
|
||||
/* Default TX parameter */
|
||||
if (!ol_txrx_set_ocb_def_tx_param(vdev,
|
||||
req->def_tx_param, req->def_tx_param_size)) {
|
||||
/* Setting the default param failed */
|
||||
WMA_LOGE(FL("Invalid default TX parameters"));
|
||||
status = VOS_STATUS_E_INVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13276,7 +13276,8 @@ static struct sir_ocb_config *sme_copy_sir_ocb_config(struct sir_ocb_config *src
|
|||
src->channel_count * sizeof(*src->channels) +
|
||||
src->schedule_size * sizeof(*src->schedule) +
|
||||
src->dcc_ndl_chan_list_len +
|
||||
src->dcc_ndl_active_state_list_len;
|
||||
src->dcc_ndl_active_state_list_len +
|
||||
src->def_tx_param_size;
|
||||
|
||||
dst = vos_mem_malloc(length);
|
||||
if (!dst)
|
||||
|
@ -13303,6 +13304,13 @@ static struct sir_ocb_config *sme_copy_sir_ocb_config(struct sir_ocb_config *src
|
|||
vos_mem_copy(dst->dcc_ndl_active_state_list,
|
||||
src->dcc_ndl_active_state_list,
|
||||
src->dcc_ndl_active_state_list_len);
|
||||
cursor += src->dcc_ndl_active_state_list_len;
|
||||
if (src->def_tx_param && src->def_tx_param_size) {
|
||||
dst->def_tx_param = cursor;
|
||||
vos_mem_copy(dst->def_tx_param, src->def_tx_param,
|
||||
src->def_tx_param_size);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue