diff options
Diffstat (limited to 'package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch')
-rw-r--r-- | package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch b/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch new file mode 100644 index 0000000..372ce58 --- /dev/null +++ b/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch @@ -0,0 +1,285 @@ +From: Ben Greear <greearb@candelatech.com> +Date: Thu, 6 Oct 2016 17:34:14 -0700 +Subject: [PATCH] ath10k: Add support for 160Mhz. + +This patch was written by Sebastian Gottschall. + +Signed-off-by: Ben Greear <greearb@candelatech.com> +Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com> +--- + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -702,6 +702,10 @@ static void ath10k_htt_rx_h_rates(struct + /* 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; +@@ -926,7 +930,7 @@ static void ath10k_process_rx(struct ath + *status = *rx_status; + + ath10k_dbg(ar, ATH10K_DBG_DATA, +- "rx skb %pK 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 %pK 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), +@@ -940,6 +944,7 @@ static void ath10k_process_rx(struct ath + 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, +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -568,10 +568,14 @@ chan_to_phymode(const struct cfg80211_ch + 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; + } +@@ -970,6 +974,7 @@ static int ath10k_monitor_vdev_start(str + 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? */ +@@ -1381,6 +1386,7 @@ static int ath10k_vdev_start_restart(str + + 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; +@@ -2444,6 +2450,9 @@ static void ath10k_peer_assoc_h_vht(stru + 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 = +@@ -2545,7 +2554,17 @@ static void ath10k_peer_assoc_h_phymode( + !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; +@@ -4277,6 +4296,10 @@ static struct ieee80211_sta_vht_cap ath1 + 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))) +@@ -6913,6 +6936,9 @@ static void ath10k_sta_rc_update(struct + 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; +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c +@@ -3560,6 +3560,7 @@ static const struct wmi_peer_flags_map w + .vht = WMI_TLV_PEER_VHT, + .bw80 = WMI_TLV_PEER_80MHZ, + .pmf = WMI_TLV_PEER_PMF, ++ .bw160 = WMI_TLV_PEER_160MHZ, + }; + + /************/ +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h +@@ -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 { +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -1576,6 +1576,7 @@ static const struct wmi_peer_flags_map w + .bw80 = WMI_PEER_80MHZ, + .vht_2g = WMI_PEER_VHT_2G, + .pmf = WMI_PEER_PMF, ++ .bw160 = WMI_PEER_160MHZ, + }; + + static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = { +@@ -1593,6 +1594,7 @@ static const struct wmi_peer_flags_map w + .spatial_mux = WMI_10X_PEER_SPATIAL_MUX, + .vht = WMI_10X_PEER_VHT, + .bw80 = WMI_10X_PEER_80MHZ, ++ .bw160 = WMI_10X_PEER_160MHZ, + }; + + static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = { +@@ -1612,6 +1614,7 @@ static const struct wmi_peer_flags_map w + .bw80 = WMI_10_2_PEER_80MHZ, + .vht_2g = WMI_10_2_PEER_VHT_2G, + .pmf = WMI_10_2_PEER_PMF, ++ .bw160 = WMI_10_2_PEER_160MHZ, + }; + + void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, +@@ -1636,7 +1639,10 @@ void ath10k_wmi_put_wmi_channel(struct w + + ch->mhz = __cpu_to_le32(arg->freq); + ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1); +- ch->band_center_freq2 = 0; ++ if (arg->mode == MODE_11AC_VHT80_80) ++ ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2); ++ else ++ ch->band_center_freq2 = 0; + ch->min_power = arg->min_power; + ch->max_power = arg->max_power; + ch->reg_power = arg->max_reg_power; +--- a/drivers/net/wireless/ath/ath10k/wmi.h ++++ b/drivers/net/wireless/ath/ath10k/wmi.h +@@ -1728,8 +1728,10 @@ enum wmi_phy_mode { + MODE_11AC_VHT20_2G = 11, + MODE_11AC_VHT40_2G = 12, + MODE_11AC_VHT80_2G = 13, +- MODE_UNKNOWN = 14, +- MODE_MAX = 14 ++ MODE_11AC_VHT80_80 = 14, ++ MODE_11AC_VHT160 = 15, ++ MODE_UNKNOWN = 16, ++ MODE_MAX = 16 + }; + + static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode) +@@ -1757,6 +1759,10 @@ static inline const char *ath10k_wmi_phy + return "11ac-vht40"; + case MODE_11AC_VHT80: + return "11ac-vht80"; ++ case MODE_11AC_VHT160: ++ return "11ac-vht160"; ++ case MODE_11AC_VHT80_80: ++ return "11ac-vht80+80"; + case MODE_11AC_VHT20_2G: + return "11ac-vht20-2g"; + case MODE_11AC_VHT40_2G: +@@ -1811,6 +1817,7 @@ struct wmi_channel { + struct wmi_channel_arg { + u32 freq; + u32 band_center_freq1; ++ u32 band_center_freq2; + bool passive; + bool allow_ibss; + bool allow_ht; +@@ -1875,9 +1882,18 @@ enum wmi_channel_change_cause { + #define WMI_VHT_CAP_MAX_MPDU_LEN_MASK 0x00000003 + #define WMI_VHT_CAP_RX_LDPC 0x00000010 + #define WMI_VHT_CAP_SGI_80MHZ 0x00000020 ++#define WMI_VHT_CAP_SGI_160MHZ 0x00000040 + #define WMI_VHT_CAP_TX_STBC 0x00000080 + #define WMI_VHT_CAP_RX_STBC_MASK 0x00000300 + #define WMI_VHT_CAP_RX_STBC_MASK_SHIFT 8 ++#define WMI_VHT_CAP_SU_BFER 0x00000800 ++#define WMI_VHT_CAP_SU_BFEE 0x00001000 ++#define WMI_VHT_CAP_MAX_CS_ANT_MASK 0x0000E000 ++#define WMI_VHT_CAP_MAX_CS_ANT_MASK_SHIFT 13 ++#define WMI_VHT_CAP_MAX_SND_DIM_MASK 0x00070000 ++#define WMI_VHT_CAP_MAX_SND_DIM_MASK_SHIFT 16 ++#define WMI_VHT_CAP_MU_BFER 0x00080000 ++#define WMI_VHT_CAP_MU_BFEE 0x00100000 + #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP 0x03800000 + #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT 23 + #define WMI_VHT_CAP_RX_FIXED_ANT 0x10000000 +@@ -1926,6 +1942,8 @@ enum { + REGDMN_MODE_11AC_VHT40PLUS = 0x40000, /* 5Ghz, VHT40 + channels */ + REGDMN_MODE_11AC_VHT40MINUS = 0x80000, /* 5Ghz VHT40 - channels */ + REGDMN_MODE_11AC_VHT80 = 0x100000, /* 5Ghz, VHT80 channels */ ++ REGDMN_MODE_11AC_VHT160 = 0x200000, /* 5Ghz, VHT160 channels */ ++ REGDMN_MODE_11AC_VHT80_80 = 0x400000, /* 5Ghz, VHT80+80 channels */ + REGDMN_MODE_ALL = 0xffffffff + }; + +@@ -5769,6 +5787,7 @@ enum wmi_peer_chwidth { + WMI_PEER_CHWIDTH_20MHZ = 0, + WMI_PEER_CHWIDTH_40MHZ = 1, + WMI_PEER_CHWIDTH_80MHZ = 2, ++ WMI_PEER_CHWIDTH_160MHZ = 3, + }; + + enum wmi_peer_param { +@@ -5859,6 +5878,7 @@ struct wmi_peer_flags_map { + u32 bw80; + u32 vht_2g; + u32 pmf; ++ u32 bw160; + }; + + enum wmi_peer_flags { +@@ -5878,6 +5898,7 @@ enum wmi_peer_flags { + WMI_PEER_80MHZ = 0x04000000, + WMI_PEER_VHT_2G = 0x08000000, + WMI_PEER_PMF = 0x10000000, ++ WMI_PEER_160MHZ = 0x20000000 + }; + + enum wmi_10x_peer_flags { +@@ -5895,6 +5916,7 @@ enum wmi_10x_peer_flags { + WMI_10X_PEER_SPATIAL_MUX = 0x00200000, + WMI_10X_PEER_VHT = 0x02000000, + WMI_10X_PEER_80MHZ = 0x04000000, ++ WMI_10X_PEER_160MHZ = 0x20000000 + }; + + enum wmi_10_2_peer_flags { +@@ -5914,6 +5936,7 @@ enum wmi_10_2_peer_flags { + WMI_10_2_PEER_80MHZ = 0x04000000, + WMI_10_2_PEER_VHT_2G = 0x08000000, + WMI_10_2_PEER_PMF = 0x10000000, ++ WMI_10_2_PEER_160MHZ = 0x20000000 + }; + + /* |