developer | abdbf25 | 2023-02-06 16:02:21 +0800 | [diff] [blame] | 1 | diff --git a/eeprom.c b/eeprom.c |
| 2 | index 0a88048b..ea54b7af 100644 |
| 3 | --- a/eeprom.c |
| 4 | +++ b/eeprom.c |
| 5 | @@ -138,6 +138,7 @@ mt76_find_power_limits_node(struct mt76_dev *dev) |
| 6 | { |
| 7 | struct device_node *np = dev->dev->of_node; |
| 8 | const char *const region_names[] = { |
| 9 | + [NL80211_DFS_UNSET] = "ww", |
| 10 | [NL80211_DFS_ETSI] = "etsi", |
| 11 | [NL80211_DFS_FCC] = "fcc", |
| 12 | [NL80211_DFS_JP] = "jp", |
| 13 | diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c |
| 14 | index 614df85e..aed4ee95 100644 |
| 15 | --- a/mt76_connac_mac.c |
| 16 | +++ b/mt76_connac_mac.c |
| 17 | @@ -823,7 +823,6 @@ void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev, |
| 18 | HE_BITS(DATA2_TXOP_KNOWN), |
| 19 | }; |
| 20 | u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1; |
| 21 | - u32 txbf_mask = is_mt7996(dev) ? BIT(11) : BIT(10); |
| 22 | struct ieee80211_radiotap_he *he; |
| 23 | |
| 24 | status->flag |= RX_FLAG_RADIOTAP_HE; |
| 25 | @@ -837,7 +836,7 @@ void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev, |
| 26 | he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) | |
| 27 | le16_encode_bits(ltf_size, |
| 28 | IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); |
| 29 | - if (le32_to_cpu(rxv[0]) & txbf_mask) |
| 30 | + if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) |
| 31 | he->data5 |= HE_BITS(DATA5_TXBF); |
| 32 | he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) | |
| 33 | HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]); |
| 34 | diff --git a/mt76x0/usb_mcu.c b/mt76x0/usb_mcu.c |
| 35 | index 45502fd4..6dc1f51f 100644 |
| 36 | --- a/mt76x0/usb_mcu.c |
| 37 | +++ b/mt76x0/usb_mcu.c |
| 38 | @@ -148,6 +148,7 @@ static int mt76x0u_load_firmware(struct mt76x02_dev *dev) |
| 39 | mt76_wr(dev, MT_USB_DMA_CFG, val); |
| 40 | |
| 41 | ret = mt76x0u_upload_firmware(dev, hdr); |
| 42 | + mt76x02_set_ethtool_fwver(dev, hdr); |
| 43 | release_firmware(fw); |
| 44 | |
| 45 | mt76_wr(dev, MT_FCE_PSE_CTRL, 1); |
| 46 | diff --git a/mt7996/mac.c b/mt7996/mac.c |
| 47 | index 674cea1a..c9a9f0e3 100644 |
| 48 | --- a/mt7996/mac.c |
| 49 | +++ b/mt7996/mac.c |
| 50 | @@ -12,6 +12,10 @@ |
| 51 | |
| 52 | #define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2) |
| 53 | |
| 54 | +#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) |
| 55 | +#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\ |
| 56 | + IEEE80211_RADIOTAP_HE_##f) |
| 57 | + |
| 58 | static const struct mt7996_dfs_radar_spec etsi_radar_specs = { |
| 59 | .pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 }, |
| 60 | .radar_pattern = { |
| 61 | @@ -251,6 +255,178 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev, |
| 62 | mt76_clear(dev, addr, BIT(5)); |
| 63 | } |
| 64 | |
| 65 | +static void |
| 66 | +mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, |
| 67 | + struct ieee80211_radiotap_he *he, |
| 68 | + __le32 *rxv) |
| 69 | +{ |
| 70 | + u32 ru_h, ru_l; |
| 71 | + u8 ru, offs = 0; |
| 72 | + |
| 73 | + ru_l = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC_L); |
| 74 | + ru_h = le32_get_bits(rxv[1], MT_PRXV_HE_RU_ALLOC_H); |
| 75 | + ru = (u8)(ru_l | ru_h << 4); |
| 76 | + |
| 77 | + status->bw = RATE_INFO_BW_HE_RU; |
| 78 | + |
| 79 | + switch (ru) { |
| 80 | + case 0 ... 36: |
| 81 | + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; |
| 82 | + offs = ru; |
| 83 | + break; |
| 84 | + case 37 ... 52: |
| 85 | + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; |
| 86 | + offs = ru - 37; |
| 87 | + break; |
| 88 | + case 53 ... 60: |
| 89 | + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; |
| 90 | + offs = ru - 53; |
| 91 | + break; |
| 92 | + case 61 ... 64: |
| 93 | + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; |
| 94 | + offs = ru - 61; |
| 95 | + break; |
| 96 | + case 65 ... 66: |
| 97 | + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; |
| 98 | + offs = ru - 65; |
| 99 | + break; |
| 100 | + case 67: |
| 101 | + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; |
| 102 | + break; |
| 103 | + case 68: |
| 104 | + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; |
| 105 | + break; |
| 106 | + } |
| 107 | + |
| 108 | + he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| 109 | + he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) | |
| 110 | + le16_encode_bits(offs, |
| 111 | + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); |
| 112 | +} |
| 113 | + |
| 114 | +static void |
| 115 | +mt7996_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv) |
| 116 | +{ |
| 117 | + struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; |
| 118 | + static const struct ieee80211_radiotap_he_mu mu_known = { |
| 119 | + .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | |
| 120 | + HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | |
| 121 | + HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | |
| 122 | + HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN), |
| 123 | + .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), |
| 124 | + }; |
| 125 | + struct ieee80211_radiotap_he_mu *he_mu = NULL; |
| 126 | + |
| 127 | + status->flag |= RX_FLAG_RADIOTAP_HE_MU; |
| 128 | + |
| 129 | + he_mu = skb_push(skb, sizeof(mu_known)); |
| 130 | + memcpy(he_mu, &mu_known, sizeof(mu_known)); |
| 131 | + |
| 132 | +#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) |
| 133 | + |
| 134 | + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); |
| 135 | + if (status->he_dcm) |
| 136 | + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); |
| 137 | + |
| 138 | + he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | |
| 139 | + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, |
| 140 | + le32_get_bits(rxv[2], MT_CRXV_HE_NUM_USER)); |
| 141 | + |
| 142 | + he_mu->ru_ch1[0] = le32_get_bits(rxv[3], MT_CRXV_HE_RU0); |
| 143 | + |
| 144 | + if (status->bw >= RATE_INFO_BW_40) { |
| 145 | + he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); |
| 146 | + he_mu->ru_ch2[0] = le32_get_bits(rxv[3], MT_CRXV_HE_RU1); |
| 147 | + } |
| 148 | + |
| 149 | + if (status->bw >= RATE_INFO_BW_80) { |
| 150 | + he_mu->ru_ch1[1] = le32_get_bits(rxv[3], MT_CRXV_HE_RU2); |
| 151 | + he_mu->ru_ch2[1] = le32_get_bits(rxv[3], MT_CRXV_HE_RU3); |
| 152 | + } |
| 153 | +} |
| 154 | + |
| 155 | +static void |
| 156 | +mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode) |
| 157 | +{ |
| 158 | + struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; |
| 159 | + static const struct ieee80211_radiotap_he known = { |
| 160 | + .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | |
| 161 | + HE_BITS(DATA1_DATA_DCM_KNOWN) | |
| 162 | + HE_BITS(DATA1_STBC_KNOWN) | |
| 163 | + HE_BITS(DATA1_CODING_KNOWN) | |
| 164 | + HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | |
| 165 | + HE_BITS(DATA1_DOPPLER_KNOWN) | |
| 166 | + HE_BITS(DATA1_SPTL_REUSE_KNOWN) | |
| 167 | + HE_BITS(DATA1_BSS_COLOR_KNOWN), |
| 168 | + .data2 = HE_BITS(DATA2_GI_KNOWN) | |
| 169 | + HE_BITS(DATA2_TXBF_KNOWN) | |
| 170 | + HE_BITS(DATA2_PE_DISAMBIG_KNOWN) | |
| 171 | + HE_BITS(DATA2_TXOP_KNOWN), |
| 172 | + }; |
| 173 | + struct ieee80211_radiotap_he *he = NULL; |
| 174 | + u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1; |
| 175 | + |
| 176 | + status->flag |= RX_FLAG_RADIOTAP_HE; |
| 177 | + |
| 178 | + he = skb_push(skb, sizeof(known)); |
| 179 | + memcpy(he, &known, sizeof(known)); |
| 180 | + |
| 181 | + he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[14]) | |
| 182 | + HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[2]); |
| 183 | + he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]); |
| 184 | + he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) | |
| 185 | + le16_encode_bits(ltf_size, |
| 186 | + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); |
| 187 | + if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) |
| 188 | + he->data5 |= HE_BITS(DATA5_TXBF); |
| 189 | + he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) | |
| 190 | + HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]); |
| 191 | + |
| 192 | + switch (mode) { |
| 193 | + case MT_PHY_TYPE_HE_SU: |
| 194 | + he->data1 |= HE_BITS(DATA1_FORMAT_SU) | |
| 195 | + HE_BITS(DATA1_UL_DL_KNOWN) | |
| 196 | + HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | |
| 197 | + HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| 198 | + |
| 199 | + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) | |
| 200 | + HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); |
| 201 | + break; |
| 202 | + case MT_PHY_TYPE_HE_EXT_SU: |
| 203 | + he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) | |
| 204 | + HE_BITS(DATA1_UL_DL_KNOWN) | |
| 205 | + HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| 206 | + |
| 207 | + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); |
| 208 | + break; |
| 209 | + case MT_PHY_TYPE_HE_MU: |
| 210 | + he->data1 |= HE_BITS(DATA1_FORMAT_MU) | |
| 211 | + HE_BITS(DATA1_UL_DL_KNOWN); |
| 212 | + |
| 213 | + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); |
| 214 | + he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]); |
| 215 | + |
| 216 | + mt7996_mac_decode_he_radiotap_ru(status, he, rxv); |
| 217 | + mt7996_mac_decode_he_mu_radiotap(skb, rxv); |
| 218 | + break; |
| 219 | + case MT_PHY_TYPE_HE_TB: |
| 220 | + he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | |
| 221 | + HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | |
| 222 | + HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | |
| 223 | + HE_BITS(DATA1_SPTL_REUSE4_KNOWN); |
| 224 | + |
| 225 | + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[11]) | |
| 226 | + HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[11]) | |
| 227 | + HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[11]) | |
| 228 | + HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[11]); |
| 229 | + |
| 230 | + mt7996_mac_decode_he_radiotap_ru(status, he, rxv); |
| 231 | + break; |
| 232 | + default: |
| 233 | + break; |
| 234 | + } |
| 235 | +} |
| 236 | + |
| 237 | /* The HW does not translate the mac header to 802.3 for mesh point */ |
| 238 | static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) |
| 239 | { |
| 240 | @@ -686,8 +862,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) |
| 241 | } |
| 242 | |
| 243 | if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023)) |
| 244 | - mt76_connac2_mac_decode_he_radiotap(&dev->mt76, skb, rxv, |
| 245 | - mode); |
| 246 | + mt7996_mac_decode_he_radiotap(skb, rxv, mode); |
| 247 | |
| 248 | if (!status->wcid || !ieee80211_is_data_qos(fc)) |
| 249 | return 0; |