.. | .. |
---|
23 | 23 | return 100 - ((bd->phy_stat0 >> 24) & 0xff); |
---|
24 | 24 | } |
---|
25 | 25 | |
---|
| 26 | +struct wcn36xx_rate { |
---|
| 27 | + u16 bitrate; |
---|
| 28 | + u16 mcs_or_legacy_index; |
---|
| 29 | + enum mac80211_rx_encoding encoding; |
---|
| 30 | + enum mac80211_rx_encoding_flags encoding_flags; |
---|
| 31 | + enum rate_info_bw bw; |
---|
| 32 | +}; |
---|
| 33 | + |
---|
| 34 | +/* Buffer descriptor rx_ch field is limited to 5-bit (4+1), a mapping is used |
---|
| 35 | + * for 11A Channels. |
---|
| 36 | + */ |
---|
| 37 | +static const u8 ab_rx_ch_map[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, |
---|
| 38 | + 108, 112, 116, 120, 124, 128, 132, 136, 140, |
---|
| 39 | + 149, 153, 157, 161, 165, 144 }; |
---|
| 40 | + |
---|
| 41 | +static const struct wcn36xx_rate wcn36xx_rate_table[] = { |
---|
| 42 | + /* 11b rates */ |
---|
| 43 | + { 10, 0, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 44 | + { 20, 1, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 45 | + { 55, 2, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 46 | + { 110, 3, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 47 | + |
---|
| 48 | + /* 11b SP (short preamble) */ |
---|
| 49 | + { 10, 0, RX_ENC_LEGACY, RX_ENC_FLAG_SHORTPRE, RATE_INFO_BW_20 }, |
---|
| 50 | + { 20, 1, RX_ENC_LEGACY, RX_ENC_FLAG_SHORTPRE, RATE_INFO_BW_20 }, |
---|
| 51 | + { 55, 2, RX_ENC_LEGACY, RX_ENC_FLAG_SHORTPRE, RATE_INFO_BW_20 }, |
---|
| 52 | + { 110, 3, RX_ENC_LEGACY, RX_ENC_FLAG_SHORTPRE, RATE_INFO_BW_20 }, |
---|
| 53 | + |
---|
| 54 | + /* 11ag */ |
---|
| 55 | + { 60, 4, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 56 | + { 90, 5, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 57 | + { 120, 6, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 58 | + { 180, 7, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 59 | + { 240, 8, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 60 | + { 360, 9, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 61 | + { 480, 10, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 62 | + { 540, 11, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, |
---|
| 63 | + |
---|
| 64 | + /* 11n */ |
---|
| 65 | + { 65, 0, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 66 | + { 130, 1, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 67 | + { 195, 2, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 68 | + { 260, 3, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 69 | + { 390, 4, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 70 | + { 520, 5, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 71 | + { 585, 6, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 72 | + { 650, 7, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 73 | + |
---|
| 74 | + /* 11n SGI */ |
---|
| 75 | + { 72, 0, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 76 | + { 144, 1, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 77 | + { 217, 2, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 78 | + { 289, 3, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 79 | + { 434, 4, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 80 | + { 578, 5, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 81 | + { 650, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 82 | + { 722, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 83 | + |
---|
| 84 | + /* 11n GF (greenfield) */ |
---|
| 85 | + { 65, 0, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 86 | + { 130, 1, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 87 | + { 195, 2, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 88 | + { 260, 3, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 89 | + { 390, 4, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 90 | + { 520, 5, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 91 | + { 585, 6, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 92 | + { 650, 7, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_20 }, |
---|
| 93 | + |
---|
| 94 | + /* 11n CB (channel bonding) */ |
---|
| 95 | + { 135, 0, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 96 | + { 270, 1, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 97 | + { 405, 2, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 98 | + { 540, 3, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 99 | + { 810, 4, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 100 | + { 1080, 5, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 101 | + { 1215, 6, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 102 | + { 1350, 7, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 103 | + |
---|
| 104 | + /* 11n CB + SGI */ |
---|
| 105 | + { 150, 0, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 106 | + { 300, 1, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 107 | + { 450, 2, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 108 | + { 600, 3, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 109 | + { 900, 4, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 110 | + { 1200, 5, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 111 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 112 | + { 1500, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 113 | + |
---|
| 114 | + /* 11n GF + CB */ |
---|
| 115 | + { 135, 0, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 116 | + { 270, 1, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 117 | + { 405, 2, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 118 | + { 540, 3, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 119 | + { 810, 4, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 120 | + { 1080, 5, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 121 | + { 1215, 6, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 122 | + { 1350, 7, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 }, |
---|
| 123 | + |
---|
| 124 | + /* 11ac reserved indices */ |
---|
| 125 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 126 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 127 | + |
---|
| 128 | + /* 11ac 20 MHz 800ns GI MCS 0-8 */ |
---|
| 129 | + { 65, 0, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 130 | + { 130, 1, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 131 | + { 195, 2, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 132 | + { 260, 3, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 133 | + { 390, 4, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 134 | + { 520, 5, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 135 | + { 585, 6, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 136 | + { 650, 7, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 137 | + { 780, 8, RX_ENC_HT, 0, RATE_INFO_BW_20 }, |
---|
| 138 | + |
---|
| 139 | + /* 11ac reserved indices */ |
---|
| 140 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 141 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 142 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 143 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 144 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 145 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 146 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 147 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 148 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 149 | + |
---|
| 150 | + /* 11ac 20 MHz 400ns SGI MCS 6-8 */ |
---|
| 151 | + { 655, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 152 | + { 722, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 153 | + { 866, 8, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 }, |
---|
| 154 | + |
---|
| 155 | + /* 11ac reserved indices */ |
---|
| 156 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 157 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 158 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 159 | + |
---|
| 160 | + /* 11ac 40 MHz 800ns GI MCS 0-9 */ |
---|
| 161 | + { 135, 0, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 162 | + { 270, 1, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 163 | + { 405, 2, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 164 | + { 540, 3, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 165 | + { 810, 4, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 166 | + { 1080, 5, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 167 | + { 1215, 6, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 168 | + { 1350, 7, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 169 | + { 1350, 7, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 170 | + { 1620, 8, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 171 | + { 1800, 9, RX_ENC_HT, 0, RATE_INFO_BW_40 }, |
---|
| 172 | + |
---|
| 173 | + /* 11ac reserved indices */ |
---|
| 174 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 175 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 176 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 177 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 178 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 179 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 180 | + |
---|
| 181 | + /* 11ac 40 MHz 400ns SGI MCS 5-7 */ |
---|
| 182 | + { 1200, 5, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 183 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 184 | + { 1500, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 185 | + |
---|
| 186 | + /* 11ac reserved index */ |
---|
| 187 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 188 | + |
---|
| 189 | + /* 11ac 40 MHz 400ns SGI MCS 5-7 */ |
---|
| 190 | + { 1800, 8, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 191 | + { 2000, 9, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 192 | + |
---|
| 193 | + /* 11ac reserved index */ |
---|
| 194 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 195 | + |
---|
| 196 | + /* 11ac 80 MHz 800ns GI MCS 0-7 */ |
---|
| 197 | + { 292, 0, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 198 | + { 585, 1, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 199 | + { 877, 2, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 200 | + { 1170, 3, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 201 | + { 1755, 4, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 202 | + { 2340, 5, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 203 | + { 2632, 6, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 204 | + { 2925, 7, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 205 | + |
---|
| 206 | + /* 11 ac reserved index */ |
---|
| 207 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 208 | + |
---|
| 209 | + /* 11ac 80 MHz 800 ns GI MCS 8-9 */ |
---|
| 210 | + { 3510, 8, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 211 | + { 3900, 9, RX_ENC_HT, 0, RATE_INFO_BW_80}, |
---|
| 212 | + |
---|
| 213 | + /* 11 ac reserved indices */ |
---|
| 214 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 215 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 216 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 217 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 218 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 219 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 220 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 221 | + |
---|
| 222 | + /* 11ac 80 MHz 400 ns SGI MCS 6-7 */ |
---|
| 223 | + { 2925, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 }, |
---|
| 224 | + { 3250, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 }, |
---|
| 225 | + |
---|
| 226 | + /* 11ac reserved index */ |
---|
| 227 | + { 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 }, |
---|
| 228 | + |
---|
| 229 | + /* 11ac 80 MHz 400ns SGI MCS 8-9 */ |
---|
| 230 | + { 3900, 8, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 }, |
---|
| 231 | + { 4333, 9, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 }, |
---|
| 232 | +}; |
---|
| 233 | + |
---|
26 | 234 | int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) |
---|
27 | 235 | { |
---|
28 | 236 | struct ieee80211_rx_status status; |
---|
| 237 | + const struct wcn36xx_rate *rate; |
---|
29 | 238 | struct ieee80211_hdr *hdr; |
---|
30 | 239 | struct wcn36xx_rx_bd *bd; |
---|
31 | 240 | u16 fc, sn; |
---|
.. | .. |
---|
49 | 258 | fc = __le16_to_cpu(hdr->frame_control); |
---|
50 | 259 | sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl)); |
---|
51 | 260 | |
---|
52 | | - /* When scanning associate beacons to this */ |
---|
53 | | - if (ieee80211_is_beacon(hdr->frame_control) && wcn->scan_freq) { |
---|
54 | | - status.freq = wcn->scan_freq; |
---|
55 | | - status.band = wcn->scan_band; |
---|
56 | | - } else { |
---|
57 | | - status.freq = WCN36XX_CENTER_FREQ(wcn); |
---|
58 | | - status.band = WCN36XX_BAND(wcn); |
---|
59 | | - } |
---|
60 | | - |
---|
61 | 261 | status.mactime = 10; |
---|
62 | 262 | status.signal = -get_rssi0(bd); |
---|
63 | 263 | status.antenna = 1; |
---|
64 | | - status.rate_idx = 1; |
---|
65 | 264 | status.flag = 0; |
---|
66 | 265 | status.rx_flags = 0; |
---|
67 | 266 | status.flag |= RX_FLAG_IV_STRIPPED | |
---|
.. | .. |
---|
69 | 268 | RX_FLAG_DECRYPTED; |
---|
70 | 269 | |
---|
71 | 270 | wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x\n", status.flag); |
---|
| 271 | + |
---|
| 272 | + if (bd->scan_learn) { |
---|
| 273 | + /* If packet originate from hardware scanning, extract the |
---|
| 274 | + * band/channel from bd descriptor. |
---|
| 275 | + */ |
---|
| 276 | + u8 hwch = (bd->reserved0 << 4) + bd->rx_ch; |
---|
| 277 | + |
---|
| 278 | + if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) { |
---|
| 279 | + status.band = NL80211_BAND_5GHZ; |
---|
| 280 | + status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1], |
---|
| 281 | + status.band); |
---|
| 282 | + } else { |
---|
| 283 | + status.band = NL80211_BAND_2GHZ; |
---|
| 284 | + status.freq = ieee80211_channel_to_frequency(hwch, status.band); |
---|
| 285 | + } |
---|
| 286 | + } else { |
---|
| 287 | + status.band = WCN36XX_BAND(wcn); |
---|
| 288 | + status.freq = WCN36XX_CENTER_FREQ(wcn); |
---|
| 289 | + } |
---|
| 290 | + |
---|
| 291 | + if (bd->rate_id < ARRAY_SIZE(wcn36xx_rate_table)) { |
---|
| 292 | + rate = &wcn36xx_rate_table[bd->rate_id]; |
---|
| 293 | + status.encoding = rate->encoding; |
---|
| 294 | + status.enc_flags = rate->encoding_flags; |
---|
| 295 | + status.bw = rate->bw; |
---|
| 296 | + status.rate_idx = rate->mcs_or_legacy_index; |
---|
| 297 | + status.nss = 1; |
---|
| 298 | + |
---|
| 299 | + if (status.band == NL80211_BAND_5GHZ && |
---|
| 300 | + status.encoding == RX_ENC_LEGACY && |
---|
| 301 | + status.rate_idx >= 4) { |
---|
| 302 | + /* no dsss rates in 5Ghz rates table */ |
---|
| 303 | + status.rate_idx -= 4; |
---|
| 304 | + } |
---|
| 305 | + } else { |
---|
| 306 | + status.encoding = 0; |
---|
| 307 | + status.bw = 0; |
---|
| 308 | + status.enc_flags = 0; |
---|
| 309 | + status.rate_idx = 0; |
---|
| 310 | + } |
---|
| 311 | + |
---|
| 312 | + if (ieee80211_is_beacon(hdr->frame_control) || |
---|
| 313 | + ieee80211_is_probe_resp(hdr->frame_control)) |
---|
| 314 | + status.boottime_ns = ktime_get_boottime_ns(); |
---|
72 | 315 | |
---|
73 | 316 | memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); |
---|
74 | 317 | |
---|
.. | .. |
---|
100 | 343 | bd->pdu.mpdu_header_off; |
---|
101 | 344 | bd->pdu.mpdu_len = len; |
---|
102 | 345 | bd->pdu.tid = tid; |
---|
103 | | - bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_QOS; |
---|
104 | 346 | } |
---|
105 | 347 | |
---|
106 | 348 | static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn, |
---|
.. | .. |
---|
160 | 402 | bool bcast) |
---|
161 | 403 | { |
---|
162 | 404 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
---|
| 405 | + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
---|
163 | 406 | struct ieee80211_vif *vif = NULL; |
---|
164 | 407 | struct wcn36xx_vif *__vif_priv = NULL; |
---|
165 | | - bool is_data_qos; |
---|
| 408 | + bool is_data_qos = ieee80211_is_data_qos(hdr->frame_control); |
---|
| 409 | + u16 tid = 0; |
---|
166 | 410 | |
---|
167 | 411 | bd->bd_rate = WCN36XX_BD_RATE_DATA; |
---|
168 | 412 | |
---|
.. | .. |
---|
191 | 435 | bd->dpu_sign = __vif_priv->self_ucast_dpu_sign; |
---|
192 | 436 | } |
---|
193 | 437 | |
---|
194 | | - if (ieee80211_is_nullfunc(hdr->frame_control) || |
---|
195 | | - (sta_priv && !sta_priv->is_data_encrypted)) |
---|
| 438 | + if (is_data_qos) { |
---|
| 439 | + tid = ieee80211_get_tid(hdr); |
---|
| 440 | + /* TID->QID is one-to-one mapping */ |
---|
| 441 | + bd->queue_id = tid; |
---|
| 442 | + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_QOS; |
---|
| 443 | + } else { |
---|
| 444 | + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; |
---|
| 445 | + } |
---|
| 446 | + |
---|
| 447 | + if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT || |
---|
| 448 | + (sta_priv && !sta_priv->is_data_encrypted)) { |
---|
196 | 449 | bd->dpu_ne = 1; |
---|
| 450 | + } |
---|
| 451 | + |
---|
| 452 | + if (ieee80211_is_any_nullfunc(hdr->frame_control)) { |
---|
| 453 | + /* Don't use a regular queue for null packet (no ampdu) */ |
---|
| 454 | + bd->queue_id = WCN36XX_TX_U_WQ_ID; |
---|
| 455 | + bd->bd_rate = WCN36XX_BD_RATE_CTRL; |
---|
| 456 | + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) |
---|
| 457 | + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST; |
---|
| 458 | + } |
---|
197 | 459 | |
---|
198 | 460 | if (bcast) { |
---|
199 | 461 | bd->ub = 1; |
---|
.. | .. |
---|
201 | 463 | } |
---|
202 | 464 | *vif_priv = __vif_priv; |
---|
203 | 465 | |
---|
204 | | - is_data_qos = ieee80211_is_data_qos(hdr->frame_control); |
---|
205 | | - |
---|
206 | 466 | wcn36xx_set_tx_pdu(bd, |
---|
207 | 467 | is_data_qos ? |
---|
208 | 468 | sizeof(struct ieee80211_qos_hdr) : |
---|
209 | 469 | sizeof(struct ieee80211_hdr_3addr), |
---|
210 | | - skb->len, sta_priv ? sta_priv->tid : 0); |
---|
| 470 | + skb->len, tid); |
---|
211 | 471 | |
---|
212 | 472 | if (sta_priv && is_data_qos) |
---|
213 | 473 | wcn36xx_tx_start_ampdu(wcn, sta_priv, skb); |
---|
.. | .. |
---|
254 | 514 | bd->queue_id = WCN36XX_TX_U_WQ_ID; |
---|
255 | 515 | *vif_priv = __vif_priv; |
---|
256 | 516 | |
---|
| 517 | + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; |
---|
| 518 | + |
---|
257 | 519 | wcn36xx_set_tx_pdu(bd, |
---|
258 | 520 | ieee80211_is_data_qos(hdr->frame_control) ? |
---|
259 | 521 | sizeof(struct ieee80211_qos_hdr) : |
---|
.. | .. |
---|
268 | 530 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
---|
269 | 531 | struct wcn36xx_vif *vif_priv = NULL; |
---|
270 | 532 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
---|
271 | | - unsigned long flags; |
---|
272 | 533 | bool is_low = ieee80211_is_data(hdr->frame_control); |
---|
273 | 534 | bool bcast = is_broadcast_ether_addr(hdr->addr1) || |
---|
274 | 535 | is_multicast_ether_addr(hdr->addr1); |
---|
| 536 | + bool ack_ind = (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && |
---|
| 537 | + !(info->flags & IEEE80211_TX_CTL_NO_ACK); |
---|
275 | 538 | struct wcn36xx_tx_bd bd; |
---|
276 | 539 | int ret; |
---|
277 | 540 | |
---|
.. | .. |
---|
287 | 550 | |
---|
288 | 551 | bd.dpu_rf = WCN36XX_BMU_WQ_TX; |
---|
289 | 552 | |
---|
290 | | - bd.tx_comp = !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); |
---|
291 | | - if (bd.tx_comp) { |
---|
| 553 | + if (unlikely(ack_ind)) { |
---|
292 | 554 | wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); |
---|
293 | | - spin_lock_irqsave(&wcn->dxe_lock, flags); |
---|
294 | | - if (wcn->tx_ack_skb) { |
---|
295 | | - spin_unlock_irqrestore(&wcn->dxe_lock, flags); |
---|
296 | | - wcn36xx_warn("tx_ack_skb already set\n"); |
---|
297 | | - return -EINVAL; |
---|
298 | | - } |
---|
299 | | - |
---|
300 | | - wcn->tx_ack_skb = skb; |
---|
301 | | - spin_unlock_irqrestore(&wcn->dxe_lock, flags); |
---|
302 | 555 | |
---|
303 | 556 | /* Only one at a time is supported by fw. Stop the TX queues |
---|
304 | 557 | * until the ack status gets back. |
---|
305 | | - * |
---|
306 | | - * TODO: Add watchdog in case FW does not answer |
---|
307 | 558 | */ |
---|
308 | 559 | ieee80211_stop_queues(wcn->hw); |
---|
| 560 | + |
---|
| 561 | + /* Request ack indication from the firmware */ |
---|
| 562 | + bd.tx_comp = 1; |
---|
309 | 563 | } |
---|
310 | 564 | |
---|
311 | 565 | /* Data frames served first*/ |
---|
.. | .. |
---|
319 | 573 | bd.tx_bd_sign = 0xbdbdbdbd; |
---|
320 | 574 | |
---|
321 | 575 | ret = wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low); |
---|
322 | | - if (ret && bd.tx_comp) { |
---|
323 | | - /* If the skb has not been transmitted, |
---|
324 | | - * don't keep a reference to it. |
---|
325 | | - */ |
---|
326 | | - spin_lock_irqsave(&wcn->dxe_lock, flags); |
---|
327 | | - wcn->tx_ack_skb = NULL; |
---|
328 | | - spin_unlock_irqrestore(&wcn->dxe_lock, flags); |
---|
329 | | - |
---|
| 576 | + if (unlikely(ret && ack_ind)) { |
---|
| 577 | + /* If the skb has not been transmitted, resume TX queue */ |
---|
330 | 578 | ieee80211_wake_queues(wcn->hw); |
---|
331 | 579 | } |
---|
332 | 580 | |
---|