Skip to content

Commit

Permalink
ath10k: Add 160Mhz support, tweaks.
Browse files Browse the repository at this point in the history
Update to latest 4.7 CT ath10k driver.  160Mhz patch is from
Sebastian and is un-tested by me.

Signed-off-by: Ben Greear <greearb@candelatech.com>
  • Loading branch information
greearb committed Oct 7, 2016
1 parent cd725d5 commit eca9b02
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 30 deletions.
9 changes: 6 additions & 3 deletions ath10k/core.c
Expand Up @@ -1195,9 +1195,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
goto err;
}

/* Save firmware name so we can display it later. */
strlcpy(ar->normal_mode_fw.fw_file.fw_name, filename,
sizeof(ar->normal_mode_fw.fw_file.fw_name));
/* Save firmware board name so we can display it later. */
strlcpy(ar->normal_mode_fw.fw_file.fw_board_name, filename,
sizeof(ar->normal_mode_fw.fw_file.fw_board_name));

return 0;

Expand Down Expand Up @@ -2294,6 +2294,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
if (ar->eeprom_overrides.rifs_enable_override)
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_RIFS_ENABLE,
ar->eeprom_overrides.rifs_enable_override);
if (ar->eeprom_overrides.wmi_wd_keepalive_ms)
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_WMI_WD,
ar->eeprom_overrides.wmi_wd_keepalive_ms);
}

return 0;
Expand Down
6 changes: 6 additions & 0 deletions ath10k/core.h
Expand Up @@ -758,6 +758,7 @@ enum ath10k_tx_pause_reason {
struct ath10k_fw_file {
const struct firmware *firmware;
char fw_name[100];
char fw_board_name[100];

char fw_version[ETHTOOL_FWVERS_LEN];

Expand Down Expand Up @@ -1116,6 +1117,11 @@ struct ath10k {
bool rifs_enable_override;
u16 max_txpower;
u16 pdev_xretry_th; /* Max failed retries before wifi chip is reset, 10.1 firmware default is 0x40 */
u32 wmi_wd_keepalive_ms; /* 0xFFFFFFFF means disable, otherwise, FW will assert after X ms of not receiving
* a NOP keepalive from the driver. Suggested value is 0xFFFFFFFF, or 8000+.
* 0 means use whatever firmware defaults to (probably 8000).
* Units are actually 1/1024 of a second, but pretty close to ms, at least.
*/
} eeprom_overrides;

/* must be last */
Expand Down
53 changes: 46 additions & 7 deletions ath10k/debug.c
Expand Up @@ -367,12 +367,37 @@ static ssize_t ath10k_read_fwinfo(struct file *file,

mutex_lock(&ar->conf_mutex);

if (len > buf_len)
len = buf_len;

len = snprintf(buf, 1000, "directory: %s\nfirmware: %s\nfwcfg: fwcfg-%s-%s.txt\n",
len = snprintf(buf, buf_len, "directory: %s\nfirmware: %s\nfwcfg: fwcfg-%s-%s.txt\nbus: %s\nfeatures: ",
ar->hw_params.fw.dir, ar->running_fw->fw_file.fw_name,
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev), dev_name(ar->dev));
ath10k_core_get_fw_features_str(ar, buf + len, buf_len - len);

/* Just to be safe */
buf[buf_len - 1] = 0;
len = strlen(buf);

len += snprintf(buf + len, buf_len - len, "\nversion: %s\nhw_rev: ",
ar->hw->wiphy->fw_version);
switch (ar->hw_rev) {
case ATH10K_HW_QCA988X:
len += snprintf(buf + len, buf_len - len, "988x\n");
break;
case ATH10K_HW_QCA6174:
len += snprintf(buf + len, buf_len - len, "6174\n");
break;
case ATH10K_HW_QCA99X0:
len += snprintf(buf + len, buf_len - len, "99x0\n");
break;
case ATH10K_HW_QCA9984:
len += snprintf(buf + len, buf_len - len, "9984\n");
break;
case ATH10K_HW_QCA9377:
len += snprintf(buf + len, buf_len - len, "9377\n");
break;
case ATH10K_HW_QCA4019:
len += snprintf(buf + len, buf_len - len, "4019\n");
break;
}

ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);

Expand Down Expand Up @@ -2946,11 +2971,24 @@ static ssize_t ath10k_write_ct_special(struct file *file,
ar->eeprom_overrides.rifs_enable_override = val;
ath10k_warn(ar, "Setting RIFS enable override to 0x%x\n", val);
}
/* Below here are local driver hacks, and not passed directly to firmware. */
else if (id == SET_SPECIAL_ID_WMI_WD) {
ar->eeprom_overrides.wmi_wd_keepalive_ms = val;
ath10k_warn(ar, "Setting WMI WD to 0x%x\n", val);
if (val == 0)
goto unlock; /* 0 means don't set */

if (val == 0xFFFFFFFF)
val = 0; /* 0xFFFFFFFF means disable, FW uses 0 to mean disable */
}
/* Below here are local driver hacks, and not necessarily passed directly to firmware. */
else if (id == 0x1001) {
/* Set station failed-transmit kickout threshold. */
ar->sta_xretry_kickout_thresh = val;
ath10k_warn(ar, "Setting ar sta-xretry-kickout-thresh to 0x%x\n", val);

ath10k_warn(ar, "Setting pdev sta-xretry-kickout-thresh to 0x%x\n",
val);

ath10k_mac_set_pdev_kickout(ar);
goto unlock;
}
/* else, pass it through to firmware...but will not be stored locally, so
Expand Down Expand Up @@ -2991,6 +3029,7 @@ static ssize_t ath10k_read_ct_special(struct file *file,
"id: 8 STA-TX-BW-MASK, 0: all, 0x1: 20Mhz, 0x2 40Mhz, 0x4 80Mhz \n"
"id: 9 pdev failed retry threshold, U16, 10.1 firmware default is 0x40\n"
"id: 0xA Enable(1)/Disable(0) baseband RIFS. Default is disabled.\n"
"id: 0xB WMI WD Keepalive(ms): 0xFFFFFFFF disables, otherwise suggest 8000+.\n"
"\nBelow here are not actually sent to firmware directly, but configure the driver.\n"
"id: 0x1001 set sta-kickout threshold due to tx-failures (0 means disable. Default is 20 * 16.)\n"
"\n";
Expand Down
13 changes: 12 additions & 1 deletion ath10k/htt_rx.c
Expand Up @@ -707,6 +707,10 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
/* 80MHZ */
case 2:
status->vht_flag |= RX_VHT_FLAG_80MHZ;
break;
case 3:
status->vht_flag |= RX_VHT_FLAG_160MHZ;
break;
}

status->flag |= RX_FLAG_VHT;
Expand Down Expand Up @@ -931,7 +935,7 @@ static void ath10k_process_rx(struct ath10k *ar,
*status = *rx_status;

ath10k_dbg(ar, ATH10K_DBG_DATA,
"rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
"rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
skb,
skb->len,
ieee80211_get_SA(hdr),
Expand All @@ -944,6 +948,7 @@ static void ath10k_process_rx(struct ath10k *ar,
status->flag & RX_FLAG_VHT ? "vht" : "",
status->flag & RX_FLAG_40MHZ ? "40" : "",
status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
status->vht_flag & RX_VHT_FLAG_160MHZ ? "160" : "",
status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
status->rate_idx,
status->vht_nss,
Expand Down Expand Up @@ -1009,6 +1014,12 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
if (unlikely(WARN_ON_ONCE(!(is_first && is_last))))
return;

/* We see zero length msdus, not sure why. At least don't
* try to trim it further.
*/
if (unlikely(msdu->len < 4))
return;

skb_trim(msdu, msdu->len - FCS_LEN);

/* In most cases this will be true for sniffed frames. It makes sense
Expand Down
59 changes: 47 additions & 12 deletions ath10k/mac.c
Expand Up @@ -584,10 +584,14 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
case NL80211_CHAN_WIDTH_80:
phymode = MODE_11AC_VHT80;
break;
case NL80211_CHAN_WIDTH_160:
phymode = MODE_11AC_VHT160;
break;
case NL80211_CHAN_WIDTH_80P80:
phymode = MODE_11AC_VHT80_80;
break;
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
case NL80211_CHAN_WIDTH_80P80:
case NL80211_CHAN_WIDTH_160:
phymode = MODE_UNKNOWN;
break;
}
Expand Down Expand Up @@ -744,21 +748,26 @@ static int ath10k_peer_create(struct ath10k *ar,
return 0;
}

int ath10k_mac_set_pdev_kickout(struct ath10k *ar)
{
u32 param = ar->wmi.pdev_param->sta_kickout_th;
int rv;

rv = ath10k_wmi_pdev_set_param(ar, param,
ar->sta_xretry_kickout_thresh);
if (rv) {
ath10k_warn(ar, "failed to set sta kickout threshold to %d: %d\n",
ar->sta_xretry_kickout_thresh, rv);
}
return rv;
}

static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
{
struct ath10k *ar = arvif->ar;
u32 param;
int ret;

param = ar->wmi.pdev_param->sta_kickout_th;
ret = ath10k_wmi_pdev_set_param(ar, param,
ar->sta_xretry_kickout_thresh);
if (ret) {
ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
arvif->vdev_id, ret);
return ret;
}

param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
ATH10K_KEEPALIVE_MIN_IDLE);
Expand Down Expand Up @@ -1011,6 +1020,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
arg.vdev_id = vdev_id;
arg.channel.freq = channel->center_freq;
arg.channel.band_center_freq1 = chandef->center_freq1;
arg.channel.band_center_freq2 = chandef->center_freq2;

/* TODO setup this dynamically, what in case we
don't have any vifs? */
Expand Down Expand Up @@ -1422,6 +1432,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,

arg.channel.freq = chandef->chan->center_freq;
arg.channel.band_center_freq1 = chandef->center_freq1;
arg.channel.band_center_freq2 = chandef->center_freq2;
arg.channel.mode = chan_to_phymode(chandef);

arg.channel.min_power = 0;
Expand Down Expand Up @@ -2666,6 +2677,9 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
arg->peer_flags |= ar->wmi.peer_flags->bw80;

if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
arg->peer_flags |= ar->wmi.peer_flags->bw160;

arg->peer_vht_rates.rx_max_rate =
__le16_to_cpu(vht_cap->vht_mcs.rx_highest);
arg->peer_vht_rates.rx_mcs_set =
Expand Down Expand Up @@ -2859,7 +2873,17 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
!ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
phymode = MODE_11AC_VHT80;
else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
else if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
phymode = MODE_11AC_VHT160;
switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
phymode = MODE_11AC_VHT160;
break;
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
phymode = MODE_11AC_VHT80_80;
break;
}
} else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
phymode = MODE_11AC_VHT40;
else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
phymode = MODE_11AC_VHT20;
Expand Down Expand Up @@ -4728,6 +4752,10 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
vht_cap.cap |= val;
}

if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) && !(ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) {
vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
}

mcs_map = 0;
for (i = 0; i < 8; i++) {
if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
Expand Down Expand Up @@ -5427,6 +5455,10 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
arvif->peer_id = HTT_INVALID_PEERID;
}

ret = ath10k_mac_set_pdev_kickout(ar);
if (ret)
return ret;

if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
ret = ath10k_mac_set_kickout(arvif);
if (ret) {
Expand Down Expand Up @@ -7486,6 +7518,9 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
bw = WMI_PEER_CHWIDTH_80MHZ;
break;
case IEEE80211_STA_RX_BW_160:
bw = WMI_PEER_CHWIDTH_160MHZ;
break;
default:
ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
sta->bandwidth, sta->addr);
bw = WMI_PEER_CHWIDTH_20MHZ;
Expand Down
2 changes: 2 additions & 0 deletions ath10k/mac.h
Expand Up @@ -113,4 +113,6 @@ static inline void ath10k_tx_h_seq_no(struct ieee80211_vif *vif,
}
}

int ath10k_mac_set_pdev_kickout(struct ath10k *ar);

#endif /* _MAC_H_ */
1 change: 1 addition & 0 deletions ath10k/wmi-tlv.c
Expand Up @@ -3560,6 +3560,7 @@ static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
.vht = WMI_TLV_PEER_VHT,
.bw80 = WMI_TLV_PEER_80MHZ,
.pmf = WMI_TLV_PEER_PMF,
.bw160 = WMI_TLV_PEER_160MHZ,
};

/************/
Expand Down
1 change: 1 addition & 0 deletions ath10k/wmi-tlv.h
Expand Up @@ -543,6 +543,7 @@ enum wmi_tlv_peer_flags {
WMI_TLV_PEER_VHT = 0x02000000,
WMI_TLV_PEER_80MHZ = 0x04000000,
WMI_TLV_PEER_PMF = 0x08000000,
WMI_TLV_PEER_160MHZ = 0x20000000,
};

enum wmi_tlv_tag {
Expand Down

0 comments on commit eca9b02

Please sign in to comment.