ath6kl: Add support for setting tx rateset.
Tx legacy and mcs rateset can configured using iw for 2.4 and 5 bands. Add support for the same in driver. kvalo: add an enum for the hw flags and rename the flag accordingly, rename ath6kl_cfg80211_set_bitrate_mask() to a shorter version to make it easier to indent Signed-off-by: Bala Shanmugam <bkamatch@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
fa338be062
commit
06e360ace9
5 changed files with 176 additions and 0 deletions
|
@ -3320,6 +3320,18 @@ static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
|
||||||
|
struct net_device *dev,
|
||||||
|
const u8 *addr,
|
||||||
|
const struct cfg80211_bitrate_mask *mask)
|
||||||
|
{
|
||||||
|
struct ath6kl *ar = ath6kl_priv(dev);
|
||||||
|
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||||
|
|
||||||
|
return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
|
||||||
|
mask);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ieee80211_txrx_stypes
|
static const struct ieee80211_txrx_stypes
|
||||||
ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
||||||
[NL80211_IFTYPE_STATION] = {
|
[NL80211_IFTYPE_STATION] = {
|
||||||
|
@ -3386,6 +3398,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
|
||||||
.mgmt_frame_register = ath6kl_mgmt_frame_register,
|
.mgmt_frame_register = ath6kl_mgmt_frame_register,
|
||||||
.sched_scan_start = ath6kl_cfg80211_sscan_start,
|
.sched_scan_start = ath6kl_cfg80211_sscan_start,
|
||||||
.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
|
.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
|
||||||
|
.set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
|
void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
|
||||||
|
@ -3616,6 +3629,17 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||||
ath6kl_band_5ghz.ht_cap.cap = 0;
|
ath6kl_band_5ghz.ht_cap.cap = 0;
|
||||||
ath6kl_band_5ghz.ht_cap.ht_supported = false;
|
ath6kl_band_5ghz.ht_cap.ht_supported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) {
|
||||||
|
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||||
|
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||||
|
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||||
|
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||||
|
} else {
|
||||||
|
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||||
|
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
if (band_2gig)
|
if (band_2gig)
|
||||||
wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
|
wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
|
||||||
if (band_5gig)
|
if (band_5gig)
|
||||||
|
|
|
@ -127,6 +127,10 @@ struct ath6kl_fw_ie {
|
||||||
u8 data[0];
|
u8 data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ath6kl_hw_flags {
|
||||||
|
ATH6KL_HW_FLAG_64BIT_RATES = BIT(0),
|
||||||
|
};
|
||||||
|
|
||||||
#define ATH6KL_FW_API2_FILE "fw-2.bin"
|
#define ATH6KL_FW_API2_FILE "fw-2.bin"
|
||||||
#define ATH6KL_FW_API3_FILE "fw-3.bin"
|
#define ATH6KL_FW_API3_FILE "fw-3.bin"
|
||||||
|
|
||||||
|
@ -702,6 +706,8 @@ struct ath6kl {
|
||||||
u32 testscript_addr;
|
u32 testscript_addr;
|
||||||
enum wmi_phy_cap cap;
|
enum wmi_phy_cap cap;
|
||||||
|
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
struct ath6kl_hw_fw {
|
struct ath6kl_hw_fw {
|
||||||
const char *dir;
|
const char *dir;
|
||||||
const char *otp;
|
const char *otp;
|
||||||
|
|
|
@ -42,6 +42,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||||
.reserved_ram_size = 6912,
|
.reserved_ram_size = 6912,
|
||||||
.refclk_hz = 26000000,
|
.refclk_hz = 26000000,
|
||||||
.uarttx_pin = 8,
|
.uarttx_pin = 8,
|
||||||
|
.flags = 0,
|
||||||
|
|
||||||
/* hw2.0 needs override address hardcoded */
|
/* hw2.0 needs override address hardcoded */
|
||||||
.app_start_override_addr = 0x944C00,
|
.app_start_override_addr = 0x944C00,
|
||||||
|
@ -67,6 +68,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||||
.refclk_hz = 26000000,
|
.refclk_hz = 26000000,
|
||||||
.uarttx_pin = 8,
|
.uarttx_pin = 8,
|
||||||
.testscript_addr = 0x57ef74,
|
.testscript_addr = 0x57ef74,
|
||||||
|
.flags = 0,
|
||||||
|
|
||||||
.fw = {
|
.fw = {
|
||||||
.dir = AR6003_HW_2_1_1_FW_DIR,
|
.dir = AR6003_HW_2_1_1_FW_DIR,
|
||||||
|
@ -91,6 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||||
.board_addr = 0x433900,
|
.board_addr = 0x433900,
|
||||||
.refclk_hz = 26000000,
|
.refclk_hz = 26000000,
|
||||||
.uarttx_pin = 11,
|
.uarttx_pin = 11,
|
||||||
|
.flags = ATH6KL_HW_FLAG_64BIT_RATES,
|
||||||
|
|
||||||
.fw = {
|
.fw = {
|
||||||
.dir = AR6004_HW_1_0_FW_DIR,
|
.dir = AR6004_HW_1_0_FW_DIR,
|
||||||
|
@ -110,6 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||||
.board_addr = 0x43d400,
|
.board_addr = 0x43d400,
|
||||||
.refclk_hz = 40000000,
|
.refclk_hz = 40000000,
|
||||||
.uarttx_pin = 11,
|
.uarttx_pin = 11,
|
||||||
|
.flags = ATH6KL_HW_FLAG_64BIT_RATES,
|
||||||
|
|
||||||
.fw = {
|
.fw = {
|
||||||
.dir = AR6004_HW_1_1_FW_DIR,
|
.dir = AR6004_HW_1_1_FW_DIR,
|
||||||
|
@ -129,6 +133,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||||
.board_addr = 0x435c00,
|
.board_addr = 0x435c00,
|
||||||
.refclk_hz = 40000000,
|
.refclk_hz = 40000000,
|
||||||
.uarttx_pin = 11,
|
.uarttx_pin = 11,
|
||||||
|
.flags = ATH6KL_HW_FLAG_64BIT_RATES,
|
||||||
|
|
||||||
.fw = {
|
.fw = {
|
||||||
.dir = AR6004_HW_1_2_FW_DIR,
|
.dir = AR6004_HW_1_2_FW_DIR,
|
||||||
|
|
|
@ -2599,6 +2599,115 @@ static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi)
|
||||||
spin_unlock_bh(&wmi->lock);
|
spin_unlock_bh(&wmi->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx,
|
||||||
|
const struct cfg80211_bitrate_mask *mask)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int ret, mode, band;
|
||||||
|
u64 mcsrate, ratemask[IEEE80211_NUM_BANDS];
|
||||||
|
struct wmi_set_tx_select_rates64_cmd *cmd;
|
||||||
|
|
||||||
|
memset(&ratemask, 0, sizeof(ratemask));
|
||||||
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||||
|
/* copy legacy rate mask */
|
||||||
|
ratemask[band] = mask->control[band].legacy;
|
||||||
|
if (band == IEEE80211_BAND_5GHZ)
|
||||||
|
ratemask[band] =
|
||||||
|
mask->control[band].legacy << 4;
|
||||||
|
|
||||||
|
/* copy mcs rate mask */
|
||||||
|
mcsrate = mask->control[band].mcs[1];
|
||||||
|
mcsrate <<= 8;
|
||||||
|
mcsrate |= mask->control[band].mcs[0];
|
||||||
|
ratemask[band] |= mcsrate << 12;
|
||||||
|
ratemask[band] |= mcsrate << 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||||
|
"Ratemask 64 bit: 2.4:%llx 5:%llx\n",
|
||||||
|
ratemask[0], ratemask[1]);
|
||||||
|
|
||||||
|
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX);
|
||||||
|
if (!skb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
cmd = (struct wmi_set_tx_select_rates64_cmd *) skb->data;
|
||||||
|
for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) {
|
||||||
|
/* A mode operate in 5GHZ band */
|
||||||
|
if (mode == WMI_RATES_MODE_11A ||
|
||||||
|
mode == WMI_RATES_MODE_11A_HT20 ||
|
||||||
|
mode == WMI_RATES_MODE_11A_HT40)
|
||||||
|
band = IEEE80211_BAND_5GHZ;
|
||||||
|
else
|
||||||
|
band = IEEE80211_BAND_2GHZ;
|
||||||
|
cmd->ratemask[mode] = cpu_to_le64(ratemask[band]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
|
||||||
|
WMI_SET_TX_SELECT_RATES_CMDID,
|
||||||
|
NO_SYNC_WMIFLAG);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx,
|
||||||
|
const struct cfg80211_bitrate_mask *mask)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int ret, mode, band;
|
||||||
|
u32 mcsrate, ratemask[IEEE80211_NUM_BANDS];
|
||||||
|
struct wmi_set_tx_select_rates32_cmd *cmd;
|
||||||
|
|
||||||
|
memset(&ratemask, 0, sizeof(ratemask));
|
||||||
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||||
|
/* copy legacy rate mask */
|
||||||
|
ratemask[band] = mask->control[band].legacy;
|
||||||
|
if (band == IEEE80211_BAND_5GHZ)
|
||||||
|
ratemask[band] =
|
||||||
|
mask->control[band].legacy << 4;
|
||||||
|
|
||||||
|
/* copy mcs rate mask */
|
||||||
|
mcsrate = mask->control[band].mcs[0];
|
||||||
|
ratemask[band] |= mcsrate << 12;
|
||||||
|
ratemask[band] |= mcsrate << 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||||
|
"Ratemask 32 bit: 2.4:%x 5:%x\n",
|
||||||
|
ratemask[0], ratemask[1]);
|
||||||
|
|
||||||
|
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX);
|
||||||
|
if (!skb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
cmd = (struct wmi_set_tx_select_rates32_cmd *) skb->data;
|
||||||
|
for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) {
|
||||||
|
/* A mode operate in 5GHZ band */
|
||||||
|
if (mode == WMI_RATES_MODE_11A ||
|
||||||
|
mode == WMI_RATES_MODE_11A_HT20 ||
|
||||||
|
mode == WMI_RATES_MODE_11A_HT40)
|
||||||
|
band = IEEE80211_BAND_5GHZ;
|
||||||
|
else
|
||||||
|
band = IEEE80211_BAND_2GHZ;
|
||||||
|
cmd->ratemask[mode] = cpu_to_le32(ratemask[band]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
|
||||||
|
WMI_SET_TX_SELECT_RATES_CMDID,
|
||||||
|
NO_SYNC_WMIFLAG);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
|
||||||
|
const struct cfg80211_bitrate_mask *mask)
|
||||||
|
{
|
||||||
|
struct ath6kl *ar = wmi->parent_dev;
|
||||||
|
|
||||||
|
if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES)
|
||||||
|
return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
|
||||||
|
else
|
||||||
|
return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
|
||||||
|
}
|
||||||
|
|
||||||
int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
|
int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
|
||||||
enum ath6kl_host_mode host_mode)
|
enum ath6kl_host_mode host_mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1063,6 +1063,36 @@ struct wmi_power_params_cmd {
|
||||||
__le16 ps_fail_event_policy;
|
__le16 ps_fail_event_policy;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ratemask for below modes should be passed
|
||||||
|
* to WMI_SET_TX_SELECT_RATES_CMDID.
|
||||||
|
* AR6003 has 32 bit mask for each modes.
|
||||||
|
* First 12 bits for legacy rates, 13 to 20
|
||||||
|
* bits for HT 20 rates and 21 to 28 bits for
|
||||||
|
* HT 40 rates
|
||||||
|
*/
|
||||||
|
enum wmi_mode_phy {
|
||||||
|
WMI_RATES_MODE_11A = 0,
|
||||||
|
WMI_RATES_MODE_11G,
|
||||||
|
WMI_RATES_MODE_11B,
|
||||||
|
WMI_RATES_MODE_11GONLY,
|
||||||
|
WMI_RATES_MODE_11A_HT20,
|
||||||
|
WMI_RATES_MODE_11G_HT20,
|
||||||
|
WMI_RATES_MODE_11A_HT40,
|
||||||
|
WMI_RATES_MODE_11G_HT40,
|
||||||
|
WMI_RATES_MODE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* WMI_SET_TX_SELECT_RATES_CMDID */
|
||||||
|
struct wmi_set_tx_select_rates32_cmd {
|
||||||
|
__le32 ratemask[WMI_RATES_MODE_MAX];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/* WMI_SET_TX_SELECT_RATES_CMDID */
|
||||||
|
struct wmi_set_tx_select_rates64_cmd {
|
||||||
|
__le64 ratemask[WMI_RATES_MODE_MAX];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* WMI_SET_DISC_TIMEOUT_CMDID */
|
/* WMI_SET_DISC_TIMEOUT_CMDID */
|
||||||
struct wmi_disc_timeout_cmd {
|
struct wmi_disc_timeout_cmd {
|
||||||
/* seconds */
|
/* seconds */
|
||||||
|
@ -2547,6 +2577,8 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
|
||||||
__be32 ips0, __be32 ips1);
|
__be32 ips0, __be32 ips1);
|
||||||
int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
|
int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
|
||||||
enum ath6kl_host_mode host_mode);
|
enum ath6kl_host_mode host_mode);
|
||||||
|
int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
|
||||||
|
const struct cfg80211_bitrate_mask *mask);
|
||||||
int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
|
int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
|
||||||
enum ath6kl_wow_mode wow_mode,
|
enum ath6kl_wow_mode wow_mode,
|
||||||
u32 filter, u16 host_req_delay);
|
u32 filter, u16 host_req_delay);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue