提交 cc4b9d39 编写于 作者: D Dan Williams 提交者: John W. Linville

libertas: convert 11D_DOMAIN_INFO to a direct command

Signed-off-by: NDan Williams <dcbw@redhat.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 9fb7663d
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -1979,113 +1979,20 @@ int lbs_cfg_register(struct lbs_private *priv)
return ret;
}
/**
* @brief This function sets DOMAIN INFO to FW
* @param priv pointer to struct lbs_private
* @return 0; -1
*/
static int lbs_11d_set_domain_info(struct lbs_private *priv)
{
int ret;
ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
CMD_ACT_SET,
CMD_OPTION_WAITFORRSP, 0, NULL);
if (ret)
lbs_deb_11d("fail to dnld domain info\n");
return ret;
}
static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy,
struct regulatory_request *request)
{
u8 no_of_triplet = 0;
u8 no_of_parsed_chan = 0;
u8 first_channel = 0, next_chan = 0, max_pwr = 0;
u8 i, flag = 0;
enum ieee80211_band band;
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
struct lbs_private *priv = wiphy_priv(wiphy);
struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg;
int ret = 0;
lbs_deb_enter(LBS_DEB_CFG80211);
/* Set country code */
domain_info->country_code[0] = request->alpha2[0];
domain_info->country_code[1] = request->alpha2[1];
domain_info->country_code[2] = ' ';
for (band = 0; band < IEEE80211_NUM_BANDS ; band++) {
if (!wiphy->bands[band])
continue;
sband = wiphy->bands[band];
for (i = 0; i < sband->n_channels ; i++) {
ch = &sband->channels[i];
if (ch->flags & IEEE80211_CHAN_DISABLED)
continue;
if (!flag) {
flag = 1;
next_chan = first_channel = (u32) ch->hw_value;
max_pwr = ch->max_power;
no_of_parsed_chan = 1;
continue;
}
if (ch->hw_value == next_chan + 1 &&
ch->max_power == max_pwr) {
next_chan++;
no_of_parsed_chan++;
} else {
domain_info->triplet[no_of_triplet]
.chans.first_channel = first_channel;
domain_info->triplet[no_of_triplet]
.chans.num_channels = no_of_parsed_chan;
domain_info->triplet[no_of_triplet]
.chans.max_power = max_pwr;
no_of_triplet++;
flag = 0;
}
}
if (flag) {
domain_info->triplet[no_of_triplet]
.chans.first_channel = first_channel;
domain_info->triplet[no_of_triplet]
.chans.num_channels = no_of_parsed_chan;
domain_info->triplet[no_of_triplet]
.chans.max_power = max_pwr;
no_of_triplet++;
}
}
domain_info->no_triplet = no_of_triplet;
/* Set domain info */
ret = lbs_11d_set_domain_info(priv);
if (ret)
lbs_pr_err("11D: error setting domain info in FW\n");
lbs_deb_leave(LBS_DEB_CFG80211);
}
int lbs_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
struct lbs_private *priv = wiphy_priv(wiphy);
int ret;
lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
"callback for domain %c%c\n", request->alpha2[0],
request->alpha2[1]);
lbs_send_domain_info_cmd_fw(wiphy, request);
ret = lbs_set_11d_domain_info(priv, request, wiphy->bands);
lbs_deb_leave(LBS_DEB_CFG80211);
return 0;
return ret;
}
void lbs_scan_deinit(struct lbs_private *priv)
......
......@@ -725,6 +725,129 @@ int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
return ret;
}
/**
* @brief Send regulatory and 802.11d domain information to the firmware
*
* @param priv pointer to struct lbs_private
* @param request cfg80211 regulatory request structure
* @param bands the device's supported bands and channels
*
* @return 0 on success, error code on failure
*/
int lbs_set_11d_domain_info(struct lbs_private *priv,
struct regulatory_request *request,
struct ieee80211_supported_band **bands)
{
struct cmd_ds_802_11d_domain_info cmd;
struct mrvl_ie_domain_param_set *domain = &cmd.domain;
struct ieee80211_country_ie_triplet *t;
enum ieee80211_band band;
struct ieee80211_channel *ch;
u8 num_triplet = 0;
u8 num_parsed_chan = 0;
u8 first_channel = 0, next_chan = 0, max_pwr = 0;
u8 i, flag = 0;
size_t triplet_size;
int ret;
lbs_deb_enter(LBS_DEB_11D);
memset(&cmd, 0, sizeof(cmd));
cmd.action = cpu_to_le16(CMD_ACT_SET);
lbs_deb_11d("Setting country code '%c%c'\n",
request->alpha2[0], request->alpha2[1]);
domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
/* Set country code */
domain->country_code[0] = request->alpha2[0];
domain->country_code[1] = request->alpha2[1];
domain->country_code[2] = ' ';
/* Now set up the channel triplets; firmware is somewhat picky here
* and doesn't validate channel numbers and spans; hence it would
* interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since
* the last 3 aren't valid channels, the driver is responsible for
* splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20)
* etc.
*/
for (band = 0;
(band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
band++) {
if (!bands[band])
continue;
for (i = 0;
(i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
i++) {
ch = &bands[band]->channels[i];
if (ch->flags & IEEE80211_CHAN_DISABLED)
continue;
if (!flag) {
flag = 1;
next_chan = first_channel = (u32) ch->hw_value;
max_pwr = ch->max_power;
num_parsed_chan = 1;
continue;
}
if ((ch->hw_value == next_chan + 1) &&
(ch->max_power == max_pwr)) {
/* Consolidate adjacent channels */
next_chan++;
num_parsed_chan++;
} else {
/* Add this triplet */
lbs_deb_11d("11D triplet (%d, %d, %d)\n",
first_channel, num_parsed_chan,
max_pwr);
t = &domain->triplet[num_triplet];
t->chans.first_channel = first_channel;
t->chans.num_channels = num_parsed_chan;
t->chans.max_power = max_pwr;
num_triplet++;
flag = 0;
}
}
if (flag) {
/* Add last triplet */
lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel,
num_parsed_chan, max_pwr);
t = &domain->triplet[num_triplet];
t->chans.first_channel = first_channel;
t->chans.num_channels = num_parsed_chan;
t->chans.max_power = max_pwr;
num_triplet++;
}
}
lbs_deb_11d("# triplets %d\n", num_triplet);
/* Set command header sizes */
triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet);
domain->header.len = cpu_to_le16(sizeof(domain->country_code) +
triplet_size);
lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set",
(u8 *) &cmd.domain.country_code,
le16_to_cpu(domain->header.len));
cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
sizeof(cmd.action) +
sizeof(cmd.domain.header) +
sizeof(cmd.domain.country_code) +
triplet_size);
ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd);
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
return ret;
}
static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr,
u8 cmd_action, void *pdata_buf)
{
......@@ -1005,66 +1128,6 @@ void lbs_set_mac_control(struct lbs_private *priv)
lbs_deb_leave(LBS_DEB_CMD);
}
/**
* @brief This function implements command CMD_802_11D_DOMAIN_INFO
* @param priv pointer to struct lbs_private
* @param cmd pointer to cmd buffer
* @param cmdno cmd ID
* @param cmdOption cmd action
* @return 0
*/
int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
struct cmd_ds_command *cmd,
u16 cmdoption)
{
struct cmd_ds_802_11d_domain_info *pdomaininfo =
&cmd->params.domaininfo;
struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
u8 nr_triplet = priv->domain_reg.no_triplet;
lbs_deb_enter(LBS_DEB_11D);
lbs_deb_11d("nr_triplet=%x\n", nr_triplet);
pdomaininfo->action = cpu_to_le16(cmdoption);
if (cmdoption == CMD_ACT_GET) {
cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
sizeof(struct cmd_header));
lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
le16_to_cpu(cmd->size));
goto done;
}
domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
memcpy(domain->countrycode, priv->domain_reg.country_code,
sizeof(domain->countrycode));
domain->header.len = cpu_to_le16(nr_triplet
* sizeof(struct ieee80211_country_ie_triplet)
+ sizeof(domain->countrycode));
if (nr_triplet) {
memcpy(domain->triplet, priv->domain_reg.triplet,
nr_triplet *
sizeof(struct ieee80211_country_ie_triplet));
cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
le16_to_cpu(domain->header.len) +
sizeof(struct mrvl_ie_header) +
sizeof(struct cmd_header));
} else {
cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
sizeof(struct cmd_header));
}
lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
le16_to_cpu(cmd->size));
done:
lbs_deb_enter(LBS_DEB_11D);
return 0;
}
/**
* @brief This function prepare the command before send to firmware.
*
......@@ -1154,11 +1217,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
ret = 0;
goto done;
case CMD_802_11D_DOMAIN_INFO:
cmdptr->command = cpu_to_le16(cmd_no);
ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_action);
break;
case CMD_802_11_TPC_CFG:
cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
cmdptr->size =
......
......@@ -3,6 +3,8 @@
#ifndef _LBS_CMD_H_
#define _LBS_CMD_H_
#include <net/cfg80211.h>
#include "host.h"
#include "dev.h"
......@@ -133,4 +135,8 @@ int lbs_set_monitor_mode(struct lbs_private *priv, int enable);
int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf);
int lbs_set_11d_domain_info(struct lbs_private *priv,
struct regulatory_request *request,
struct ieee80211_supported_band **bands);
#endif /* _LBS_CMD_H */
......@@ -96,53 +96,6 @@ static int lbs_ret_reg_access(struct lbs_private *priv,
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
/**
* @brief This function parses countryinfo from AP and download country info to FW
* @param priv pointer to struct lbs_private
* @param resp pointer to command response buffer
* @return 0; -1
*/
static int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
{
struct cmd_ds_802_11d_domain_info *domaininfo =
&resp->params.domaininforesp;
struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
u16 action = le16_to_cpu(domaininfo->action);
s16 ret = 0;
u8 nr_triplet = 0;
lbs_deb_enter(LBS_DEB_11D);
lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp,
(int)le16_to_cpu(resp->size));
nr_triplet = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
sizeof(struct ieee80211_country_ie_triplet);
lbs_deb_11d("domain info resp: nr_triplet %d\n", nr_triplet);
if (nr_triplet > MRVDRV_MAX_TRIPLET_802_11D) {
lbs_deb_11d("invalid number of triplets returned!!\n");
return -1;
}
switch (action) {
case CMD_ACT_SET: /*Proc set action */
break;
case CMD_ACT_GET:
break;
default:
lbs_deb_11d("invalid action:%d\n", domaininfo->action);
ret = -1;
break;
}
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
return ret;
}
static inline int handle_cmd_response(struct lbs_private *priv,
struct cmd_header *cmd_response)
{
......@@ -172,10 +125,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
case CMD_RET(CMD_802_11_BEACON_STOP):
break;
case CMD_RET(CMD_802_11D_DOMAIN_INFO):
ret = lbs_ret_802_11d_domain_info(resp);
break;
case CMD_RET(CMD_802_11_TPC_CFG):
spin_lock_irqsave(&priv->driver_lock, flags);
memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
......
......@@ -53,9 +53,4 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
u32 lbs_fw_index_to_data_rate(u8 index);
u8 lbs_data_rate_to_fw_index(u32 rate);
int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
struct cmd_ds_command *cmd, u16 cmdoption);
int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp);
#endif
......@@ -60,9 +60,6 @@ struct lbs_private {
struct dentry *regs_dir;
struct dentry *debugfs_regs_files[6];
/** 11D and domain regulatory data */
struct lbs_802_11d_domain_reg domain_reg;
/* Hardware debugging */
u32 mac_offset;
u32 bbp_offset;
......
......@@ -389,30 +389,22 @@ struct lbs_offset_value {
u32 value;
} __packed;
#define MRVDRV_MAX_TRIPLET_802_11D 83
#define COUNTRY_CODE_LEN 3
#define MAX_11D_TRIPLETS 83
struct mrvl_ie_domain_param_set {
struct mrvl_ie_header header;
u8 countrycode[COUNTRY_CODE_LEN];
struct ieee80211_country_ie_triplet triplet[1];
u8 country_code[3];
struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS];
} __packed;
struct cmd_ds_802_11d_domain_info {
struct cmd_header hdr;
__le16 action;
struct mrvl_ie_domain_param_set domain;
} __packed;
struct lbs_802_11d_domain_reg {
/** Country code*/
u8 country_code[COUNTRY_CODE_LEN];
/** No. of triplet*/
u8 no_triplet;
struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D];
} __packed;
/*
* Define data structure for CMD_GET_HW_SPEC
* This structure defines the response for the GET_HW_SPEC command
......@@ -973,9 +965,6 @@ struct cmd_ds_command {
struct cmd_ds_bbp_reg_access bbpreg;
struct cmd_ds_rf_reg_access rfreg;
struct cmd_ds_802_11d_domain_info domaininfo;
struct cmd_ds_802_11d_domain_info domaininforesp;
struct cmd_ds_802_11_tpc_cfg tpccfg;
struct cmd_ds_802_11_afc afc;
struct cmd_ds_802_11_led_ctrl ledgpio;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部