1 /* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org> 6 * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/cdefs.h> 22 #include "opt_wlan.h" 23 24 #include <sys/param.h> 25 #include <sys/lock.h> 26 #include <sys/mutex.h> 27 #include <sys/mbuf.h> 28 #include <sys/kernel.h> 29 #include <sys/socket.h> 30 #include <sys/systm.h> 31 #include <sys/malloc.h> 32 #include <sys/queue.h> 33 #include <sys/taskqueue.h> 34 #include <sys/bus.h> 35 #include <sys/endian.h> 36 #include <sys/linker.h> 37 38 #include <net/if.h> 39 #include <net/ethernet.h> 40 #include <net/if_media.h> 41 42 #include <net80211/ieee80211_var.h> 43 #include <net80211/ieee80211_radiotap.h> 44 45 #include <dev/rtwn/if_rtwnreg.h> 46 #include <dev/rtwn/if_rtwnvar.h> 47 48 #include <dev/rtwn/if_rtwn_ridx.h> 49 #include <dev/rtwn/if_rtwn_tx.h> 50 51 #include <dev/rtwn/rtl8192c/r92c.h> 52 #include <dev/rtwn/rtl8192c/r92c_var.h> 53 #include <dev/rtwn/rtl8192c/r92c_tx_desc.h> 54 55 static int 56 r92c_tx_get_sco(struct rtwn_softc *sc, struct ieee80211_channel *c) 57 { 58 if (IEEE80211_IS_CHAN_HT40U(c)) 59 return (R92C_TXDW4_SCO_SCA); 60 else 61 return (R92C_TXDW4_SCO_SCB); 62 } 63 64 static void 65 r92c_tx_set_ht40(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni) 66 { 67 struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf; 68 69 if (ieee80211_ht_check_tx_ht40(ni)) { 70 int extc_offset; 71 72 extc_offset = r92c_tx_get_sco(sc, ni->ni_chan); 73 txd->txdw4 |= htole32(R92C_TXDW4_DATA_BW40); 74 txd->txdw4 |= htole32(SM(R92C_TXDW4_DATA_SCO, extc_offset)); 75 } 76 } 77 78 static void 79 r92c_tx_protection(struct rtwn_softc *sc, struct r92c_tx_desc *txd, 80 enum ieee80211_protmode mode, uint8_t ridx, bool force_rate) 81 { 82 struct ieee80211com *ic = &sc->sc_ic; 83 uint8_t rate; 84 bool use_fw_ratectl; 85 86 use_fw_ratectl = 87 (sc->sc_ratectl == RTWN_RATECTL_FW && !force_rate); 88 89 switch (mode) { 90 case IEEE80211_PROT_CTSONLY: 91 txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF); 92 break; 93 case IEEE80211_PROT_RTSCTS: 94 txd->txdw4 |= htole32(R92C_TXDW4_RTSEN); 95 break; 96 default: 97 break; 98 } 99 100 if (mode == IEEE80211_PROT_CTSONLY || 101 mode == IEEE80211_PROT_RTSCTS) { 102 if (use_fw_ratectl) { 103 /* 104 * If we're not forcing the driver rate then this 105 * field actually doesn't matter; what matters is 106 * the RRSR and INIRTS configuration. 107 */ 108 ridx = RTWN_RIDX_OFDM24; 109 } else if (RTWN_RATE_IS_HT(ridx)) { 110 rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx); 111 ridx = rate2ridx(IEEE80211_RV(rate)); 112 } else { 113 rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]); 114 ridx = rate2ridx(IEEE80211_RV(rate)); 115 } 116 117 txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, ridx)); 118 /* RTS rate fallback limit (max). */ 119 txd->txdw5 |= htole32(SM(R92C_TXDW5_RTSRATE_FB_LMT, 0xf)); 120 121 if (!use_fw_ratectl && RTWN_RATE_IS_CCK(ridx) && 122 ridx != RTWN_RIDX_CCK1 && 123 (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 124 txd->txdw4 |= htole32(R92C_TXDW4_RTS_SHORT); 125 } 126 } 127 128 static void 129 r92c_tx_raid(struct rtwn_softc *sc, struct r92c_tx_desc *txd, 130 struct ieee80211_node *ni, int ismcast) 131 { 132 struct ieee80211com *ic = &sc->sc_ic; 133 struct ieee80211vap *vap = ni->ni_vap; 134 struct ieee80211_channel *chan; 135 enum ieee80211_phymode mode; 136 uint8_t raid; 137 138 chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ? 139 ni->ni_chan : ic->ic_curchan; 140 mode = ieee80211_chan2mode(chan); 141 142 /* NB: group addressed frames are done at 11bg rates for now */ 143 if (ismcast || !(ni->ni_flags & IEEE80211_NODE_HT)) { 144 switch (mode) { 145 case IEEE80211_MODE_11B: 146 case IEEE80211_MODE_11G: 147 break; 148 case IEEE80211_MODE_11NG: 149 mode = IEEE80211_MODE_11G; 150 break; 151 default: 152 device_printf(sc->sc_dev, "unknown mode(1) %d!\n", 153 ic->ic_curmode); 154 return; 155 } 156 } 157 158 switch (mode) { 159 case IEEE80211_MODE_11B: 160 raid = R92C_RAID_11B; 161 break; 162 case IEEE80211_MODE_11G: 163 if (vap->iv_flags & IEEE80211_F_PUREG) 164 raid = R92C_RAID_11G; 165 else 166 raid = R92C_RAID_11BG; 167 break; 168 case IEEE80211_MODE_11NG: 169 if (vap->iv_flags_ht & IEEE80211_FHT_PUREN) 170 raid = R92C_RAID_11N; 171 else 172 raid = R92C_RAID_11BGN; 173 break; 174 default: 175 device_printf(sc->sc_dev, "unknown mode(2) %d!\n", mode); 176 return; 177 } 178 179 txd->txdw1 |= htole32(SM(R92C_TXDW1_RAID, raid)); 180 } 181 182 /* XXX move to device-independent layer */ 183 static void 184 r92c_tx_set_sgi(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni) 185 { 186 struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf; 187 188 /* 189 * Only enable short-GI if we're transmitting in that 190 * width to that node. 191 * 192 * Specifically, do not enable shortgi for 20MHz if 193 * we're attempting to transmit at 40MHz. 194 */ 195 if (ieee80211_ht_check_tx_ht40(ni)) { 196 if (ieee80211_ht_check_tx_shortgi_40(ni)) 197 txd->txdw5 |= htole32(R92C_TXDW5_SGI); 198 } else if (ieee80211_ht_check_tx_ht(ni)) { 199 if (ieee80211_ht_check_tx_shortgi_20(ni)) 200 txd->txdw5 |= htole32(R92C_TXDW5_SGI); 201 } 202 } 203 204 void 205 r92c_tx_enable_ampdu(void *buf, int enable) 206 { 207 struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf; 208 209 if (enable) 210 txd->txdw1 |= htole32(R92C_TXDW1_AGGEN); 211 else 212 txd->txdw1 |= htole32(R92C_TXDW1_AGGBK); 213 } 214 215 void 216 r92c_tx_setup_hwseq(void *buf) 217 { 218 struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf; 219 220 txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ_EN); 221 } 222 223 void 224 r92c_tx_setup_macid(void *buf, int id) 225 { 226 struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf; 227 228 txd->txdw1 |= htole32(SM(R92C_TXDW1_MACID, id)); 229 } 230 231 static int 232 r92c_calculate_tx_agg_window(struct rtwn_softc *sc, 233 const struct ieee80211_node *ni, int tid) 234 { 235 const struct ieee80211_tx_ampdu *tap; 236 int wnd; 237 238 tap = &ni->ni_tx_ampdu[tid]; 239 240 /* 241 * BAW is (MAX_AGG * 2) + 1, hence the /2 here. 242 * Ensure we don't send 0 or more than 64. 243 */ 244 wnd = tap->txa_wnd / 2; 245 if (wnd == 0) 246 wnd = 1; 247 else if (wnd > 0x1f) 248 wnd = 0x1f; 249 250 return (wnd); 251 } 252 253 /* 254 * Check whether to enable the per-packet TX CCX report. 255 * 256 * For chipsets that do the RPT2 reports, enabling the TX 257 * CCX report results in the packet not being counted in 258 * the RPT2 counts. 259 */ 260 static bool 261 r92c_check_enable_ccx_report(struct rtwn_softc *sc, int macid) 262 { 263 if (sc->sc_ratectl != RTWN_RATECTL_NET80211) 264 return false; 265 266 #ifndef RTWN_WITHOUT_UCODE 267 if ((sc->macid_rpt2_max_num != 0) && 268 (macid < sc->macid_rpt2_max_num)) 269 return false; 270 #endif 271 return true; 272 } 273 274 static void 275 r92c_fill_tx_desc_datarate(struct rtwn_softc *sc, struct r92c_tx_desc *txd, 276 uint8_t ridx, bool force_rate) 277 { 278 279 /* Force this rate if needed. */ 280 if (sc->sc_ratectl == RTWN_RATECTL_FW && !force_rate) { 281 txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0)); 282 } else { 283 txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx)); 284 txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE); 285 } 286 287 /* Data rate fallback limit (max). */ 288 txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE_FB_LMT, 0x1f)); 289 } 290 291 static void 292 r92c_fill_tx_desc_shpreamble(struct rtwn_softc *sc, struct r92c_tx_desc *txd, 293 uint8_t ridx, bool force_rate) 294 { 295 const struct ieee80211com *ic = &sc->sc_ic; 296 297 if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 && 298 (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 299 txd->txdw4 |= htole32(R92C_TXDW4_DATA_SHPRE); 300 } 301 302 static enum ieee80211_protmode 303 r92c_tx_get_protmode(struct rtwn_softc *sc, const struct ieee80211vap *vap, 304 const struct ieee80211_node *ni, const struct mbuf *m, 305 uint8_t ridx, bool force_rate) 306 { 307 const struct ieee80211com *ic = &sc->sc_ic; 308 enum ieee80211_protmode prot; 309 310 prot = IEEE80211_PROT_NONE; 311 312 /* 313 * If doing firmware rate control, base it the configured channel. 314 * This ensures that for HT operation the RTS/CTS or CTS-to-self 315 * configuration is obeyed. 316 */ 317 if (sc->sc_ratectl == RTWN_RATECTL_FW && !force_rate) { 318 struct ieee80211_channel *chan; 319 enum ieee80211_phymode mode; 320 321 chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ? 322 ni->ni_chan : ic->ic_curchan; 323 mode = ieee80211_chan2mode(chan); 324 if (mode == IEEE80211_MODE_11NG) 325 prot = ic->ic_htprotmode; 326 else if (ic->ic_flags & IEEE80211_F_USEPROT) 327 prot = ic->ic_protmode; 328 } else { 329 if (RTWN_RATE_IS_HT(ridx)) 330 prot = ic->ic_htprotmode; 331 else if (ic->ic_flags & IEEE80211_F_USEPROT) 332 prot = ic->ic_protmode; 333 } 334 335 /* XXX fix last comparison for A-MSDU (in net80211) */ 336 /* XXX A-MPDU? */ 337 if (m->m_pkthdr.len + IEEE80211_CRC_LEN > 338 vap->iv_rtsthreshold && 339 vap->iv_rtsthreshold != IEEE80211_RTS_MAX) 340 prot = IEEE80211_PROT_RTSCTS; 341 342 return (prot); 343 } 344 345 void 346 r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni, 347 struct mbuf *m, void *buf, uint8_t ridx, bool force_rate, int maxretry) 348 { 349 #ifndef RTWN_WITHOUT_UCODE 350 struct r92c_softc *rs = sc->sc_priv; 351 #endif 352 struct ieee80211vap *vap = ni->ni_vap; 353 struct rtwn_vap *uvp = RTWN_VAP(vap); 354 struct ieee80211_frame *wh; 355 struct r92c_tx_desc *txd; 356 enum ieee80211_protmode prot; 357 uint8_t type, tid, qos, qsel; 358 int hasqos, ismcast, macid; 359 360 wh = mtod(m, struct ieee80211_frame *); 361 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 362 hasqos = IEEE80211_QOS_HAS_SEQ(wh); 363 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 364 365 /* Select TX ring for this frame. */ 366 if (hasqos) { 367 qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; 368 tid = qos & IEEE80211_QOS_TID; 369 } else { 370 qos = 0; 371 tid = 0; 372 } 373 374 /* Fill Tx descriptor. */ 375 txd = (struct r92c_tx_desc *)buf; 376 txd->flags0 |= R92C_FLAGS0_LSG | R92C_FLAGS0_FSG; 377 if (ismcast) 378 txd->flags0 |= R92C_FLAGS0_BMCAST; 379 380 if (IEEE80211_IS_QOSDATA(wh)) 381 txd->txdw4 |= htole32(R92C_TXDW4_QOS); 382 383 if (!ismcast) { 384 struct rtwn_node *un = RTWN_NODE(ni); 385 macid = un->id; 386 387 /* Unicast frame, check if an ACK is expected. */ 388 if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) != 389 IEEE80211_QOS_ACKPOLICY_NOACK) { 390 txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA); 391 txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT, 392 maxretry)); 393 } 394 395 if (type == IEEE80211_FC0_TYPE_DATA) { 396 qsel = tid % RTWN_MAX_TID; 397 398 rtwn_r92c_tx_enable_ampdu(sc, buf, 399 (m->m_flags & M_AMPDU_MPDU) != 0); 400 if (m->m_flags & M_AMPDU_MPDU) { 401 txd->txdw2 |= htole32(SM(R92C_TXDW2_AMPDU_DEN, 402 ieee80211_ht_get_node_ampdu_density(ni))); 403 txd->txdw6 |= htole32(SM(R92C_TXDW6_MAX_AGG, 404 r92c_calculate_tx_agg_window(sc, ni, tid))); 405 } 406 if (r92c_check_enable_ccx_report(sc, macid)) { 407 txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT); 408 sc->sc_tx_n_active++; 409 #ifndef RTWN_WITHOUT_UCODE 410 rs->rs_c2h_pending++; 411 #endif 412 } 413 414 r92c_fill_tx_desc_shpreamble(sc, txd, ridx, force_rate); 415 416 prot = r92c_tx_get_protmode(sc, vap, ni, m, ridx, 417 force_rate); 418 419 /* 420 * Note: Firmware rate control will enable short-GI 421 * based on the configured rate mask, however HT40 422 * may not be enabled. 423 */ 424 if (sc->sc_ratectl != RTWN_RATECTL_FW && 425 RTWN_RATE_IS_HT(ridx)) { 426 r92c_tx_set_ht40(sc, txd, ni); 427 r92c_tx_set_sgi(sc, txd, ni); 428 } 429 430 /* NB: checks for ht40 / short bits (set above). */ 431 r92c_tx_protection(sc, txd, prot, ridx, force_rate); 432 } else /* IEEE80211_FC0_TYPE_MGT */ 433 qsel = R92C_TXDW1_QSEL_MGNT; 434 } else { 435 macid = RTWN_MACID_BC; 436 qsel = R92C_TXDW1_QSEL_MGNT; 437 } 438 439 txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, qsel)); 440 441 rtwn_r92c_tx_setup_macid(sc, txd, macid); 442 443 /* Fill in data rate, data retry */ 444 r92c_fill_tx_desc_datarate(sc, txd, ridx, force_rate); 445 446 txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id)); 447 r92c_tx_raid(sc, txd, ni, ismcast); 448 449 if (!hasqos) { 450 /* Use HW sequence numbering for non-QoS frames. */ 451 rtwn_r92c_tx_setup_hwseq(sc, txd); 452 } else { 453 uint16_t seqno; 454 455 if (m->m_flags & M_AMPDU_MPDU) { 456 seqno = ni->ni_txseqs[tid] % IEEE80211_SEQ_RANGE; 457 ni->ni_txseqs[tid]++; 458 } else 459 seqno = M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE; 460 461 /* Set sequence number. */ 462 txd->txdseq = htole16(seqno); 463 } 464 } 465 466 void 467 r92c_fill_tx_desc_raw(struct rtwn_softc *sc, struct ieee80211_node *ni, 468 struct mbuf *m, void *buf, const struct ieee80211_bpf_params *params) 469 { 470 struct ieee80211vap *vap = ni->ni_vap; 471 struct rtwn_vap *uvp = RTWN_VAP(vap); 472 struct ieee80211_frame *wh; 473 struct r92c_tx_desc *txd; 474 uint8_t ridx; 475 int ismcast; 476 477 /* XXX TODO: 11n checks, matching r92c_fill_tx_desc() */ 478 479 wh = mtod(m, struct ieee80211_frame *); 480 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 481 ridx = rate2ridx(params->ibp_rate0); 482 483 /* Fill Tx descriptor. */ 484 txd = (struct r92c_tx_desc *)buf; 485 txd->flags0 |= R92C_FLAGS0_LSG | R92C_FLAGS0_FSG; 486 if (ismcast) 487 txd->flags0 |= R92C_FLAGS0_BMCAST; 488 489 if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) { 490 txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA); 491 txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT, 492 params->ibp_try0)); 493 } 494 if (params->ibp_flags & IEEE80211_BPF_RTS) 495 r92c_tx_protection(sc, txd, IEEE80211_PROT_RTSCTS, ridx, 496 true); 497 if (params->ibp_flags & IEEE80211_BPF_CTS) 498 r92c_tx_protection(sc, txd, IEEE80211_PROT_CTSONLY, ridx, 499 true); 500 501 rtwn_r92c_tx_setup_macid(sc, txd, RTWN_MACID_BC); 502 txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT)); 503 504 /* Set TX rate index. */ 505 r92c_fill_tx_desc_datarate(sc, txd, ridx, true); /* force rate */ 506 txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id)); 507 r92c_tx_raid(sc, txd, ni, ismcast); 508 509 if (!IEEE80211_QOS_HAS_SEQ(wh)) { 510 /* Use HW sequence numbering for non-QoS frames. */ 511 rtwn_r92c_tx_setup_hwseq(sc, txd); 512 } else { 513 /* Set sequence number. */ 514 txd->txdseq |= htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE); 515 } 516 } 517 518 void 519 r92c_fill_tx_desc_null(struct rtwn_softc *sc, void *buf, int is11b, 520 int qos, int id) 521 { 522 struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf; 523 524 txd->flags0 = R92C_FLAGS0_FSG | R92C_FLAGS0_LSG | R92C_FLAGS0_OWN; 525 txd->txdw1 = htole32( 526 SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT)); 527 528 txd->txdw4 = htole32(R92C_TXDW4_DRVRATE); 529 txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, id)); 530 if (is11b) { 531 txd->txdw5 = htole32(SM(R92C_TXDW5_DATARATE, 532 RTWN_RIDX_CCK1)); 533 } else { 534 txd->txdw5 = htole32(SM(R92C_TXDW5_DATARATE, 535 RTWN_RIDX_OFDM6)); 536 } 537 538 if (!qos) { 539 rtwn_r92c_tx_setup_hwseq(sc, txd); 540 } 541 } 542 543 uint8_t 544 r92c_tx_radiotap_flags(const void *buf) 545 { 546 const struct r92c_tx_desc *txd = buf; 547 uint8_t flags; 548 549 flags = 0; 550 if (txd->txdw4 & htole32(R92C_TXDW4_DATA_SHPRE)) 551 flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 552 if (txd->txdw5 & htole32(R92C_TXDW5_SGI)) 553 flags |= IEEE80211_RADIOTAP_F_SHORTGI; 554 return (flags); 555 } 556