main.c revision af44e258108058f30d4d4de1f7af0aff88ea3f4b
1/* 2 * Copyright (c) 2010 Broadcom Corporation 3 * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19 20#include <linux/pci_ids.h> 21#include <linux/if_ether.h> 22#include <net/cfg80211.h> 23#include <net/mac80211.h> 24#include <brcm_hw_ids.h> 25#include <aiutils.h> 26#include <chipcommon.h> 27#include "rate.h" 28#include "scb.h" 29#include "phy/phy_hal.h" 30#include "channel.h" 31#include "antsel.h" 32#include "stf.h" 33#include "ampdu.h" 34#include "mac80211_if.h" 35#include "ucode_loader.h" 36#include "main.h" 37#include "soc.h" 38#include "dma.h" 39#include "debug.h" 40#include "brcms_trace_events.h" 41 42/* watchdog timer, in unit of ms */ 43#define TIMER_INTERVAL_WATCHDOG 1000 44/* radio monitor timer, in unit of ms */ 45#define TIMER_INTERVAL_RADIOCHK 800 46 47/* beacon interval, in unit of 1024TU */ 48#define BEACON_INTERVAL_DEFAULT 100 49 50/* n-mode support capability */ 51/* 2x2 includes both 1x1 & 2x2 devices 52 * reserved #define 2 for future when we want to separate 1x1 & 2x2 and 53 * control it independently 54 */ 55#define WL_11N_2x2 1 56#define WL_11N_3x3 3 57#define WL_11N_4x4 4 58 59#define EDCF_ACI_MASK 0x60 60#define EDCF_ACI_SHIFT 5 61#define EDCF_ECWMIN_MASK 0x0f 62#define EDCF_ECWMAX_SHIFT 4 63#define EDCF_AIFSN_MASK 0x0f 64#define EDCF_AIFSN_MAX 15 65#define EDCF_ECWMAX_MASK 0xf0 66 67#define EDCF_AC_BE_TXOP_STA 0x0000 68#define EDCF_AC_BK_TXOP_STA 0x0000 69#define EDCF_AC_VO_ACI_STA 0x62 70#define EDCF_AC_VO_ECW_STA 0x32 71#define EDCF_AC_VI_ACI_STA 0x42 72#define EDCF_AC_VI_ECW_STA 0x43 73#define EDCF_AC_BK_ECW_STA 0xA4 74#define EDCF_AC_VI_TXOP_STA 0x005e 75#define EDCF_AC_VO_TXOP_STA 0x002f 76#define EDCF_AC_BE_ACI_STA 0x03 77#define EDCF_AC_BE_ECW_STA 0xA4 78#define EDCF_AC_BK_ACI_STA 0x27 79#define EDCF_AC_VO_TXOP_AP 0x002f 80 81#define EDCF_TXOP2USEC(txop) ((txop) << 5) 82#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) 83 84#define APHY_SYMBOL_TIME 4 85#define APHY_PREAMBLE_TIME 16 86#define APHY_SIGNAL_TIME 4 87#define APHY_SIFS_TIME 16 88#define APHY_SERVICE_NBITS 16 89#define APHY_TAIL_NBITS 6 90#define BPHY_SIFS_TIME 10 91#define BPHY_PLCP_SHORT_TIME 96 92 93#define PREN_PREAMBLE 24 94#define PREN_MM_EXT 12 95#define PREN_PREAMBLE_EXT 4 96 97#define DOT11_MAC_HDR_LEN 24 98#define DOT11_ACK_LEN 10 99#define DOT11_BA_LEN 4 100#define DOT11_OFDM_SIGNAL_EXTENSION 6 101#define DOT11_MIN_FRAG_LEN 256 102#define DOT11_RTS_LEN 16 103#define DOT11_CTS_LEN 10 104#define DOT11_BA_BITMAP_LEN 128 105#define DOT11_MAXNUMFRAGS 16 106#define DOT11_MAX_FRAG_LEN 2346 107 108#define BPHY_PLCP_TIME 192 109#define RIFS_11N_TIME 2 110 111/* length of the BCN template area */ 112#define BCN_TMPL_LEN 512 113 114/* brcms_bss_info flag bit values */ 115#define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ 116 117/* chip rx buffer offset */ 118#define BRCMS_HWRXOFF 38 119 120/* rfdisable delay timer 500 ms, runs of ALP clock */ 121#define RFDISABLE_DEFAULT 10000000 122 123#define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ 124 125/* synthpu_dly times in us */ 126#define SYNTHPU_DLY_APHY_US 3700 127#define SYNTHPU_DLY_BPHY_US 1050 128#define SYNTHPU_DLY_NPHY_US 2048 129#define SYNTHPU_DLY_LPPHY_US 300 130 131#define ANTCNT 10 /* vanilla M_MAX_ANTCNT val */ 132 133/* Per-AC retry limit register definitions; uses defs.h bitfield macros */ 134#define EDCF_SHORT_S 0 135#define EDCF_SFB_S 4 136#define EDCF_LONG_S 8 137#define EDCF_LFB_S 12 138#define EDCF_SHORT_M BITFIELD_MASK(4) 139#define EDCF_SFB_M BITFIELD_MASK(4) 140#define EDCF_LONG_M BITFIELD_MASK(4) 141#define EDCF_LFB_M BITFIELD_MASK(4) 142 143#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ 144#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ 145#define RETRY_LONG_DEF 4 /* Default Long retry count */ 146#define RETRY_SHORT_FB 3 /* Short count for fb rate */ 147#define RETRY_LONG_FB 2 /* Long count for fb rate */ 148 149#define APHY_CWMIN 15 150#define PHY_CWMAX 1023 151 152#define EDCF_AIFSN_MIN 1 153 154#define FRAGNUM_MASK 0xF 155 156#define APHY_SLOT_TIME 9 157#define BPHY_SLOT_TIME 20 158 159#define WL_SPURAVOID_OFF 0 160#define WL_SPURAVOID_ON1 1 161#define WL_SPURAVOID_ON2 2 162 163/* invalid core flags, use the saved coreflags */ 164#define BRCMS_USE_COREFLAGS 0xffffffff 165 166/* values for PLCPHdr_override */ 167#define BRCMS_PLCP_AUTO -1 168#define BRCMS_PLCP_SHORT 0 169#define BRCMS_PLCP_LONG 1 170 171/* values for g_protection_override and n_protection_override */ 172#define BRCMS_PROTECTION_AUTO -1 173#define BRCMS_PROTECTION_OFF 0 174#define BRCMS_PROTECTION_ON 1 175#define BRCMS_PROTECTION_MMHDR_ONLY 2 176#define BRCMS_PROTECTION_CTS_ONLY 3 177 178/* values for g_protection_control and n_protection_control */ 179#define BRCMS_PROTECTION_CTL_OFF 0 180#define BRCMS_PROTECTION_CTL_LOCAL 1 181#define BRCMS_PROTECTION_CTL_OVERLAP 2 182 183/* values for n_protection */ 184#define BRCMS_N_PROTECTION_OFF 0 185#define BRCMS_N_PROTECTION_OPTIONAL 1 186#define BRCMS_N_PROTECTION_20IN40 2 187#define BRCMS_N_PROTECTION_MIXEDMODE 3 188 189/* values for band specific 40MHz capabilities */ 190#define BRCMS_N_BW_20ALL 0 191#define BRCMS_N_BW_40ALL 1 192#define BRCMS_N_BW_20IN2G_40IN5G 2 193 194/* bitflags for SGI support (sgi_rx iovar) */ 195#define BRCMS_N_SGI_20 0x01 196#define BRCMS_N_SGI_40 0x02 197 198/* defines used by the nrate iovar */ 199/* MSC in use,indicates b0-6 holds an mcs */ 200#define NRATE_MCS_INUSE 0x00000080 201/* rate/mcs value */ 202#define NRATE_RATE_MASK 0x0000007f 203/* stf mode mask: siso, cdd, stbc, sdm */ 204#define NRATE_STF_MASK 0x0000ff00 205/* stf mode shift */ 206#define NRATE_STF_SHIFT 8 207/* bit indicate to override mcs only */ 208#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 209#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ 210#define NRATE_SGI_SHIFT 23 /* sgi mode */ 211#define NRATE_LDPC_CODING 0x00400000 /* adv coding in use */ 212#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ 213 214#define NRATE_STF_SISO 0 /* stf mode SISO */ 215#define NRATE_STF_CDD 1 /* stf mode CDD */ 216#define NRATE_STF_STBC 2 /* stf mode STBC */ 217#define NRATE_STF_SDM 3 /* stf mode SDM */ 218 219#define MAX_DMA_SEGS 4 220 221/* # of entries in Tx FIFO */ 222#define NTXD 64 223/* Max # of entries in Rx FIFO based on 4kb page size */ 224#define NRXD 256 225 226/* Amount of headroom to leave in Tx FIFO */ 227#define TX_HEADROOM 4 228 229/* try to keep this # rbufs posted to the chip */ 230#define NRXBUFPOST 32 231 232/* max # frames to process in brcms_c_recv() */ 233#define RXBND 8 234/* max # tx status to process in wlc_txstatus() */ 235#define TXSBND 8 236 237/* brcmu_format_flags() bit description structure */ 238struct brcms_c_bit_desc { 239 u32 bit; 240 const char *name; 241}; 242 243/* 244 * The following table lists the buffer memory allocated to xmt fifos in HW. 245 * the size is in units of 256bytes(one block), total size is HW dependent 246 * ucode has default fifo partition, sw can overwrite if necessary 247 * 248 * This is documented in twiki under the topic UcodeTxFifo. Please ensure 249 * the twiki is updated before making changes. 250 */ 251 252/* Starting corerev for the fifo size table */ 253#define XMTFIFOTBL_STARTREV 17 254 255struct d11init { 256 __le16 addr; 257 __le16 size; 258 __le32 value; 259}; 260 261struct edcf_acparam { 262 u8 ACI; 263 u8 ECW; 264 u16 TXOP; 265} __packed; 266 267/* debug/trace */ 268uint brcm_msg_level; 269 270/* TX FIFO number to WME/802.1E Access Category */ 271static const u8 wme_fifo2ac[] = { 272 IEEE80211_AC_BK, 273 IEEE80211_AC_BE, 274 IEEE80211_AC_VI, 275 IEEE80211_AC_VO, 276 IEEE80211_AC_BE, 277 IEEE80211_AC_BE 278}; 279 280/* ieee80211 Access Category to TX FIFO number */ 281static const u8 wme_ac2fifo[] = { 282 TX_AC_VO_FIFO, 283 TX_AC_VI_FIFO, 284 TX_AC_BE_FIFO, 285 TX_AC_BK_FIFO 286}; 287 288static const u16 xmtfifo_sz[][NFIFO] = { 289 /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ 290 {20, 192, 192, 21, 17, 5}, 291 /* corerev 18: */ 292 {0, 0, 0, 0, 0, 0}, 293 /* corerev 19: */ 294 {0, 0, 0, 0, 0, 0}, 295 /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */ 296 {20, 192, 192, 21, 17, 5}, 297 /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */ 298 {9, 58, 22, 14, 14, 5}, 299 /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */ 300 {20, 192, 192, 21, 17, 5}, 301 /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */ 302 {20, 192, 192, 21, 17, 5}, 303 /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ 304 {9, 58, 22, 14, 14, 5}, 305 /* corerev 25: */ 306 {0, 0, 0, 0, 0, 0}, 307 /* corerev 26: */ 308 {0, 0, 0, 0, 0, 0}, 309 /* corerev 27: */ 310 {0, 0, 0, 0, 0, 0}, 311 /* corerev 28: 2304, 14848, 5632, 3584, 3584, 1280 */ 312 {9, 58, 22, 14, 14, 5}, 313}; 314 315#ifdef DEBUG 316static const char * const fifo_names[] = { 317 "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; 318#else 319static const char fifo_names[6][0]; 320#endif 321 322#ifdef DEBUG 323/* pointer to most recently allocated wl/wlc */ 324static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); 325#endif 326 327/* Mapping of ieee80211 AC numbers to tx fifos */ 328static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = { 329 [IEEE80211_AC_VO] = TX_AC_VO_FIFO, 330 [IEEE80211_AC_VI] = TX_AC_VI_FIFO, 331 [IEEE80211_AC_BE] = TX_AC_BE_FIFO, 332 [IEEE80211_AC_BK] = TX_AC_BK_FIFO, 333}; 334 335/* Mapping of tx fifos to ieee80211 AC numbers */ 336static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = { 337 [TX_AC_BK_FIFO] = IEEE80211_AC_BK, 338 [TX_AC_BE_FIFO] = IEEE80211_AC_BE, 339 [TX_AC_VI_FIFO] = IEEE80211_AC_VI, 340 [TX_AC_VO_FIFO] = IEEE80211_AC_VO, 341}; 342 343static u8 brcms_ac_to_fifo(u8 ac) 344{ 345 if (ac >= ARRAY_SIZE(ac_to_fifo_mapping)) 346 return TX_AC_BE_FIFO; 347 return ac_to_fifo_mapping[ac]; 348} 349 350static u8 brcms_fifo_to_ac(u8 fifo) 351{ 352 if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping)) 353 return IEEE80211_AC_BE; 354 return fifo_to_ac_mapping[fifo]; 355} 356 357/* Find basic rate for a given rate */ 358static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) 359{ 360 if (is_mcs_rate(rspec)) 361 return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK] 362 .leg_ofdm]; 363 return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK]; 364} 365 366static u16 frametype(u32 rspec, u8 mimoframe) 367{ 368 if (is_mcs_rate(rspec)) 369 return mimoframe; 370 return is_cck_rate(rspec) ? FT_CCK : FT_OFDM; 371} 372 373/* currently the best mechanism for determining SIFS is the band in use */ 374static u16 get_sifs(struct brcms_band *band) 375{ 376 return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME : 377 BPHY_SIFS_TIME; 378} 379 380/* 381 * Detect Card removed. 382 * Even checking an sbconfig register read will not false trigger when the core 383 * is in reset it breaks CF address mechanism. Accessing gphy phyversion will 384 * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible 385 * reg with fixed 0/1 pattern (some platforms return all 0). 386 * If clocks are present, call the sb routine which will figure out if the 387 * device is removed. 388 */ 389static bool brcms_deviceremoved(struct brcms_c_info *wlc) 390{ 391 u32 macctrl; 392 393 if (!wlc->hw->clk) 394 return ai_deviceremoved(wlc->hw->sih); 395 macctrl = bcma_read32(wlc->hw->d11core, 396 D11REGOFFS(maccontrol)); 397 return (macctrl & (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN; 398} 399 400/* sum the individual fifo tx pending packet counts */ 401static int brcms_txpktpendtot(struct brcms_c_info *wlc) 402{ 403 int i; 404 int pending = 0; 405 406 for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) 407 if (wlc->hw->di[i]) 408 pending += dma_txpending(wlc->hw->di[i]); 409 return pending; 410} 411 412static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) 413{ 414 return wlc->pub->_nbands > 1 && !wlc->bandlocked; 415} 416 417static int brcms_chspec_bw(u16 chanspec) 418{ 419 if (CHSPEC_IS40(chanspec)) 420 return BRCMS_40_MHZ; 421 if (CHSPEC_IS20(chanspec)) 422 return BRCMS_20_MHZ; 423 424 return BRCMS_10_MHZ; 425} 426 427static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg) 428{ 429 if (cfg == NULL) 430 return; 431 432 kfree(cfg->current_bss); 433 kfree(cfg); 434} 435 436static void brcms_c_detach_mfree(struct brcms_c_info *wlc) 437{ 438 if (wlc == NULL) 439 return; 440 441 brcms_c_bsscfg_mfree(wlc->bsscfg); 442 kfree(wlc->pub); 443 kfree(wlc->modulecb); 444 kfree(wlc->default_bss); 445 kfree(wlc->protection); 446 kfree(wlc->stf); 447 kfree(wlc->bandstate[0]); 448 kfree(wlc->corestate->macstat_snapshot); 449 kfree(wlc->corestate); 450 kfree(wlc->hw->bandstate[0]); 451 kfree(wlc->hw); 452 if (wlc->beacon) 453 dev_kfree_skb_any(wlc->beacon); 454 455 /* free the wlc */ 456 kfree(wlc); 457 wlc = NULL; 458} 459 460static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit) 461{ 462 struct brcms_bss_cfg *cfg; 463 464 cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC); 465 if (cfg == NULL) 466 goto fail; 467 468 cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC); 469 if (cfg->current_bss == NULL) 470 goto fail; 471 472 return cfg; 473 474 fail: 475 brcms_c_bsscfg_mfree(cfg); 476 return NULL; 477} 478 479static struct brcms_c_info * 480brcms_c_attach_malloc(uint unit, uint *err, uint devid) 481{ 482 struct brcms_c_info *wlc; 483 484 wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC); 485 if (wlc == NULL) { 486 *err = 1002; 487 goto fail; 488 } 489 490 /* allocate struct brcms_c_pub state structure */ 491 wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC); 492 if (wlc->pub == NULL) { 493 *err = 1003; 494 goto fail; 495 } 496 wlc->pub->wlc = wlc; 497 498 /* allocate struct brcms_hardware state structure */ 499 500 wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC); 501 if (wlc->hw == NULL) { 502 *err = 1005; 503 goto fail; 504 } 505 wlc->hw->wlc = wlc; 506 507 wlc->hw->bandstate[0] = 508 kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC); 509 if (wlc->hw->bandstate[0] == NULL) { 510 *err = 1006; 511 goto fail; 512 } else { 513 int i; 514 515 for (i = 1; i < MAXBANDS; i++) 516 wlc->hw->bandstate[i] = (struct brcms_hw_band *) 517 ((unsigned long)wlc->hw->bandstate[0] + 518 (sizeof(struct brcms_hw_band) * i)); 519 } 520 521 wlc->modulecb = 522 kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC); 523 if (wlc->modulecb == NULL) { 524 *err = 1009; 525 goto fail; 526 } 527 528 wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC); 529 if (wlc->default_bss == NULL) { 530 *err = 1010; 531 goto fail; 532 } 533 534 wlc->bsscfg = brcms_c_bsscfg_malloc(unit); 535 if (wlc->bsscfg == NULL) { 536 *err = 1011; 537 goto fail; 538 } 539 540 wlc->protection = kzalloc(sizeof(struct brcms_protection), 541 GFP_ATOMIC); 542 if (wlc->protection == NULL) { 543 *err = 1016; 544 goto fail; 545 } 546 547 wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC); 548 if (wlc->stf == NULL) { 549 *err = 1017; 550 goto fail; 551 } 552 553 wlc->bandstate[0] = 554 kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC); 555 if (wlc->bandstate[0] == NULL) { 556 *err = 1025; 557 goto fail; 558 } else { 559 int i; 560 561 for (i = 1; i < MAXBANDS; i++) 562 wlc->bandstate[i] = (struct brcms_band *) 563 ((unsigned long)wlc->bandstate[0] 564 + (sizeof(struct brcms_band)*i)); 565 } 566 567 wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC); 568 if (wlc->corestate == NULL) { 569 *err = 1026; 570 goto fail; 571 } 572 573 wlc->corestate->macstat_snapshot = 574 kzalloc(sizeof(struct macstat), GFP_ATOMIC); 575 if (wlc->corestate->macstat_snapshot == NULL) { 576 *err = 1027; 577 goto fail; 578 } 579 580 return wlc; 581 582 fail: 583 brcms_c_detach_mfree(wlc); 584 return NULL; 585} 586 587/* 588 * Update the slot timing for standard 11b/g (20us slots) 589 * or shortslot 11g (9us slots) 590 * The PSM needs to be suspended for this call. 591 */ 592static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, 593 bool shortslot) 594{ 595 struct bcma_device *core = wlc_hw->d11core; 596 597 if (shortslot) { 598 /* 11g short slot: 11a timing */ 599 bcma_write16(core, D11REGOFFS(ifs_slot), 0x0207); 600 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); 601 } else { 602 /* 11g long slot: 11b timing */ 603 bcma_write16(core, D11REGOFFS(ifs_slot), 0x0212); 604 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); 605 } 606} 607 608/* 609 * calculate frame duration of a given rate and length, return 610 * time in usec unit 611 */ 612static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, 613 u8 preamble_type, uint mac_len) 614{ 615 uint nsyms, dur = 0, Ndps, kNdps; 616 uint rate = rspec2rate(ratespec); 617 618 if (rate == 0) { 619 brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n", 620 wlc->pub->unit); 621 rate = BRCM_RATE_1M; 622 } 623 624 if (is_mcs_rate(ratespec)) { 625 uint mcs = ratespec & RSPEC_RATE_MASK; 626 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); 627 628 dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); 629 if (preamble_type == BRCMS_MM_PREAMBLE) 630 dur += PREN_MM_EXT; 631 /* 1000Ndbps = kbps * 4 */ 632 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec), 633 rspec_issgi(ratespec)) * 4; 634 635 if (rspec_stc(ratespec) == 0) 636 nsyms = 637 CEIL((APHY_SERVICE_NBITS + 8 * mac_len + 638 APHY_TAIL_NBITS) * 1000, kNdps); 639 else 640 /* STBC needs to have even number of symbols */ 641 nsyms = 642 2 * 643 CEIL((APHY_SERVICE_NBITS + 8 * mac_len + 644 APHY_TAIL_NBITS) * 1000, 2 * kNdps); 645 646 dur += APHY_SYMBOL_TIME * nsyms; 647 if (wlc->band->bandtype == BRCM_BAND_2G) 648 dur += DOT11_OFDM_SIGNAL_EXTENSION; 649 } else if (is_ofdm_rate(rate)) { 650 dur = APHY_PREAMBLE_TIME; 651 dur += APHY_SIGNAL_TIME; 652 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ 653 Ndps = rate * 2; 654 /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ 655 nsyms = 656 CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS), 657 Ndps); 658 dur += APHY_SYMBOL_TIME * nsyms; 659 if (wlc->band->bandtype == BRCM_BAND_2G) 660 dur += DOT11_OFDM_SIGNAL_EXTENSION; 661 } else { 662 /* 663 * calc # bits * 2 so factor of 2 in rate (1/2 mbps) 664 * will divide out 665 */ 666 mac_len = mac_len * 8 * 2; 667 /* calc ceiling of bits/rate = microseconds of air time */ 668 dur = (mac_len + rate - 1) / rate; 669 if (preamble_type & BRCMS_SHORT_PREAMBLE) 670 dur += BPHY_PLCP_SHORT_TIME; 671 else 672 dur += BPHY_PLCP_TIME; 673 } 674 return dur; 675} 676 677static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, 678 const struct d11init *inits) 679{ 680 struct bcma_device *core = wlc_hw->d11core; 681 int i; 682 uint offset; 683 u16 size; 684 u32 value; 685 686 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); 687 688 for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { 689 size = le16_to_cpu(inits[i].size); 690 offset = le16_to_cpu(inits[i].addr); 691 value = le32_to_cpu(inits[i].value); 692 if (size == 2) 693 bcma_write16(core, offset, value); 694 else if (size == 4) 695 bcma_write32(core, offset, value); 696 else 697 break; 698 } 699} 700 701static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) 702{ 703 u8 idx; 704 u16 addr[] = { 705 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, 706 M_HOST_FLAGS5 707 }; 708 709 for (idx = 0; idx < MHFMAX; idx++) 710 brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]); 711} 712 713static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) 714{ 715 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; 716 717 /* init microcode host flags */ 718 brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs); 719 720 /* do band-specific ucode IHR, SHM, and SCR inits */ 721 if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { 722 if (BRCMS_ISNPHY(wlc_hw->band)) 723 brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); 724 else 725 brcms_err(wlc_hw->d11core, 726 "%s: wl%d: unsupported phy in corerev %d\n", 727 __func__, wlc_hw->unit, 728 wlc_hw->corerev); 729 } else { 730 if (D11REV_IS(wlc_hw->corerev, 24)) { 731 if (BRCMS_ISLCNPHY(wlc_hw->band)) 732 brcms_c_write_inits(wlc_hw, 733 ucode->d11lcn0bsinitvals24); 734 else 735 brcms_err(wlc_hw->d11core, 736 "%s: wl%d: unsupported phy in core rev %d\n", 737 __func__, wlc_hw->unit, 738 wlc_hw->corerev); 739 } else { 740 brcms_err(wlc_hw->d11core, 741 "%s: wl%d: unsupported corerev %d\n", 742 __func__, wlc_hw->unit, wlc_hw->corerev); 743 } 744 } 745} 746 747static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v) 748{ 749 struct bcma_device *core = wlc_hw->d11core; 750 u32 ioctl = bcma_aread32(core, BCMA_IOCTL) & ~m; 751 752 bcma_awrite32(core, BCMA_IOCTL, ioctl | v); 753} 754 755static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) 756{ 757 brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk); 758 759 wlc_hw->phyclk = clk; 760 761 if (OFF == clk) { /* clear gmode bit, put phy into reset */ 762 763 brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC | SICF_GMODE), 764 (SICF_PRST | SICF_FGC)); 765 udelay(1); 766 brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_PRST); 767 udelay(1); 768 769 } else { /* take phy out of reset */ 770 771 brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_FGC); 772 udelay(1); 773 brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0); 774 udelay(1); 775 776 } 777} 778 779/* low-level band switch utility routine */ 780static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) 781{ 782 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, 783 bandunit); 784 785 wlc_hw->band = wlc_hw->bandstate[bandunit]; 786 787 /* 788 * BMAC_NOTE: 789 * until we eliminate need for wlc->band refs in low level code 790 */ 791 wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit]; 792 793 /* set gmode core flag */ 794 if (wlc_hw->sbclk && !wlc_hw->noreset) { 795 u32 gmode = 0; 796 797 if (bandunit == 0) 798 gmode = SICF_GMODE; 799 800 brcms_b_core_ioctl(wlc_hw, SICF_GMODE, gmode); 801 } 802} 803 804/* switch to new band but leave it inactive */ 805static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) 806{ 807 struct brcms_hardware *wlc_hw = wlc->hw; 808 u32 macintmask; 809 u32 macctrl; 810 811 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); 812 macctrl = bcma_read32(wlc_hw->d11core, 813 D11REGOFFS(maccontrol)); 814 WARN_ON((macctrl & MCTL_EN_MAC) != 0); 815 816 /* disable interrupts */ 817 macintmask = brcms_intrsoff(wlc->wl); 818 819 /* radio off */ 820 wlc_phy_switch_radio(wlc_hw->band->pi, OFF); 821 822 brcms_b_core_phy_clk(wlc_hw, OFF); 823 824 brcms_c_setxband(wlc_hw, bandunit); 825 826 return macintmask; 827} 828 829/* process an individual struct tx_status */ 830static bool 831brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) 832{ 833 struct sk_buff *p = NULL; 834 uint queue = NFIFO; 835 struct dma_pub *dma = NULL; 836 struct d11txh *txh = NULL; 837 struct scb *scb = NULL; 838 bool free_pdu; 839 int tx_rts, tx_frame_count, tx_rts_count; 840 uint totlen, supr_status; 841 bool lastframe; 842 struct ieee80211_hdr *h; 843 u16 mcl; 844 struct ieee80211_tx_info *tx_info; 845 struct ieee80211_tx_rate *txrate; 846 int i; 847 bool fatal = true; 848 849 trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen, 850 txs->frameid, txs->status, txs->lasttxtime, 851 txs->sequence, txs->phyerr, txs->ackphyrxsh); 852 853 /* discard intermediate indications for ucode with one legitimate case: 854 * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, 855 * but the subsequent tx of DATA failed. so it will start rts/cts 856 * from the beginning (resetting the rts transmission count) 857 */ 858 if (!(txs->status & TX_STATUS_AMPDU) 859 && (txs->status & TX_STATUS_INTERMEDIATE)) { 860 brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n"); 861 fatal = false; 862 goto out; 863 } 864 865 queue = txs->frameid & TXFID_QUEUE_MASK; 866 if (queue >= NFIFO) { 867 brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue); 868 goto out; 869 } 870 871 dma = wlc->hw->di[queue]; 872 873 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); 874 if (p == NULL) { 875 brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n"); 876 goto out; 877 } 878 879 txh = (struct d11txh *) (p->data); 880 mcl = le16_to_cpu(txh->MacTxControlLow); 881 882 if (txs->phyerr) 883 brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n", 884 txs->phyerr, txh->MainRates); 885 886 if (txs->frameid != le16_to_cpu(txh->TxFrameID)) { 887 brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n"); 888 goto out; 889 } 890 tx_info = IEEE80211_SKB_CB(p); 891 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); 892 893 if (tx_info->rate_driver_data[0]) 894 scb = &wlc->pri_scb; 895 896 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 897 brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); 898 fatal = false; 899 goto out; 900 } 901 902 /* 903 * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU 904 * frames; this traces them for the rest. 905 */ 906 trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); 907 908 supr_status = txs->status & TX_STATUS_SUPR_MASK; 909 if (supr_status == TX_STATUS_SUPR_BADCH) { 910 unsigned xfts = le16_to_cpu(txh->XtraFrameTypes); 911 brcms_dbg_tx(wlc->hw->d11core, 912 "Pkt tx suppressed, dest chan %u, current %d\n", 913 (xfts >> XFTS_CHANNEL_SHIFT) & 0xff, 914 CHSPEC_CHANNEL(wlc->default_bss->chanspec)); 915 } 916 917 tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; 918 tx_frame_count = 919 (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; 920 tx_rts_count = 921 (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; 922 923 lastframe = !ieee80211_has_morefrags(h->frame_control); 924 925 if (!lastframe) { 926 brcms_err(wlc->hw->d11core, "Not last frame!\n"); 927 } else { 928 /* 929 * Set information to be consumed by Minstrel ht. 930 * 931 * The "fallback limit" is the number of tx attempts a given 932 * MPDU is sent at the "primary" rate. Tx attempts beyond that 933 * limit are sent at the "secondary" rate. 934 * A 'short frame' does not exceed RTS treshold. 935 */ 936 u16 sfbl, /* Short Frame Rate Fallback Limit */ 937 lfbl, /* Long Frame Rate Fallback Limit */ 938 fbl; 939 940 if (queue < IEEE80211_NUM_ACS) { 941 sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], 942 EDCF_SFB); 943 lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], 944 EDCF_LFB); 945 } else { 946 sfbl = wlc->SFBL; 947 lfbl = wlc->LFBL; 948 } 949 950 txrate = tx_info->status.rates; 951 if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) 952 fbl = lfbl; 953 else 954 fbl = sfbl; 955 956 ieee80211_tx_info_clear_status(tx_info); 957 958 if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) { 959 /* 960 * rate selection requested a fallback rate 961 * and we used it 962 */ 963 txrate[0].count = fbl; 964 txrate[1].count = tx_frame_count - fbl; 965 } else { 966 /* 967 * rate selection did not request fallback rate, or 968 * we didn't need it 969 */ 970 txrate[0].count = tx_frame_count; 971 /* 972 * rc80211_minstrel.c:minstrel_tx_status() expects 973 * unused rates to be marked with idx = -1 974 */ 975 txrate[1].idx = -1; 976 txrate[1].count = 0; 977 } 978 979 /* clear the rest of the rates */ 980 for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { 981 txrate[i].idx = -1; 982 txrate[i].count = 0; 983 } 984 985 if (txs->status & TX_STATUS_ACK_RCV) 986 tx_info->flags |= IEEE80211_TX_STAT_ACK; 987 } 988 989 totlen = p->len; 990 free_pdu = true; 991 992 if (lastframe) { 993 /* remove PLCP & Broadcom tx descriptor header */ 994 skb_pull(p, D11_PHY_HDR_LEN); 995 skb_pull(p, D11_TXH_LEN); 996 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); 997 } else { 998 brcms_err(wlc->hw->d11core, 999 "%s: Not last frame => not calling tx_status\n", 1000 __func__); 1001 } 1002 1003 fatal = false; 1004 1005 out: 1006 if (fatal) { 1007 if (txh) 1008 trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, 1009 sizeof(*txh)); 1010 if (p) 1011 brcmu_pkt_buf_free_skb(p); 1012 } 1013 1014 if (dma && queue < NFIFO) { 1015 u16 ac_queue = brcms_fifo_to_ac(queue); 1016 if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO && 1017 ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue)) 1018 ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue); 1019 dma_kick_tx(dma); 1020 } 1021 1022 return fatal; 1023} 1024 1025/* process tx completion events in BMAC 1026 * Return true if more tx status need to be processed. false otherwise. 1027 */ 1028static bool 1029brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) 1030{ 1031 struct bcma_device *core; 1032 struct tx_status txstatus, *txs; 1033 u32 s1, s2; 1034 uint n = 0; 1035 /* 1036 * Param 'max_tx_num' indicates max. # tx status to process before 1037 * break out. 1038 */ 1039 uint max_tx_num = bound ? TXSBND : -1; 1040 1041 txs = &txstatus; 1042 core = wlc_hw->d11core; 1043 *fatal = false; 1044 1045 while (n < max_tx_num) { 1046 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); 1047 if (s1 == 0xffffffff) { 1048 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, 1049 __func__); 1050 *fatal = true; 1051 return false; 1052 } 1053 /* only process when valid */ 1054 if (!(s1 & TXS_V)) 1055 break; 1056 1057 s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); 1058 txs->status = s1 & TXS_STATUS_MASK; 1059 txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; 1060 txs->sequence = s2 & TXS_SEQ_MASK; 1061 txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; 1062 txs->lasttxtime = 0; 1063 1064 *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); 1065 if (*fatal == true) 1066 return false; 1067 n++; 1068 } 1069 1070 return n >= max_tx_num; 1071} 1072 1073static void brcms_c_tbtt(struct brcms_c_info *wlc) 1074{ 1075 if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC) 1076 /* 1077 * DirFrmQ is now valid...defer setting until end 1078 * of ATIM window 1079 */ 1080 wlc->qvalid |= MCMD_DIRFRMQVAL; 1081} 1082 1083/* set initial host flags value */ 1084static void 1085brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init) 1086{ 1087 struct brcms_hardware *wlc_hw = wlc->hw; 1088 1089 memset(mhfs, 0, MHFMAX * sizeof(u16)); 1090 1091 mhfs[MHF2] |= mhf2_init; 1092 1093 /* prohibit use of slowclock on multifunction boards */ 1094 if (wlc_hw->boardflags & BFL_NOPLLDOWN) 1095 mhfs[MHF1] |= MHF1_FORCEFASTCLK; 1096 1097 if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { 1098 mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; 1099 mhfs[MHF1] |= MHF1_IQSWAP_WAR; 1100 } 1101} 1102 1103static uint 1104dmareg(uint direction, uint fifonum) 1105{ 1106 if (direction == DMA_TX) 1107 return offsetof(struct d11regs, fifo64regs[fifonum].dmaxmt); 1108 return offsetof(struct d11regs, fifo64regs[fifonum].dmarcv); 1109} 1110 1111static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) 1112{ 1113 uint i; 1114 char name[8]; 1115 /* 1116 * ucode host flag 2 needed for pio mode, independent of band and fifo 1117 */ 1118 u16 pio_mhf2 = 0; 1119 struct brcms_hardware *wlc_hw = wlc->hw; 1120 uint unit = wlc_hw->unit; 1121 1122 /* name and offsets for dma_attach */ 1123 snprintf(name, sizeof(name), "wl%d", unit); 1124 1125 if (wlc_hw->di[0] == NULL) { /* Init FIFOs */ 1126 int dma_attach_err = 0; 1127 1128 /* 1129 * FIFO 0 1130 * TX: TX_AC_BK_FIFO (TX AC Background data packets) 1131 * RX: RX_FIFO (RX data packets) 1132 */ 1133 wlc_hw->di[0] = dma_attach(name, wlc, 1134 (wme ? dmareg(DMA_TX, 0) : 0), 1135 dmareg(DMA_RX, 0), 1136 (wme ? NTXD : 0), NRXD, 1137 RXBUFSZ, -1, NRXBUFPOST, 1138 BRCMS_HWRXOFF); 1139 dma_attach_err |= (NULL == wlc_hw->di[0]); 1140 1141 /* 1142 * FIFO 1 1143 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets) 1144 * (legacy) TX_DATA_FIFO (TX data packets) 1145 * RX: UNUSED 1146 */ 1147 wlc_hw->di[1] = dma_attach(name, wlc, 1148 dmareg(DMA_TX, 1), 0, 1149 NTXD, 0, 0, -1, 0, 0); 1150 dma_attach_err |= (NULL == wlc_hw->di[1]); 1151 1152 /* 1153 * FIFO 2 1154 * TX: TX_AC_VI_FIFO (TX AC Video data packets) 1155 * RX: UNUSED 1156 */ 1157 wlc_hw->di[2] = dma_attach(name, wlc, 1158 dmareg(DMA_TX, 2), 0, 1159 NTXD, 0, 0, -1, 0, 0); 1160 dma_attach_err |= (NULL == wlc_hw->di[2]); 1161 /* 1162 * FIFO 3 1163 * TX: TX_AC_VO_FIFO (TX AC Voice data packets) 1164 * (legacy) TX_CTL_FIFO (TX control & mgmt packets) 1165 */ 1166 wlc_hw->di[3] = dma_attach(name, wlc, 1167 dmareg(DMA_TX, 3), 1168 0, NTXD, 0, 0, -1, 1169 0, 0); 1170 dma_attach_err |= (NULL == wlc_hw->di[3]); 1171/* Cleaner to leave this as if with AP defined */ 1172 1173 if (dma_attach_err) { 1174 brcms_err(wlc_hw->d11core, 1175 "wl%d: wlc_attach: dma_attach failed\n", 1176 unit); 1177 return false; 1178 } 1179 1180 /* get pointer to dma engine tx flow control variable */ 1181 for (i = 0; i < NFIFO; i++) 1182 if (wlc_hw->di[i]) 1183 wlc_hw->txavail[i] = 1184 (uint *) dma_getvar(wlc_hw->di[i], 1185 "&txavail"); 1186 } 1187 1188 /* initial ucode host flags */ 1189 brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); 1190 1191 return true; 1192} 1193 1194static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw) 1195{ 1196 uint j; 1197 1198 for (j = 0; j < NFIFO; j++) { 1199 if (wlc_hw->di[j]) { 1200 dma_detach(wlc_hw->di[j]); 1201 wlc_hw->di[j] = NULL; 1202 } 1203 } 1204} 1205 1206/* 1207 * Initialize brcms_c_info default values ... 1208 * may get overrides later in this function 1209 * BMAC_NOTES, move low out and resolve the dangling ones 1210 */ 1211static void brcms_b_info_init(struct brcms_hardware *wlc_hw) 1212{ 1213 struct brcms_c_info *wlc = wlc_hw->wlc; 1214 1215 /* set default sw macintmask value */ 1216 wlc->defmacintmask = DEF_MACINTMASK; 1217 1218 /* various 802.11g modes */ 1219 wlc_hw->shortslot = false; 1220 1221 wlc_hw->SFBL = RETRY_SHORT_FB; 1222 wlc_hw->LFBL = RETRY_LONG_FB; 1223 1224 /* default mac retry limits */ 1225 wlc_hw->SRL = RETRY_SHORT_DEF; 1226 wlc_hw->LRL = RETRY_LONG_DEF; 1227 wlc_hw->chanspec = ch20mhz_chspec(1); 1228} 1229 1230static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw) 1231{ 1232 /* delay before first read of ucode state */ 1233 udelay(40); 1234 1235 /* wait until ucode is no longer asleep */ 1236 SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) == 1237 DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); 1238} 1239 1240/* control chip clock to save power, enable dynamic clock or force fast clock */ 1241static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode) 1242{ 1243 if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) { 1244 /* new chips with PMU, CCS_FORCEHT will distribute the HT clock 1245 * on backplane, but mac core will still run on ALP(not HT) when 1246 * it enters powersave mode, which means the FCA bit may not be 1247 * set. Should wakeup mac if driver wants it to run on HT. 1248 */ 1249 1250 if (wlc_hw->clk) { 1251 if (mode == BCMA_CLKMODE_FAST) { 1252 bcma_set32(wlc_hw->d11core, 1253 D11REGOFFS(clk_ctl_st), 1254 CCS_FORCEHT); 1255 1256 udelay(64); 1257 1258 SPINWAIT( 1259 ((bcma_read32(wlc_hw->d11core, 1260 D11REGOFFS(clk_ctl_st)) & 1261 CCS_HTAVAIL) == 0), 1262 PMU_MAX_TRANSITION_DLY); 1263 WARN_ON(!(bcma_read32(wlc_hw->d11core, 1264 D11REGOFFS(clk_ctl_st)) & 1265 CCS_HTAVAIL)); 1266 } else { 1267 if ((ai_get_pmurev(wlc_hw->sih) == 0) && 1268 (bcma_read32(wlc_hw->d11core, 1269 D11REGOFFS(clk_ctl_st)) & 1270 (CCS_FORCEHT | CCS_HTAREQ))) 1271 SPINWAIT( 1272 ((bcma_read32(wlc_hw->d11core, 1273 offsetof(struct d11regs, 1274 clk_ctl_st)) & 1275 CCS_HTAVAIL) == 0), 1276 PMU_MAX_TRANSITION_DLY); 1277 bcma_mask32(wlc_hw->d11core, 1278 D11REGOFFS(clk_ctl_st), 1279 ~CCS_FORCEHT); 1280 } 1281 } 1282 wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST); 1283 } else { 1284 1285 /* old chips w/o PMU, force HT through cc, 1286 * then use FCA to verify mac is running fast clock 1287 */ 1288 1289 wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode); 1290 1291 /* check fast clock is available (if core is not in reset) */ 1292 if (wlc_hw->forcefastclk && wlc_hw->clk) 1293 WARN_ON(!(bcma_aread32(wlc_hw->d11core, BCMA_IOST) & 1294 SISF_FCLKA)); 1295 1296 /* 1297 * keep the ucode wake bit on if forcefastclk is on since we 1298 * do not want ucode to put us back to slow clock when it dozes 1299 * for PM mode. Code below matches the wake override bit with 1300 * current forcefastclk state. Only setting bit in wake_override 1301 * instead of waking ucode immediately since old code had this 1302 * behavior. Older code set wlc->forcefastclk but only had the 1303 * wake happen if the wakup_ucode work (protected by an up 1304 * check) was executed just below. 1305 */ 1306 if (wlc_hw->forcefastclk) 1307 mboolset(wlc_hw->wake_override, 1308 BRCMS_WAKE_OVERRIDE_FORCEFAST); 1309 else 1310 mboolclr(wlc_hw->wake_override, 1311 BRCMS_WAKE_OVERRIDE_FORCEFAST); 1312 } 1313} 1314 1315/* set or clear ucode host flag bits 1316 * it has an optimization for no-change write 1317 * it only writes through shared memory when the core has clock; 1318 * pre-CLK changes should use wlc_write_mhf to get around the optimization 1319 * 1320 * 1321 * bands values are: BRCM_BAND_AUTO <--- Current band only 1322 * BRCM_BAND_5G <--- 5G band only 1323 * BRCM_BAND_2G <--- 2G band only 1324 * BRCM_BAND_ALL <--- All bands 1325 */ 1326void 1327brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val, 1328 int bands) 1329{ 1330 u16 save; 1331 u16 addr[MHFMAX] = { 1332 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, 1333 M_HOST_FLAGS5 1334 }; 1335 struct brcms_hw_band *band; 1336 1337 if ((val & ~mask) || idx >= MHFMAX) 1338 return; /* error condition */ 1339 1340 switch (bands) { 1341 /* Current band only or all bands, 1342 * then set the band to current band 1343 */ 1344 case BRCM_BAND_AUTO: 1345 case BRCM_BAND_ALL: 1346 band = wlc_hw->band; 1347 break; 1348 case BRCM_BAND_5G: 1349 band = wlc_hw->bandstate[BAND_5G_INDEX]; 1350 break; 1351 case BRCM_BAND_2G: 1352 band = wlc_hw->bandstate[BAND_2G_INDEX]; 1353 break; 1354 default: 1355 band = NULL; /* error condition */ 1356 } 1357 1358 if (band) { 1359 save = band->mhfs[idx]; 1360 band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val; 1361 1362 /* optimization: only write through if changed, and 1363 * changed band is the current band 1364 */ 1365 if (wlc_hw->clk && (band->mhfs[idx] != save) 1366 && (band == wlc_hw->band)) 1367 brcms_b_write_shm(wlc_hw, addr[idx], 1368 (u16) band->mhfs[idx]); 1369 } 1370 1371 if (bands == BRCM_BAND_ALL) { 1372 wlc_hw->bandstate[0]->mhfs[idx] = 1373 (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; 1374 wlc_hw->bandstate[1]->mhfs[idx] = 1375 (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val; 1376 } 1377} 1378 1379/* set the maccontrol register to desired reset state and 1380 * initialize the sw cache of the register 1381 */ 1382static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw) 1383{ 1384 /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ 1385 wlc_hw->maccontrol = 0; 1386 wlc_hw->suspended_fifos = 0; 1387 wlc_hw->wake_override = 0; 1388 wlc_hw->mute_override = 0; 1389 brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); 1390} 1391 1392/* 1393 * write the software state of maccontrol and 1394 * overrides to the maccontrol register 1395 */ 1396static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw) 1397{ 1398 u32 maccontrol = wlc_hw->maccontrol; 1399 1400 /* OR in the wake bit if overridden */ 1401 if (wlc_hw->wake_override) 1402 maccontrol |= MCTL_WAKE; 1403 1404 /* set AP and INFRA bits for mute if needed */ 1405 if (wlc_hw->mute_override) { 1406 maccontrol &= ~(MCTL_AP); 1407 maccontrol |= MCTL_INFRA; 1408 } 1409 1410 bcma_write32(wlc_hw->d11core, D11REGOFFS(maccontrol), 1411 maccontrol); 1412} 1413 1414/* set or clear maccontrol bits */ 1415void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val) 1416{ 1417 u32 maccontrol; 1418 u32 new_maccontrol; 1419 1420 if (val & ~mask) 1421 return; /* error condition */ 1422 maccontrol = wlc_hw->maccontrol; 1423 new_maccontrol = (maccontrol & ~mask) | val; 1424 1425 /* if the new maccontrol value is the same as the old, nothing to do */ 1426 if (new_maccontrol == maccontrol) 1427 return; 1428 1429 /* something changed, cache the new value */ 1430 wlc_hw->maccontrol = new_maccontrol; 1431 1432 /* write the new values with overrides applied */ 1433 brcms_c_mctrl_write(wlc_hw); 1434} 1435 1436void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, 1437 u32 override_bit) 1438{ 1439 if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { 1440 mboolset(wlc_hw->wake_override, override_bit); 1441 return; 1442 } 1443 1444 mboolset(wlc_hw->wake_override, override_bit); 1445 1446 brcms_c_mctrl_write(wlc_hw); 1447 brcms_b_wait_for_wake(wlc_hw); 1448} 1449 1450void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, 1451 u32 override_bit) 1452{ 1453 mboolclr(wlc_hw->wake_override, override_bit); 1454 1455 if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) 1456 return; 1457 1458 brcms_c_mctrl_write(wlc_hw); 1459} 1460 1461/* When driver needs ucode to stop beaconing, it has to make sure that 1462 * MCTL_AP is clear and MCTL_INFRA is set 1463 * Mode MCTL_AP MCTL_INFRA 1464 * AP 1 1 1465 * STA 0 1 <--- This will ensure no beacons 1466 * IBSS 0 0 1467 */ 1468static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw) 1469{ 1470 wlc_hw->mute_override = 1; 1471 1472 /* if maccontrol already has AP == 0 and INFRA == 1 without this 1473 * override, then there is no change to write 1474 */ 1475 if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) 1476 return; 1477 1478 brcms_c_mctrl_write(wlc_hw); 1479} 1480 1481/* Clear the override on AP and INFRA bits */ 1482static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw) 1483{ 1484 if (wlc_hw->mute_override == 0) 1485 return; 1486 1487 wlc_hw->mute_override = 0; 1488 1489 /* if maccontrol already has AP == 0 and INFRA == 1 without this 1490 * override, then there is no change to write 1491 */ 1492 if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) 1493 return; 1494 1495 brcms_c_mctrl_write(wlc_hw); 1496} 1497 1498/* 1499 * Write a MAC address to the given match reg offset in the RXE match engine. 1500 */ 1501static void 1502brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, 1503 const u8 *addr) 1504{ 1505 struct bcma_device *core = wlc_hw->d11core; 1506 u16 mac_l; 1507 u16 mac_m; 1508 u16 mac_h; 1509 1510 brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit); 1511 1512 mac_l = addr[0] | (addr[1] << 8); 1513 mac_m = addr[2] | (addr[3] << 8); 1514 mac_h = addr[4] | (addr[5] << 8); 1515 1516 /* enter the MAC addr into the RXE match registers */ 1517 bcma_write16(core, D11REGOFFS(rcm_ctl), 1518 RCM_INC_DATA | match_reg_offset); 1519 bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_l); 1520 bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_m); 1521 bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_h); 1522} 1523 1524void 1525brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, 1526 void *buf) 1527{ 1528 struct bcma_device *core = wlc_hw->d11core; 1529 u32 word; 1530 __le32 word_le; 1531 __be32 word_be; 1532 bool be_bit; 1533 brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); 1534 1535 bcma_write32(core, D11REGOFFS(tplatewrptr), offset); 1536 1537 /* if MCTL_BIGEND bit set in mac control register, 1538 * the chip swaps data in fifo, as well as data in 1539 * template ram 1540 */ 1541 be_bit = (bcma_read32(core, D11REGOFFS(maccontrol)) & MCTL_BIGEND) != 0; 1542 1543 while (len > 0) { 1544 memcpy(&word, buf, sizeof(u32)); 1545 1546 if (be_bit) { 1547 word_be = cpu_to_be32(word); 1548 word = *(u32 *)&word_be; 1549 } else { 1550 word_le = cpu_to_le32(word); 1551 word = *(u32 *)&word_le; 1552 } 1553 1554 bcma_write32(core, D11REGOFFS(tplatewrdata), word); 1555 1556 buf = (u8 *) buf + sizeof(u32); 1557 len -= sizeof(u32); 1558 } 1559} 1560 1561static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin) 1562{ 1563 wlc_hw->band->CWmin = newmin; 1564 1565 bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr), 1566 OBJADDR_SCR_SEL | S_DOT11_CWMIN); 1567 (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr)); 1568 bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmin); 1569} 1570 1571static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax) 1572{ 1573 wlc_hw->band->CWmax = newmax; 1574 1575 bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr), 1576 OBJADDR_SCR_SEL | S_DOT11_CWMAX); 1577 (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr)); 1578 bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmax); 1579} 1580 1581void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw) 1582{ 1583 bool fastclk; 1584 1585 /* request FAST clock if not on */ 1586 fastclk = wlc_hw->forcefastclk; 1587 if (!fastclk) 1588 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 1589 1590 wlc_phy_bw_state_set(wlc_hw->band->pi, bw); 1591 1592 brcms_b_phy_reset(wlc_hw); 1593 wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); 1594 1595 /* restore the clk */ 1596 if (!fastclk) 1597 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); 1598} 1599 1600static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw) 1601{ 1602 u16 v; 1603 struct brcms_c_info *wlc = wlc_hw->wlc; 1604 /* update SYNTHPU_DLY */ 1605 1606 if (BRCMS_ISLCNPHY(wlc->band)) 1607 v = SYNTHPU_DLY_LPPHY_US; 1608 else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) 1609 v = SYNTHPU_DLY_NPHY_US; 1610 else 1611 v = SYNTHPU_DLY_BPHY_US; 1612 1613 brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v); 1614} 1615 1616static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw) 1617{ 1618 u16 phyctl; 1619 u16 phytxant = wlc_hw->bmac_phytxant; 1620 u16 mask = PHY_TXC_ANT_MASK; 1621 1622 /* set the Probe Response frame phy control word */ 1623 phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); 1624 phyctl = (phyctl & ~mask) | phytxant; 1625 brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); 1626 1627 /* set the Response (ACK/CTS) frame phy control word */ 1628 phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD); 1629 phyctl = (phyctl & ~mask) | phytxant; 1630 brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); 1631} 1632 1633static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw, 1634 u8 rate) 1635{ 1636 uint i; 1637 u8 plcp_rate = 0; 1638 struct plcp_signal_rate_lookup { 1639 u8 rate; 1640 u8 signal_rate; 1641 }; 1642 /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ 1643 const struct plcp_signal_rate_lookup rate_lookup[] = { 1644 {BRCM_RATE_6M, 0xB}, 1645 {BRCM_RATE_9M, 0xF}, 1646 {BRCM_RATE_12M, 0xA}, 1647 {BRCM_RATE_18M, 0xE}, 1648 {BRCM_RATE_24M, 0x9}, 1649 {BRCM_RATE_36M, 0xD}, 1650 {BRCM_RATE_48M, 0x8}, 1651 {BRCM_RATE_54M, 0xC} 1652 }; 1653 1654 for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { 1655 if (rate == rate_lookup[i].rate) { 1656 plcp_rate = rate_lookup[i].signal_rate; 1657 break; 1658 } 1659 } 1660 1661 /* Find the SHM pointer to the rate table entry by looking in the 1662 * Direct-map Table 1663 */ 1664 return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); 1665} 1666 1667static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw) 1668{ 1669 u8 rate; 1670 u8 rates[8] = { 1671 BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M, 1672 BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M 1673 }; 1674 u16 entry_ptr; 1675 u16 pctl1; 1676 uint i; 1677 1678 if (!BRCMS_PHY_11N_CAP(wlc_hw->band)) 1679 return; 1680 1681 /* walk the phy rate table and update the entries */ 1682 for (i = 0; i < ARRAY_SIZE(rates); i++) { 1683 rate = rates[i]; 1684 1685 entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate); 1686 1687 /* read the SHM Rate Table entry OFDM PCTL1 values */ 1688 pctl1 = 1689 brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); 1690 1691 /* modify the value */ 1692 pctl1 &= ~PHY_TXC1_MODE_MASK; 1693 pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); 1694 1695 /* Update the SHM Rate Table entry OFDM PCTL1 values */ 1696 brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, 1697 pctl1); 1698 } 1699} 1700 1701/* band-specific init */ 1702static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) 1703{ 1704 struct brcms_hardware *wlc_hw = wlc->hw; 1705 1706 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, 1707 wlc_hw->band->bandunit); 1708 1709 brcms_c_ucode_bsinit(wlc_hw); 1710 1711 wlc_phy_init(wlc_hw->band->pi, chanspec); 1712 1713 brcms_c_ucode_txant_set(wlc_hw); 1714 1715 /* 1716 * cwmin is band-specific, update hardware 1717 * with value for current band 1718 */ 1719 brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin); 1720 brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax); 1721 1722 brcms_b_update_slot_timing(wlc_hw, 1723 wlc_hw->band->bandtype == BRCM_BAND_5G ? 1724 true : wlc_hw->shortslot); 1725 1726 /* write phytype and phyvers */ 1727 brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); 1728 brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); 1729 1730 /* 1731 * initialize the txphyctl1 rate table since 1732 * shmem is shared between bands 1733 */ 1734 brcms_upd_ofdm_pctl1_table(wlc_hw); 1735 1736 brcms_b_upd_synthpu(wlc_hw); 1737} 1738 1739/* Perform a soft reset of the PHY PLL */ 1740void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) 1741{ 1742 ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), 1743 ~0, 0); 1744 udelay(1); 1745 ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data), 1746 0x4, 0); 1747 udelay(1); 1748 ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data), 1749 0x4, 4); 1750 udelay(1); 1751 ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data), 1752 0x4, 0); 1753 udelay(1); 1754} 1755 1756/* light way to turn on phy clock without reset for NPHY only 1757 * refer to brcms_b_core_phy_clk for full version 1758 */ 1759void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk) 1760{ 1761 /* support(necessary for NPHY and HYPHY) only */ 1762 if (!BRCMS_ISNPHY(wlc_hw->band)) 1763 return; 1764 1765 if (ON == clk) 1766 brcms_b_core_ioctl(wlc_hw, SICF_FGC, SICF_FGC); 1767 else 1768 brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0); 1769 1770} 1771 1772void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk) 1773{ 1774 if (ON == clk) 1775 brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, SICF_MPCLKE); 1776 else 1777 brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, 0); 1778} 1779 1780void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) 1781{ 1782 struct brcms_phy_pub *pih = wlc_hw->band->pi; 1783 u32 phy_bw_clkbits; 1784 bool phy_in_reset = false; 1785 1786 brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit); 1787 1788 if (pih == NULL) 1789 return; 1790 1791 phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); 1792 1793 /* Specific reset sequence required for NPHY rev 3 and 4 */ 1794 if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && 1795 NREV_LE(wlc_hw->band->phyrev, 4)) { 1796 /* Set the PHY bandwidth */ 1797 brcms_b_core_ioctl(wlc_hw, SICF_BWMASK, phy_bw_clkbits); 1798 1799 udelay(1); 1800 1801 /* Perform a soft reset of the PHY PLL */ 1802 brcms_b_core_phypll_reset(wlc_hw); 1803 1804 /* reset the PHY */ 1805 brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_PCLKE), 1806 (SICF_PRST | SICF_PCLKE)); 1807 phy_in_reset = true; 1808 } else { 1809 brcms_b_core_ioctl(wlc_hw, 1810 (SICF_PRST | SICF_PCLKE | SICF_BWMASK), 1811 (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); 1812 } 1813 1814 udelay(2); 1815 brcms_b_core_phy_clk(wlc_hw, ON); 1816 1817 if (pih) 1818 wlc_phy_anacore(pih, ON); 1819} 1820 1821/* switch to and initialize new band */ 1822static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit, 1823 u16 chanspec) { 1824 struct brcms_c_info *wlc = wlc_hw->wlc; 1825 u32 macintmask; 1826 1827 /* Enable the d11 core before accessing it */ 1828 if (!bcma_core_is_enabled(wlc_hw->d11core)) { 1829 bcma_core_enable(wlc_hw->d11core, 0); 1830 brcms_c_mctrl_reset(wlc_hw); 1831 } 1832 1833 macintmask = brcms_c_setband_inact(wlc, bandunit); 1834 1835 if (!wlc_hw->up) 1836 return; 1837 1838 brcms_b_core_phy_clk(wlc_hw, ON); 1839 1840 /* band-specific initializations */ 1841 brcms_b_bsinit(wlc, chanspec); 1842 1843 /* 1844 * If there are any pending software interrupt bits, 1845 * then replace these with a harmless nonzero value 1846 * so brcms_c_dpc() will re-enable interrupts when done. 1847 */ 1848 if (wlc->macintstatus) 1849 wlc->macintstatus = MI_DMAINT; 1850 1851 /* restore macintmask */ 1852 brcms_intrsrestore(wlc->wl, macintmask); 1853 1854 /* ucode should still be suspended.. */ 1855 WARN_ON((bcma_read32(wlc_hw->d11core, D11REGOFFS(maccontrol)) & 1856 MCTL_EN_MAC) != 0); 1857} 1858 1859static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw) 1860{ 1861 1862 /* reject unsupported corerev */ 1863 if (!CONF_HAS(D11CONF, wlc_hw->corerev)) { 1864 wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n", 1865 wlc_hw->corerev); 1866 return false; 1867 } 1868 1869 return true; 1870} 1871 1872/* Validate some board info parameters */ 1873static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw) 1874{ 1875 uint boardrev = wlc_hw->boardrev; 1876 1877 /* 4 bits each for board type, major, minor, and tiny version */ 1878 uint brt = (boardrev & 0xf000) >> 12; 1879 uint b0 = (boardrev & 0xf00) >> 8; 1880 uint b1 = (boardrev & 0xf0) >> 4; 1881 uint b2 = boardrev & 0xf; 1882 1883 /* voards from other vendors are always considered valid */ 1884 if (ai_get_boardvendor(wlc_hw->sih) != PCI_VENDOR_ID_BROADCOM) 1885 return true; 1886 1887 /* do some boardrev sanity checks when boardvendor is Broadcom */ 1888 if (boardrev == 0) 1889 return false; 1890 1891 if (boardrev <= 0xff) 1892 return true; 1893 1894 if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) 1895 || (b2 > 9)) 1896 return false; 1897 1898 return true; 1899} 1900 1901static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN]) 1902{ 1903 struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom; 1904 1905 /* If macaddr exists, use it (Sromrev4, CIS, ...). */ 1906 if (!is_zero_ether_addr(sprom->il0mac)) { 1907 memcpy(etheraddr, sprom->il0mac, 6); 1908 return; 1909 } 1910 1911 if (wlc_hw->_nbands > 1) 1912 memcpy(etheraddr, sprom->et1mac, 6); 1913 else 1914 memcpy(etheraddr, sprom->il0mac, 6); 1915} 1916 1917/* power both the pll and external oscillator on/off */ 1918static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) 1919{ 1920 brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want); 1921 1922 /* 1923 * dont power down if plldown is false or 1924 * we must poll hw radio disable 1925 */ 1926 if (!want && wlc_hw->pllreq) 1927 return; 1928 1929 wlc_hw->sbclk = want; 1930 if (!wlc_hw->sbclk) { 1931 wlc_hw->clk = false; 1932 if (wlc_hw->band && wlc_hw->band->pi) 1933 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); 1934 } 1935} 1936 1937/* 1938 * Return true if radio is disabled, otherwise false. 1939 * hw radio disable signal is an external pin, users activate it asynchronously 1940 * this function could be called when driver is down and w/o clock 1941 * it operates on different registers depending on corerev and boardflag. 1942 */ 1943static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw) 1944{ 1945 bool v, clk, xtal; 1946 u32 flags = 0; 1947 1948 xtal = wlc_hw->sbclk; 1949 if (!xtal) 1950 brcms_b_xtal(wlc_hw, ON); 1951 1952 /* may need to take core out of reset first */ 1953 clk = wlc_hw->clk; 1954 if (!clk) { 1955 /* 1956 * mac no longer enables phyclk automatically when driver 1957 * accesses phyreg throughput mac. This can be skipped since 1958 * only mac reg is accessed below 1959 */ 1960 if (D11REV_GE(wlc_hw->corerev, 18)) 1961 flags |= SICF_PCLKE; 1962 1963 /* 1964 * TODO: test suspend/resume 1965 * 1966 * AI chip doesn't restore bar0win2 on 1967 * hibernation/resume, need sw fixup 1968 */ 1969 1970 bcma_core_enable(wlc_hw->d11core, flags); 1971 brcms_c_mctrl_reset(wlc_hw); 1972 } 1973 1974 v = ((bcma_read32(wlc_hw->d11core, 1975 D11REGOFFS(phydebug)) & PDBG_RFD) != 0); 1976 1977 /* put core back into reset */ 1978 if (!clk) 1979 bcma_core_disable(wlc_hw->d11core, 0); 1980 1981 if (!xtal) 1982 brcms_b_xtal(wlc_hw, OFF); 1983 1984 return v; 1985} 1986 1987static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo) 1988{ 1989 struct dma_pub *di = wlc_hw->di[fifo]; 1990 return dma_rxreset(di); 1991} 1992 1993/* d11 core reset 1994 * ensure fask clock during reset 1995 * reset dma 1996 * reset d11(out of reset) 1997 * reset phy(out of reset) 1998 * clear software macintstatus for fresh new start 1999 * one testing hack wlc_hw->noreset will bypass the d11/phy reset 2000 */ 2001void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) 2002{ 2003 uint i; 2004 bool fastclk; 2005 2006 if (flags == BRCMS_USE_COREFLAGS) 2007 flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); 2008 2009 brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit); 2010 2011 /* request FAST clock if not on */ 2012 fastclk = wlc_hw->forcefastclk; 2013 if (!fastclk) 2014 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 2015 2016 /* reset the dma engines except first time thru */ 2017 if (bcma_core_is_enabled(wlc_hw->d11core)) { 2018 for (i = 0; i < NFIFO; i++) 2019 if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) 2020 brcms_err(wlc_hw->d11core, "wl%d: %s: " 2021 "dma_txreset[%d]: cannot stop dma\n", 2022 wlc_hw->unit, __func__, i); 2023 2024 if ((wlc_hw->di[RX_FIFO]) 2025 && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) 2026 brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset" 2027 "[%d]: cannot stop dma\n", 2028 wlc_hw->unit, __func__, RX_FIFO); 2029 } 2030 /* if noreset, just stop the psm and return */ 2031 if (wlc_hw->noreset) { 2032 wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ 2033 brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); 2034 return; 2035 } 2036 2037 /* 2038 * mac no longer enables phyclk automatically when driver accesses 2039 * phyreg throughput mac, AND phy_reset is skipped at early stage when 2040 * band->pi is invalid. need to enable PHY CLK 2041 */ 2042 if (D11REV_GE(wlc_hw->corerev, 18)) 2043 flags |= SICF_PCLKE; 2044 2045 /* 2046 * reset the core 2047 * In chips with PMU, the fastclk request goes through d11 core 2048 * reg 0x1e0, which is cleared by the core_reset. have to re-request it. 2049 * 2050 * This adds some delay and we can optimize it by also requesting 2051 * fastclk through chipcommon during this period if necessary. But 2052 * that has to work coordinate with other driver like mips/arm since 2053 * they may touch chipcommon as well. 2054 */ 2055 wlc_hw->clk = false; 2056 bcma_core_enable(wlc_hw->d11core, flags); 2057 wlc_hw->clk = true; 2058 if (wlc_hw->band && wlc_hw->band->pi) 2059 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); 2060 2061 brcms_c_mctrl_reset(wlc_hw); 2062 2063 if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) 2064 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 2065 2066 brcms_b_phy_reset(wlc_hw); 2067 2068 /* turn on PHY_PLL */ 2069 brcms_b_core_phypll_ctl(wlc_hw, true); 2070 2071 /* clear sw intstatus */ 2072 wlc_hw->wlc->macintstatus = 0; 2073 2074 /* restore the clk setting */ 2075 if (!fastclk) 2076 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); 2077} 2078 2079/* txfifo sizes needs to be modified(increased) since the newer cores 2080 * have more memory. 2081 */ 2082static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw) 2083{ 2084 struct bcma_device *core = wlc_hw->d11core; 2085 u16 fifo_nu; 2086 u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; 2087 u16 txfifo_def, txfifo_def1; 2088 u16 txfifo_cmd; 2089 2090 /* tx fifos start at TXFIFO_START_BLK from the Base address */ 2091 txfifo_startblk = TXFIFO_START_BLK; 2092 2093 /* sequence of operations: reset fifo, set fifo size, reset fifo */ 2094 for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { 2095 2096 txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu]; 2097 txfifo_def = (txfifo_startblk & 0xff) | 2098 (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT); 2099 txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) | 2100 ((((txfifo_endblk - 2101 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT); 2102 txfifo_cmd = 2103 TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); 2104 2105 bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd); 2106 bcma_write16(core, D11REGOFFS(xmtfifodef), txfifo_def); 2107 bcma_write16(core, D11REGOFFS(xmtfifodef1), txfifo_def1); 2108 2109 bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd); 2110 2111 txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; 2112 } 2113 /* 2114 * need to propagate to shm location to be in sync since ucode/hw won't 2115 * do this 2116 */ 2117 brcms_b_write_shm(wlc_hw, M_FIFOSIZE0, 2118 wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); 2119 brcms_b_write_shm(wlc_hw, M_FIFOSIZE1, 2120 wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); 2121 brcms_b_write_shm(wlc_hw, M_FIFOSIZE2, 2122 ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> 2123 xmtfifo_sz[TX_AC_BK_FIFO])); 2124 brcms_b_write_shm(wlc_hw, M_FIFOSIZE3, 2125 ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> 2126 xmtfifo_sz[TX_BCMC_FIFO])); 2127} 2128 2129/* This function is used for changing the tsf frac register 2130 * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz 2131 * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz 2132 * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz 2133 * HTPHY Formula is 2^26/freq(MHz) e.g. 2134 * For spuron2 - 126MHz -> 2^26/126 = 532610.0 2135 * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082 2136 * For spuron: 123MHz -> 2^26/123 = 545600.5 2137 * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341 2138 * For spur off: 120MHz -> 2^26/120 = 559240.5 2139 * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 2140 */ 2141 2142void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode) 2143{ 2144 struct bcma_device *core = wlc_hw->d11core; 2145 2146 if ((ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM43224) || 2147 (ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM43225)) { 2148 if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ 2149 bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x2082); 2150 bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8); 2151 } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ 2152 bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x5341); 2153 bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8); 2154 } else { /* 120Mhz */ 2155 bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x8889); 2156 bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8); 2157 } 2158 } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { 2159 if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ 2160 bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x7CE0); 2161 bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC); 2162 } else { /* 80Mhz */ 2163 bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0xCCCD); 2164 bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC); 2165 } 2166 } 2167} 2168 2169void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr) 2170{ 2171 memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr)); 2172 wlc->bsscfg->type = BRCMS_TYPE_STATION; 2173} 2174 2175/* Initialize GPIOs that are controlled by D11 core */ 2176static void brcms_c_gpio_init(struct brcms_c_info *wlc) 2177{ 2178 struct brcms_hardware *wlc_hw = wlc->hw; 2179 u32 gc, gm; 2180 2181 /* use GPIO select 0 to get all gpio signals from the gpio out reg */ 2182 brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); 2183 2184 /* 2185 * Common GPIO setup: 2186 * G0 = LED 0 = WLAN Activity 2187 * G1 = LED 1 = WLAN 2.4 GHz Radio State 2188 * G2 = LED 2 = WLAN 5 GHz Radio State 2189 * G4 = radio disable input (HI enabled, LO disabled) 2190 */ 2191 2192 gc = gm = 0; 2193 2194 /* Allocate GPIOs for mimo antenna diversity feature */ 2195 if (wlc_hw->antsel_type == ANTSEL_2x3) { 2196 /* Enable antenna diversity, use 2x3 mode */ 2197 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, 2198 MHF3_ANTSEL_EN, BRCM_BAND_ALL); 2199 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 2200 MHF3_ANTSEL_MODE, BRCM_BAND_ALL); 2201 2202 /* init superswitch control */ 2203 wlc_phy_antsel_init(wlc_hw->band->pi, false); 2204 2205 } else if (wlc_hw->antsel_type == ANTSEL_2x4) { 2206 gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); 2207 /* 2208 * The board itself is powered by these GPIOs 2209 * (when not sending pattern) so set them high 2210 */ 2211 bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_oe), 2212 (BOARD_GPIO_12 | BOARD_GPIO_13)); 2213 bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_out), 2214 (BOARD_GPIO_12 | BOARD_GPIO_13)); 2215 2216 /* Enable antenna diversity, use 2x4 mode */ 2217 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, 2218 MHF3_ANTSEL_EN, BRCM_BAND_ALL); 2219 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, 2220 BRCM_BAND_ALL); 2221 2222 /* Configure the desired clock to be 4Mhz */ 2223 brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV, 2224 ANTSEL_CLKDIV_4MHZ); 2225 } 2226 2227 /* 2228 * gpio 9 controls the PA. ucode is responsible 2229 * for wiggling out and oe 2230 */ 2231 if (wlc_hw->boardflags & BFL_PACTRL) 2232 gm |= gc |= BOARD_GPIO_PACTRL; 2233 2234 /* apply to gpiocontrol register */ 2235 bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc); 2236} 2237 2238static void brcms_ucode_write(struct brcms_hardware *wlc_hw, 2239 const __le32 ucode[], const size_t nbytes) 2240{ 2241 struct bcma_device *core = wlc_hw->d11core; 2242 uint i; 2243 uint count; 2244 2245 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); 2246 2247 count = (nbytes / sizeof(u32)); 2248 2249 bcma_write32(core, D11REGOFFS(objaddr), 2250 OBJADDR_AUTO_INC | OBJADDR_UCM_SEL); 2251 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2252 for (i = 0; i < count; i++) 2253 bcma_write32(core, D11REGOFFS(objdata), le32_to_cpu(ucode[i])); 2254 2255} 2256 2257static void brcms_ucode_download(struct brcms_hardware *wlc_hw) 2258{ 2259 struct brcms_c_info *wlc; 2260 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; 2261 2262 wlc = wlc_hw->wlc; 2263 2264 if (wlc_hw->ucode_loaded) 2265 return; 2266 2267 if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { 2268 if (BRCMS_ISNPHY(wlc_hw->band)) { 2269 brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo, 2270 ucode->bcm43xx_16_mimosz); 2271 wlc_hw->ucode_loaded = true; 2272 } else 2273 brcms_err(wlc_hw->d11core, 2274 "%s: wl%d: unsupported phy in corerev %d\n", 2275 __func__, wlc_hw->unit, wlc_hw->corerev); 2276 } else if (D11REV_IS(wlc_hw->corerev, 24)) { 2277 if (BRCMS_ISLCNPHY(wlc_hw->band)) { 2278 brcms_ucode_write(wlc_hw, ucode->bcm43xx_24_lcn, 2279 ucode->bcm43xx_24_lcnsz); 2280 wlc_hw->ucode_loaded = true; 2281 } else { 2282 brcms_err(wlc_hw->d11core, 2283 "%s: wl%d: unsupported phy in corerev %d\n", 2284 __func__, wlc_hw->unit, wlc_hw->corerev); 2285 } 2286 } 2287} 2288 2289void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant) 2290{ 2291 /* update sw state */ 2292 wlc_hw->bmac_phytxant = phytxant; 2293 2294 /* push to ucode if up */ 2295 if (!wlc_hw->up) 2296 return; 2297 brcms_c_ucode_txant_set(wlc_hw); 2298 2299} 2300 2301u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw) 2302{ 2303 return (u16) wlc_hw->wlc->stf->txant; 2304} 2305 2306void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type) 2307{ 2308 wlc_hw->antsel_type = antsel_type; 2309 2310 /* Update the antsel type for phy module to use */ 2311 wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); 2312} 2313 2314static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) 2315{ 2316 bool fatal = false; 2317 uint unit; 2318 uint intstatus, idx; 2319 struct bcma_device *core = wlc_hw->d11core; 2320 2321 unit = wlc_hw->unit; 2322 2323 for (idx = 0; idx < NFIFO; idx++) { 2324 /* read intstatus register and ignore any non-error bits */ 2325 intstatus = 2326 bcma_read32(core, 2327 D11REGOFFS(intctrlregs[idx].intstatus)) & 2328 I_ERRORS; 2329 if (!intstatus) 2330 continue; 2331 2332 brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n", 2333 unit, idx, intstatus); 2334 2335 if (intstatus & I_RO) { 2336 brcms_err(core, "wl%d: fifo %d: receive fifo " 2337 "overflow\n", unit, idx); 2338 fatal = true; 2339 } 2340 2341 if (intstatus & I_PC) { 2342 brcms_err(core, "wl%d: fifo %d: descriptor error\n", 2343 unit, idx); 2344 fatal = true; 2345 } 2346 2347 if (intstatus & I_PD) { 2348 brcms_err(core, "wl%d: fifo %d: data error\n", unit, 2349 idx); 2350 fatal = true; 2351 } 2352 2353 if (intstatus & I_DE) { 2354 brcms_err(core, "wl%d: fifo %d: descriptor protocol " 2355 "error\n", unit, idx); 2356 fatal = true; 2357 } 2358 2359 if (intstatus & I_RU) 2360 brcms_err(core, "wl%d: fifo %d: receive descriptor " 2361 "underflow\n", idx, unit); 2362 2363 if (intstatus & I_XU) { 2364 brcms_err(core, "wl%d: fifo %d: transmit fifo " 2365 "underflow\n", idx, unit); 2366 fatal = true; 2367 } 2368 2369 if (fatal) { 2370 brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */ 2371 break; 2372 } else 2373 bcma_write32(core, 2374 D11REGOFFS(intctrlregs[idx].intstatus), 2375 intstatus); 2376 } 2377} 2378 2379void brcms_c_intrson(struct brcms_c_info *wlc) 2380{ 2381 struct brcms_hardware *wlc_hw = wlc->hw; 2382 wlc->macintmask = wlc->defmacintmask; 2383 bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask); 2384} 2385 2386u32 brcms_c_intrsoff(struct brcms_c_info *wlc) 2387{ 2388 struct brcms_hardware *wlc_hw = wlc->hw; 2389 u32 macintmask; 2390 2391 if (!wlc_hw->clk) 2392 return 0; 2393 2394 macintmask = wlc->macintmask; /* isr can still happen */ 2395 2396 bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), 0); 2397 (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(macintmask)); 2398 udelay(1); /* ensure int line is no longer driven */ 2399 wlc->macintmask = 0; 2400 2401 /* return previous macintmask; resolve race between us and our isr */ 2402 return wlc->macintstatus ? 0 : macintmask; 2403} 2404 2405void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask) 2406{ 2407 struct brcms_hardware *wlc_hw = wlc->hw; 2408 if (!wlc_hw->clk) 2409 return; 2410 2411 wlc->macintmask = macintmask; 2412 bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask); 2413} 2414 2415/* assumes that the d11 MAC is enabled */ 2416static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, 2417 uint tx_fifo) 2418{ 2419 u8 fifo = 1 << tx_fifo; 2420 2421 /* Two clients of this code, 11h Quiet period and scanning. */ 2422 2423 /* only suspend if not already suspended */ 2424 if ((wlc_hw->suspended_fifos & fifo) == fifo) 2425 return; 2426 2427 /* force the core awake only if not already */ 2428 if (wlc_hw->suspended_fifos == 0) 2429 brcms_c_ucode_wake_override_set(wlc_hw, 2430 BRCMS_WAKE_OVERRIDE_TXFIFO); 2431 2432 wlc_hw->suspended_fifos |= fifo; 2433 2434 if (wlc_hw->di[tx_fifo]) { 2435 /* 2436 * Suspending AMPDU transmissions in the middle can cause 2437 * underflow which may result in mismatch between ucode and 2438 * driver so suspend the mac before suspending the FIFO 2439 */ 2440 if (BRCMS_PHY_11N_CAP(wlc_hw->band)) 2441 brcms_c_suspend_mac_and_wait(wlc_hw->wlc); 2442 2443 dma_txsuspend(wlc_hw->di[tx_fifo]); 2444 2445 if (BRCMS_PHY_11N_CAP(wlc_hw->band)) 2446 brcms_c_enable_mac(wlc_hw->wlc); 2447 } 2448} 2449 2450static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, 2451 uint tx_fifo) 2452{ 2453 /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case 2454 * but need to be done here for PIO otherwise the watchdog will catch 2455 * the inconsistency and fire 2456 */ 2457 /* Two clients of this code, 11h Quiet period and scanning. */ 2458 if (wlc_hw->di[tx_fifo]) 2459 dma_txresume(wlc_hw->di[tx_fifo]); 2460 2461 /* allow core to sleep again */ 2462 if (wlc_hw->suspended_fifos == 0) 2463 return; 2464 else { 2465 wlc_hw->suspended_fifos &= ~(1 << tx_fifo); 2466 if (wlc_hw->suspended_fifos == 0) 2467 brcms_c_ucode_wake_override_clear(wlc_hw, 2468 BRCMS_WAKE_OVERRIDE_TXFIFO); 2469 } 2470} 2471 2472/* precondition: requires the mac core to be enabled */ 2473static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) 2474{ 2475 static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; 2476 u8 *ethaddr = wlc_hw->wlc->pub->cur_etheraddr; 2477 2478 if (mute_tx) { 2479 /* suspend tx fifos */ 2480 brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); 2481 brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); 2482 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); 2483 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); 2484 2485 /* zero the address match register so we do not send ACKs */ 2486 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, null_ether_addr); 2487 } else { 2488 /* resume tx fifos */ 2489 brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); 2490 brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); 2491 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); 2492 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); 2493 2494 /* Restore address */ 2495 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, ethaddr); 2496 } 2497 2498 wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0); 2499 2500 if (mute_tx) 2501 brcms_c_ucode_mute_override_set(wlc_hw); 2502 else 2503 brcms_c_ucode_mute_override_clear(wlc_hw); 2504} 2505 2506void 2507brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx) 2508{ 2509 brcms_b_mute(wlc->hw, mute_tx); 2510} 2511 2512/* 2513 * Read and clear macintmask and macintstatus and intstatus registers. 2514 * This routine should be called with interrupts off 2515 * Return: 2516 * -1 if brcms_deviceremoved(wlc) evaluates to true; 2517 * 0 if the interrupt is not for us, or we are in some special cases; 2518 * device interrupt status bits otherwise. 2519 */ 2520static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) 2521{ 2522 struct brcms_hardware *wlc_hw = wlc->hw; 2523 struct bcma_device *core = wlc_hw->d11core; 2524 u32 macintstatus, mask; 2525 2526 /* macintstatus includes a DMA interrupt summary bit */ 2527 macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); 2528 mask = in_isr ? wlc->macintmask : wlc->defmacintmask; 2529 2530 trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask); 2531 2532 /* detect cardbus removed, in power down(suspend) and in reset */ 2533 if (brcms_deviceremoved(wlc)) 2534 return -1; 2535 2536 /* brcms_deviceremoved() succeeds even when the core is still resetting, 2537 * handle that case here. 2538 */ 2539 if (macintstatus == 0xffffffff) 2540 return 0; 2541 2542 /* defer unsolicited interrupts */ 2543 macintstatus &= mask; 2544 2545 /* if not for us */ 2546 if (macintstatus == 0) 2547 return 0; 2548 2549 /* turn off the interrupts */ 2550 bcma_write32(core, D11REGOFFS(macintmask), 0); 2551 (void)bcma_read32(core, D11REGOFFS(macintmask)); 2552 wlc->macintmask = 0; 2553 2554 /* clear device interrupts */ 2555 bcma_write32(core, D11REGOFFS(macintstatus), macintstatus); 2556 2557 /* MI_DMAINT is indication of non-zero intstatus */ 2558 if (macintstatus & MI_DMAINT) 2559 /* 2560 * only fifo interrupt enabled is I_RI in 2561 * RX_FIFO. If MI_DMAINT is set, assume it 2562 * is set and clear the interrupt. 2563 */ 2564 bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intstatus), 2565 DEF_RXINTMASK); 2566 2567 return macintstatus; 2568} 2569 2570/* Update wlc->macintstatus and wlc->intstatus[]. */ 2571/* Return true if they are updated successfully. false otherwise */ 2572bool brcms_c_intrsupd(struct brcms_c_info *wlc) 2573{ 2574 u32 macintstatus; 2575 2576 /* read and clear macintstatus and intstatus registers */ 2577 macintstatus = wlc_intstatus(wlc, false); 2578 2579 /* device is removed */ 2580 if (macintstatus == 0xffffffff) 2581 return false; 2582 2583 /* update interrupt status in software */ 2584 wlc->macintstatus |= macintstatus; 2585 2586 return true; 2587} 2588 2589/* 2590 * First-level interrupt processing. 2591 * Return true if this was our interrupt 2592 * and if further brcms_c_dpc() processing is required, 2593 * false otherwise. 2594 */ 2595bool brcms_c_isr(struct brcms_c_info *wlc) 2596{ 2597 struct brcms_hardware *wlc_hw = wlc->hw; 2598 u32 macintstatus; 2599 2600 if (!wlc_hw->up || !wlc->macintmask) 2601 return false; 2602 2603 /* read and clear macintstatus and intstatus registers */ 2604 macintstatus = wlc_intstatus(wlc, true); 2605 2606 if (macintstatus == 0xffffffff) { 2607 brcms_err(wlc_hw->d11core, 2608 "DEVICEREMOVED detected in the ISR code path\n"); 2609 return false; 2610 } 2611 2612 /* it is not for us */ 2613 if (macintstatus == 0) 2614 return false; 2615 2616 /* save interrupt status bits */ 2617 wlc->macintstatus = macintstatus; 2618 2619 return true; 2620 2621} 2622 2623void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) 2624{ 2625 struct brcms_hardware *wlc_hw = wlc->hw; 2626 struct bcma_device *core = wlc_hw->d11core; 2627 u32 mc, mi; 2628 2629 brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, 2630 wlc_hw->band->bandunit); 2631 2632 /* 2633 * Track overlapping suspend requests 2634 */ 2635 wlc_hw->mac_suspend_depth++; 2636 if (wlc_hw->mac_suspend_depth > 1) 2637 return; 2638 2639 /* force the core awake */ 2640 brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND); 2641 2642 mc = bcma_read32(core, D11REGOFFS(maccontrol)); 2643 2644 if (mc == 0xffffffff) { 2645 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, 2646 __func__); 2647 brcms_down(wlc->wl); 2648 return; 2649 } 2650 WARN_ON(mc & MCTL_PSM_JMP_0); 2651 WARN_ON(!(mc & MCTL_PSM_RUN)); 2652 WARN_ON(!(mc & MCTL_EN_MAC)); 2653 2654 mi = bcma_read32(core, D11REGOFFS(macintstatus)); 2655 if (mi == 0xffffffff) { 2656 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, 2657 __func__); 2658 brcms_down(wlc->wl); 2659 return; 2660 } 2661 WARN_ON(mi & MI_MACSSPNDD); 2662 2663 brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0); 2664 2665 SPINWAIT(!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD), 2666 BRCMS_MAX_MAC_SUSPEND); 2667 2668 if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { 2669 brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" 2670 " and MI_MACSSPNDD is still not on.\n", 2671 wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); 2672 brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " 2673 "psm_brc 0x%04x\n", wlc_hw->unit, 2674 bcma_read32(core, D11REGOFFS(psmdebug)), 2675 bcma_read32(core, D11REGOFFS(phydebug)), 2676 bcma_read16(core, D11REGOFFS(psm_brc))); 2677 } 2678 2679 mc = bcma_read32(core, D11REGOFFS(maccontrol)); 2680 if (mc == 0xffffffff) { 2681 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, 2682 __func__); 2683 brcms_down(wlc->wl); 2684 return; 2685 } 2686 WARN_ON(mc & MCTL_PSM_JMP_0); 2687 WARN_ON(!(mc & MCTL_PSM_RUN)); 2688 WARN_ON(mc & MCTL_EN_MAC); 2689} 2690 2691void brcms_c_enable_mac(struct brcms_c_info *wlc) 2692{ 2693 struct brcms_hardware *wlc_hw = wlc->hw; 2694 struct bcma_device *core = wlc_hw->d11core; 2695 u32 mc, mi; 2696 2697 brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, 2698 wlc->band->bandunit); 2699 2700 /* 2701 * Track overlapping suspend requests 2702 */ 2703 wlc_hw->mac_suspend_depth--; 2704 if (wlc_hw->mac_suspend_depth > 0) 2705 return; 2706 2707 mc = bcma_read32(core, D11REGOFFS(maccontrol)); 2708 WARN_ON(mc & MCTL_PSM_JMP_0); 2709 WARN_ON(mc & MCTL_EN_MAC); 2710 WARN_ON(!(mc & MCTL_PSM_RUN)); 2711 2712 brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); 2713 bcma_write32(core, D11REGOFFS(macintstatus), MI_MACSSPNDD); 2714 2715 mc = bcma_read32(core, D11REGOFFS(maccontrol)); 2716 WARN_ON(mc & MCTL_PSM_JMP_0); 2717 WARN_ON(!(mc & MCTL_EN_MAC)); 2718 WARN_ON(!(mc & MCTL_PSM_RUN)); 2719 2720 mi = bcma_read32(core, D11REGOFFS(macintstatus)); 2721 WARN_ON(mi & MI_MACSSPNDD); 2722 2723 brcms_c_ucode_wake_override_clear(wlc_hw, 2724 BRCMS_WAKE_OVERRIDE_MACSUSPEND); 2725} 2726 2727void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode) 2728{ 2729 wlc_hw->hw_stf_ss_opmode = stf_mode; 2730 2731 if (wlc_hw->clk) 2732 brcms_upd_ofdm_pctl1_table(wlc_hw); 2733} 2734 2735static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) 2736{ 2737 struct bcma_device *core = wlc_hw->d11core; 2738 u32 w, val; 2739 struct wiphy *wiphy = wlc_hw->wlc->wiphy; 2740 2741 /* Validate dchip register access */ 2742 2743 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); 2744 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2745 w = bcma_read32(core, D11REGOFFS(objdata)); 2746 2747 /* Can we write and read back a 32bit register? */ 2748 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); 2749 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2750 bcma_write32(core, D11REGOFFS(objdata), (u32) 0xaa5555aa); 2751 2752 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); 2753 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2754 val = bcma_read32(core, D11REGOFFS(objdata)); 2755 if (val != (u32) 0xaa5555aa) { 2756 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " 2757 "expected 0xaa5555aa\n", wlc_hw->unit, val); 2758 return false; 2759 } 2760 2761 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); 2762 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2763 bcma_write32(core, D11REGOFFS(objdata), (u32) 0x55aaaa55); 2764 2765 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); 2766 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2767 val = bcma_read32(core, D11REGOFFS(objdata)); 2768 if (val != (u32) 0x55aaaa55) { 2769 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " 2770 "expected 0x55aaaa55\n", wlc_hw->unit, val); 2771 return false; 2772 } 2773 2774 bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); 2775 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2776 bcma_write32(core, D11REGOFFS(objdata), w); 2777 2778 /* clear CFPStart */ 2779 bcma_write32(core, D11REGOFFS(tsf_cfpstart), 0); 2780 2781 w = bcma_read32(core, D11REGOFFS(maccontrol)); 2782 if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && 2783 (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { 2784 wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = " 2785 "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w, 2786 (MCTL_IHR_EN | MCTL_WAKE), 2787 (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); 2788 return false; 2789 } 2790 2791 return true; 2792} 2793 2794#define PHYPLL_WAIT_US 100000 2795 2796void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) 2797{ 2798 struct bcma_device *core = wlc_hw->d11core; 2799 u32 tmp; 2800 2801 brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); 2802 2803 tmp = 0; 2804 2805 if (on) { 2806 if ((ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM4313)) { 2807 bcma_set32(core, D11REGOFFS(clk_ctl_st), 2808 CCS_ERSRC_REQ_HT | 2809 CCS_ERSRC_REQ_D11PLL | 2810 CCS_ERSRC_REQ_PHYPLL); 2811 SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) & 2812 CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT, 2813 PHYPLL_WAIT_US); 2814 2815 tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); 2816 if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) 2817 brcms_err(core, "%s: turn on PHY PLL failed\n", 2818 __func__); 2819 } else { 2820 bcma_set32(core, D11REGOFFS(clk_ctl_st), 2821 tmp | CCS_ERSRC_REQ_D11PLL | 2822 CCS_ERSRC_REQ_PHYPLL); 2823 SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) & 2824 (CCS_ERSRC_AVAIL_D11PLL | 2825 CCS_ERSRC_AVAIL_PHYPLL)) != 2826 (CCS_ERSRC_AVAIL_D11PLL | 2827 CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); 2828 2829 tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); 2830 if ((tmp & 2831 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) 2832 != 2833 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) 2834 brcms_err(core, "%s: turn on PHY PLL failed\n", 2835 __func__); 2836 } 2837 } else { 2838 /* 2839 * Since the PLL may be shared, other cores can still 2840 * be requesting it; so we'll deassert the request but 2841 * not wait for status to comply. 2842 */ 2843 bcma_mask32(core, D11REGOFFS(clk_ctl_st), 2844 ~CCS_ERSRC_REQ_PHYPLL); 2845 (void)bcma_read32(core, D11REGOFFS(clk_ctl_st)); 2846 } 2847} 2848 2849static void brcms_c_coredisable(struct brcms_hardware *wlc_hw) 2850{ 2851 bool dev_gone; 2852 2853 brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit); 2854 2855 dev_gone = brcms_deviceremoved(wlc_hw->wlc); 2856 2857 if (dev_gone) 2858 return; 2859 2860 if (wlc_hw->noreset) 2861 return; 2862 2863 /* radio off */ 2864 wlc_phy_switch_radio(wlc_hw->band->pi, OFF); 2865 2866 /* turn off analog core */ 2867 wlc_phy_anacore(wlc_hw->band->pi, OFF); 2868 2869 /* turn off PHYPLL to save power */ 2870 brcms_b_core_phypll_ctl(wlc_hw, false); 2871 2872 wlc_hw->clk = false; 2873 bcma_core_disable(wlc_hw->d11core, 0); 2874 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); 2875} 2876 2877static void brcms_c_flushqueues(struct brcms_c_info *wlc) 2878{ 2879 struct brcms_hardware *wlc_hw = wlc->hw; 2880 uint i; 2881 2882 /* free any posted tx packets */ 2883 for (i = 0; i < NFIFO; i++) { 2884 if (wlc_hw->di[i]) { 2885 dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); 2886 if (i < TX_BCMC_FIFO) 2887 ieee80211_wake_queue(wlc->pub->ieee_hw, 2888 brcms_fifo_to_ac(i)); 2889 } 2890 } 2891 2892 /* free any posted rx packets */ 2893 dma_rxreclaim(wlc_hw->di[RX_FIFO]); 2894} 2895 2896static u16 2897brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel) 2898{ 2899 struct bcma_device *core = wlc_hw->d11core; 2900 u16 objoff = D11REGOFFS(objdata); 2901 2902 bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2)); 2903 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2904 if (offset & 2) 2905 objoff += 2; 2906 2907 return bcma_read16(core, objoff); 2908} 2909 2910static void 2911brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v, 2912 u32 sel) 2913{ 2914 struct bcma_device *core = wlc_hw->d11core; 2915 u16 objoff = D11REGOFFS(objdata); 2916 2917 bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2)); 2918 (void)bcma_read32(core, D11REGOFFS(objaddr)); 2919 if (offset & 2) 2920 objoff += 2; 2921 2922 bcma_wflush16(core, objoff, v); 2923} 2924 2925/* 2926 * Read a single u16 from shared memory. 2927 * SHM 'offset' needs to be an even address 2928 */ 2929u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset) 2930{ 2931 return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); 2932} 2933 2934/* 2935 * Write a single u16 to shared memory. 2936 * SHM 'offset' needs to be an even address 2937 */ 2938void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v) 2939{ 2940 brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); 2941} 2942 2943/* 2944 * Copy a buffer to shared memory of specified type . 2945 * SHM 'offset' needs to be an even address and 2946 * Buffer length 'len' must be an even number of bytes 2947 * 'sel' selects the type of memory 2948 */ 2949void 2950brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset, 2951 const void *buf, int len, u32 sel) 2952{ 2953 u16 v; 2954 const u8 *p = (const u8 *)buf; 2955 int i; 2956 2957 if (len <= 0 || (offset & 1) || (len & 1)) 2958 return; 2959 2960 for (i = 0; i < len; i += 2) { 2961 v = p[i] | (p[i + 1] << 8); 2962 brcms_b_write_objmem(wlc_hw, offset + i, v, sel); 2963 } 2964} 2965 2966/* 2967 * Copy a piece of shared memory of specified type to a buffer . 2968 * SHM 'offset' needs to be an even address and 2969 * Buffer length 'len' must be an even number of bytes 2970 * 'sel' selects the type of memory 2971 */ 2972void 2973brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf, 2974 int len, u32 sel) 2975{ 2976 u16 v; 2977 u8 *p = (u8 *) buf; 2978 int i; 2979 2980 if (len <= 0 || (offset & 1) || (len & 1)) 2981 return; 2982 2983 for (i = 0; i < len; i += 2) { 2984 v = brcms_b_read_objmem(wlc_hw, offset + i, sel); 2985 p[i] = v & 0xFF; 2986 p[i + 1] = (v >> 8) & 0xFF; 2987 } 2988} 2989 2990/* Copy a buffer to shared memory. 2991 * SHM 'offset' needs to be an even address and 2992 * Buffer length 'len' must be an even number of bytes 2993 */ 2994static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset, 2995 const void *buf, int len) 2996{ 2997 brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); 2998} 2999 3000static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, 3001 u16 SRL, u16 LRL) 3002{ 3003 wlc_hw->SRL = SRL; 3004 wlc_hw->LRL = LRL; 3005 3006 /* write retry limit to SCR, shouldn't need to suspend */ 3007 if (wlc_hw->up) { 3008 bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr), 3009 OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); 3010 (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr)); 3011 bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->SRL); 3012 bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr), 3013 OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); 3014 (void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr)); 3015 bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->LRL); 3016 } 3017} 3018 3019static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit) 3020{ 3021 if (set) { 3022 if (mboolisset(wlc_hw->pllreq, req_bit)) 3023 return; 3024 3025 mboolset(wlc_hw->pllreq, req_bit); 3026 3027 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { 3028 if (!wlc_hw->sbclk) 3029 brcms_b_xtal(wlc_hw, ON); 3030 } 3031 } else { 3032 if (!mboolisset(wlc_hw->pllreq, req_bit)) 3033 return; 3034 3035 mboolclr(wlc_hw->pllreq, req_bit); 3036 3037 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { 3038 if (wlc_hw->sbclk) 3039 brcms_b_xtal(wlc_hw, OFF); 3040 } 3041 } 3042} 3043 3044static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail) 3045{ 3046 wlc_hw->antsel_avail = antsel_avail; 3047} 3048 3049/* 3050 * conditions under which the PM bit should be set in outgoing frames 3051 * and STAY_AWAKE is meaningful 3052 */ 3053static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) 3054{ 3055 /* disallow PS when one of the following global conditions meets */ 3056 if (!wlc->pub->associated) 3057 return false; 3058 3059 /* disallow PS when one of these meets when not scanning */ 3060 if (wlc->filter_flags & FIF_PROMISC_IN_BSS) 3061 return false; 3062 3063 return true; 3064} 3065 3066static void brcms_c_statsupd(struct brcms_c_info *wlc) 3067{ 3068 int i; 3069 struct macstat macstats; 3070#ifdef DEBUG 3071 u16 delta; 3072 u16 rxf0ovfl; 3073 u16 txfunfl[NFIFO]; 3074#endif /* DEBUG */ 3075 3076 /* if driver down, make no sense to update stats */ 3077 if (!wlc->pub->up) 3078 return; 3079 3080#ifdef DEBUG 3081 /* save last rx fifo 0 overflow count */ 3082 rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; 3083 3084 /* save last tx fifo underflow count */ 3085 for (i = 0; i < NFIFO; i++) 3086 txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; 3087#endif /* DEBUG */ 3088 3089 /* Read mac stats from contiguous shared memory */ 3090 brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats, 3091 sizeof(struct macstat), OBJADDR_SHM_SEL); 3092 3093#ifdef DEBUG 3094 /* check for rx fifo 0 overflow */ 3095 delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); 3096 if (delta) 3097 brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n", 3098 wlc->pub->unit, delta); 3099 3100 /* check for tx fifo underflows */ 3101 for (i = 0; i < NFIFO; i++) { 3102 delta = 3103 (u16) (wlc->core->macstat_snapshot->txfunfl[i] - 3104 txfunfl[i]); 3105 if (delta) 3106 brcms_err(wlc->hw->d11core, 3107 "wl%d: %u tx fifo %d underflows!\n", 3108 wlc->pub->unit, delta, i); 3109 } 3110#endif /* DEBUG */ 3111 3112 /* merge counters from dma module */ 3113 for (i = 0; i < NFIFO; i++) { 3114 if (wlc->hw->di[i]) 3115 dma_counterreset(wlc->hw->di[i]); 3116 } 3117} 3118 3119static void brcms_b_reset(struct brcms_hardware *wlc_hw) 3120{ 3121 /* reset the core */ 3122 if (!brcms_deviceremoved(wlc_hw->wlc)) 3123 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); 3124 3125 /* purge the dma rings */ 3126 brcms_c_flushqueues(wlc_hw->wlc); 3127} 3128 3129void brcms_c_reset(struct brcms_c_info *wlc) 3130{ 3131 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); 3132 3133 /* slurp up hw mac counters before core reset */ 3134 brcms_c_statsupd(wlc); 3135 3136 /* reset our snapshot of macstat counters */ 3137 memset(wlc->core->macstat_snapshot, 0, sizeof(struct macstat)); 3138 3139 brcms_b_reset(wlc->hw); 3140} 3141 3142void brcms_c_init_scb(struct scb *scb) 3143{ 3144 int i; 3145 3146 memset(scb, 0, sizeof(struct scb)); 3147 scb->flags = SCB_WMECAP | SCB_HTCAP; 3148 for (i = 0; i < NUMPRIO; i++) { 3149 scb->seqnum[i] = 0; 3150 scb->seqctl[i] = 0xFFFF; 3151 } 3152 3153 scb->seqctl_nonqos = 0xFFFF; 3154 scb->magic = SCB_MAGIC; 3155} 3156 3157/* d11 core init 3158 * reset PSM 3159 * download ucode/PCM 3160 * let ucode run to suspended 3161 * download ucode inits 3162 * config other core registers 3163 * init dma 3164 */ 3165static void brcms_b_coreinit(struct brcms_c_info *wlc) 3166{ 3167 struct brcms_hardware *wlc_hw = wlc->hw; 3168 struct bcma_device *core = wlc_hw->d11core; 3169 u32 sflags; 3170 u32 bcnint_us; 3171 uint i = 0; 3172 bool fifosz_fixup = false; 3173 int err = 0; 3174 u16 buf[NFIFO]; 3175 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; 3176 3177 brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit); 3178 3179 /* reset PSM */ 3180 brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); 3181 3182 brcms_ucode_download(wlc_hw); 3183 /* 3184 * FIFOSZ fixup. driver wants to controls the fifo allocation. 3185 */ 3186 fifosz_fixup = true; 3187 3188 /* let the PSM run to the suspended state, set mode to BSS STA */ 3189 bcma_write32(core, D11REGOFFS(macintstatus), -1); 3190 brcms_b_mctrl(wlc_hw, ~0, 3191 (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); 3192 3193 /* wait for ucode to self-suspend after auto-init */ 3194 SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & 3195 MI_MACSSPNDD) == 0), 1000 * 1000); 3196 if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) 3197 brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-" 3198 "suspend!\n", wlc_hw->unit); 3199 3200 brcms_c_gpio_init(wlc); 3201 3202 sflags = bcma_aread32(core, BCMA_IOST); 3203 3204 if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { 3205 if (BRCMS_ISNPHY(wlc_hw->band)) 3206 brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); 3207 else 3208 brcms_err(core, "%s: wl%d: unsupported phy in corerev" 3209 " %d\n", __func__, wlc_hw->unit, 3210 wlc_hw->corerev); 3211 } else if (D11REV_IS(wlc_hw->corerev, 24)) { 3212 if (BRCMS_ISLCNPHY(wlc_hw->band)) 3213 brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); 3214 else 3215 brcms_err(core, "%s: wl%d: unsupported phy in corerev" 3216 " %d\n", __func__, wlc_hw->unit, 3217 wlc_hw->corerev); 3218 } else { 3219 brcms_err(core, "%s: wl%d: unsupported corerev %d\n", 3220 __func__, wlc_hw->unit, wlc_hw->corerev); 3221 } 3222 3223 /* For old ucode, txfifo sizes needs to be modified(increased) */ 3224 if (fifosz_fixup) 3225 brcms_b_corerev_fifofixup(wlc_hw); 3226 3227 /* check txfifo allocations match between ucode and driver */ 3228 buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0); 3229 if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { 3230 i = TX_AC_BE_FIFO; 3231 err = -1; 3232 } 3233 buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1); 3234 if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { 3235 i = TX_AC_VI_FIFO; 3236 err = -1; 3237 } 3238 buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2); 3239 buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; 3240 buf[TX_AC_BK_FIFO] &= 0xff; 3241 if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { 3242 i = TX_AC_BK_FIFO; 3243 err = -1; 3244 } 3245 if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) { 3246 i = TX_AC_VO_FIFO; 3247 err = -1; 3248 } 3249 buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3); 3250 buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; 3251 buf[TX_BCMC_FIFO] &= 0xff; 3252 if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { 3253 i = TX_BCMC_FIFO; 3254 err = -1; 3255 } 3256 if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) { 3257 i = TX_ATIM_FIFO; 3258 err = -1; 3259 } 3260 if (err != 0) 3261 brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d" 3262 " driver size %d index %d\n", buf[i], 3263 wlc_hw->xmtfifo_sz[i], i); 3264 3265 /* make sure we can still talk to the mac */ 3266 WARN_ON(bcma_read32(core, D11REGOFFS(maccontrol)) == 0xffffffff); 3267 3268 /* band-specific inits done by wlc_bsinit() */ 3269 3270 /* Set up frame burst size and antenna swap threshold init values */ 3271 brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); 3272 brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); 3273 3274 /* enable one rx interrupt per received frame */ 3275 bcma_write32(core, D11REGOFFS(intrcvlazy[0]), (1 << IRL_FC_SHIFT)); 3276 3277 /* set the station mode (BSS STA) */ 3278 brcms_b_mctrl(wlc_hw, 3279 (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), 3280 (MCTL_INFRA | MCTL_DISCARD_PMQ)); 3281 3282 /* set up Beacon interval */ 3283 bcnint_us = 0x8000 << 10; 3284 bcma_write32(core, D11REGOFFS(tsf_cfprep), 3285 (bcnint_us << CFPREP_CBI_SHIFT)); 3286 bcma_write32(core, D11REGOFFS(tsf_cfpstart), bcnint_us); 3287 bcma_write32(core, D11REGOFFS(macintstatus), MI_GP1); 3288 3289 /* write interrupt mask */ 3290 bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intmask), 3291 DEF_RXINTMASK); 3292 3293 /* allow the MAC to control the PHY clock (dynamic on/off) */ 3294 brcms_b_macphyclk_set(wlc_hw, ON); 3295 3296 /* program dynamic clock control fast powerup delay register */ 3297 wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih); 3298 bcma_write16(core, D11REGOFFS(scc_fastpwrup_dly), wlc->fastpwrup_dly); 3299 3300 /* tell the ucode the corerev */ 3301 brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); 3302 3303 /* tell the ucode MAC capabilities */ 3304 brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L, 3305 (u16) (wlc_hw->machwcap & 0xffff)); 3306 brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H, 3307 (u16) ((wlc_hw-> 3308 machwcap >> 16) & 0xffff)); 3309 3310 /* write retry limits to SCR, this done after PSM init */ 3311 bcma_write32(core, D11REGOFFS(objaddr), 3312 OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); 3313 (void)bcma_read32(core, D11REGOFFS(objaddr)); 3314 bcma_write32(core, D11REGOFFS(objdata), wlc_hw->SRL); 3315 bcma_write32(core, D11REGOFFS(objaddr), 3316 OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); 3317 (void)bcma_read32(core, D11REGOFFS(objaddr)); 3318 bcma_write32(core, D11REGOFFS(objdata), wlc_hw->LRL); 3319 3320 /* write rate fallback retry limits */ 3321 brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); 3322 brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); 3323 3324 bcma_mask16(core, D11REGOFFS(ifs_ctl), 0x0FFF); 3325 bcma_write16(core, D11REGOFFS(ifs_aifsn), EDCF_AIFSN_MIN); 3326 3327 /* init the tx dma engines */ 3328 for (i = 0; i < NFIFO; i++) { 3329 if (wlc_hw->di[i]) 3330 dma_txinit(wlc_hw->di[i]); 3331 } 3332 3333 /* init the rx dma engine(s) and post receive buffers */ 3334 dma_rxinit(wlc_hw->di[RX_FIFO]); 3335 dma_rxfill(wlc_hw->di[RX_FIFO]); 3336} 3337 3338void 3339static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { 3340 u32 macintmask; 3341 bool fastclk; 3342 struct brcms_c_info *wlc = wlc_hw->wlc; 3343 3344 /* request FAST clock if not on */ 3345 fastclk = wlc_hw->forcefastclk; 3346 if (!fastclk) 3347 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 3348 3349 /* disable interrupts */ 3350 macintmask = brcms_intrsoff(wlc->wl); 3351 3352 /* set up the specified band and chanspec */ 3353 brcms_c_setxband(wlc_hw, chspec_bandunit(chanspec)); 3354 wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); 3355 3356 /* do one-time phy inits and calibration */ 3357 wlc_phy_cal_init(wlc_hw->band->pi); 3358 3359 /* core-specific initialization */ 3360 brcms_b_coreinit(wlc); 3361 3362 /* band-specific inits */ 3363 brcms_b_bsinit(wlc, chanspec); 3364 3365 /* restore macintmask */ 3366 brcms_intrsrestore(wlc->wl, macintmask); 3367 3368 /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac 3369 * is suspended and brcms_c_enable_mac() will clear this override bit. 3370 */ 3371 mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND); 3372 3373 /* 3374 * initialize mac_suspend_depth to 1 to match ucode 3375 * initial suspended state 3376 */ 3377 wlc_hw->mac_suspend_depth = 1; 3378 3379 /* restore the clk */ 3380 if (!fastclk) 3381 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); 3382} 3383 3384static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc, 3385 u16 chanspec) 3386{ 3387 /* Save our copy of the chanspec */ 3388 wlc->chanspec = chanspec; 3389 3390 /* Set the chanspec and power limits for this locale */ 3391 brcms_c_channel_set_chanspec(wlc->cmi, chanspec, BRCMS_TXPWR_MAX); 3392 3393 if (wlc->stf->ss_algosel_auto) 3394 brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, 3395 chanspec); 3396 3397 brcms_c_stf_ss_update(wlc, wlc->band); 3398} 3399 3400static void 3401brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs) 3402{ 3403 brcms_c_rateset_default(rs, NULL, wlc->band->phytype, 3404 wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL, 3405 (bool) (wlc->pub->_n_enab & SUPPORT_11N), 3406 brcms_chspec_bw(wlc->default_bss->chanspec), 3407 wlc->stf->txstreams); 3408} 3409 3410/* derive wlc->band->basic_rate[] table from 'rateset' */ 3411static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, 3412 struct brcms_c_rateset *rateset) 3413{ 3414 u8 rate; 3415 u8 mandatory; 3416 u8 cck_basic = 0; 3417 u8 ofdm_basic = 0; 3418 u8 *br = wlc->band->basic_rate; 3419 uint i; 3420 3421 /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ 3422 memset(br, 0, BRCM_MAXRATE + 1); 3423 3424 /* For each basic rate in the rates list, make an entry in the 3425 * best basic lookup. 3426 */ 3427 for (i = 0; i < rateset->count; i++) { 3428 /* only make an entry for a basic rate */ 3429 if (!(rateset->rates[i] & BRCMS_RATE_FLAG)) 3430 continue; 3431 3432 /* mask off basic bit */ 3433 rate = (rateset->rates[i] & BRCMS_RATE_MASK); 3434 3435 if (rate > BRCM_MAXRATE) { 3436 brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: " 3437 "invalid rate 0x%X in rate set\n", 3438 rateset->rates[i]); 3439 continue; 3440 } 3441 3442 br[rate] = rate; 3443 } 3444 3445 /* The rate lookup table now has non-zero entries for each 3446 * basic rate, equal to the basic rate: br[basicN] = basicN 3447 * 3448 * To look up the best basic rate corresponding to any 3449 * particular rate, code can use the basic_rate table 3450 * like this 3451 * 3452 * basic_rate = wlc->band->basic_rate[tx_rate] 3453 * 3454 * Make sure there is a best basic rate entry for 3455 * every rate by walking up the table from low rates 3456 * to high, filling in holes in the lookup table 3457 */ 3458 3459 for (i = 0; i < wlc->band->hw_rateset.count; i++) { 3460 rate = wlc->band->hw_rateset.rates[i]; 3461 3462 if (br[rate] != 0) { 3463 /* This rate is a basic rate. 3464 * Keep track of the best basic rate so far by 3465 * modulation type. 3466 */ 3467 if (is_ofdm_rate(rate)) 3468 ofdm_basic = rate; 3469 else 3470 cck_basic = rate; 3471 3472 continue; 3473 } 3474 3475 /* This rate is not a basic rate so figure out the 3476 * best basic rate less than this rate and fill in 3477 * the hole in the table 3478 */ 3479 3480 br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic; 3481 3482 if (br[rate] != 0) 3483 continue; 3484 3485 if (is_ofdm_rate(rate)) { 3486 /* 3487 * In 11g and 11a, the OFDM mandatory rates 3488 * are 6, 12, and 24 Mbps 3489 */ 3490 if (rate >= BRCM_RATE_24M) 3491 mandatory = BRCM_RATE_24M; 3492 else if (rate >= BRCM_RATE_12M) 3493 mandatory = BRCM_RATE_12M; 3494 else 3495 mandatory = BRCM_RATE_6M; 3496 } else { 3497 /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */ 3498 mandatory = rate; 3499 } 3500 3501 br[rate] = mandatory; 3502 } 3503} 3504 3505static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, 3506 u16 chanspec) 3507{ 3508 struct brcms_c_rateset default_rateset; 3509 uint parkband; 3510 uint i, band_order[2]; 3511 3512 /* 3513 * We might have been bandlocked during down and the chip 3514 * power-cycled (hibernate). Figure out the right band to park on 3515 */ 3516 if (wlc->bandlocked || wlc->pub->_nbands == 1) { 3517 /* updated in brcms_c_bandlock() */ 3518 parkband = wlc->band->bandunit; 3519 band_order[0] = band_order[1] = parkband; 3520 } else { 3521 /* park on the band of the specified chanspec */ 3522 parkband = chspec_bandunit(chanspec); 3523 3524 /* order so that parkband initialize last */ 3525 band_order[0] = parkband ^ 1; 3526 band_order[1] = parkband; 3527 } 3528 3529 /* make each band operational, software state init */ 3530 for (i = 0; i < wlc->pub->_nbands; i++) { 3531 uint j = band_order[i]; 3532 3533 wlc->band = wlc->bandstate[j]; 3534 3535 brcms_default_rateset(wlc, &default_rateset); 3536 3537 /* fill in hw_rate */ 3538 brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset, 3539 false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK, 3540 (bool) (wlc->pub->_n_enab & SUPPORT_11N)); 3541 3542 /* init basic rate lookup */ 3543 brcms_c_rate_lookup_init(wlc, &default_rateset); 3544 } 3545 3546 /* sync up phy/radio chanspec */ 3547 brcms_c_set_phy_chanspec(wlc, chanspec); 3548} 3549 3550/* 3551 * Set or clear filtering related maccontrol bits based on 3552 * specified filter flags 3553 */ 3554void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags) 3555{ 3556 u32 promisc_bits = 0; 3557 3558 wlc->filter_flags = filter_flags; 3559 3560 if (filter_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) 3561 promisc_bits |= MCTL_PROMISC; 3562 3563 if (filter_flags & FIF_BCN_PRBRESP_PROMISC) 3564 promisc_bits |= MCTL_BCNS_PROMISC; 3565 3566 if (filter_flags & FIF_FCSFAIL) 3567 promisc_bits |= MCTL_KEEPBADFCS; 3568 3569 if (filter_flags & (FIF_CONTROL | FIF_PSPOLL)) 3570 promisc_bits |= MCTL_KEEPCONTROL; 3571 3572 brcms_b_mctrl(wlc->hw, 3573 MCTL_PROMISC | MCTL_BCNS_PROMISC | 3574 MCTL_KEEPCONTROL | MCTL_KEEPBADFCS, 3575 promisc_bits); 3576} 3577 3578/* 3579 * ucode, hwmac update 3580 * Channel dependent updates for ucode and hw 3581 */ 3582static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc) 3583{ 3584 /* enable or disable any active IBSSs depending on whether or not 3585 * we are on the home channel 3586 */ 3587 if (wlc->home_chanspec == wlc_phy_chanspec_get(wlc->band->pi)) { 3588 if (wlc->pub->associated) { 3589 /* 3590 * BMAC_NOTE: This is something that should be fixed 3591 * in ucode inits. I think that the ucode inits set 3592 * up the bcn templates and shm values with a bogus 3593 * beacon. This should not be done in the inits. If 3594 * ucode needs to set up a beacon for testing, the 3595 * test routines should write it down, not expect the 3596 * inits to populate a bogus beacon. 3597 */ 3598 if (BRCMS_PHY_11N_CAP(wlc->band)) 3599 brcms_b_write_shm(wlc->hw, 3600 M_BCN_TXTSF_OFFSET, 0); 3601 } 3602 } else { 3603 /* disable an active IBSS if we are not on the home channel */ 3604 } 3605} 3606 3607static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate, 3608 u8 basic_rate) 3609{ 3610 u8 phy_rate, index; 3611 u8 basic_phy_rate, basic_index; 3612 u16 dir_table, basic_table; 3613 u16 basic_ptr; 3614 3615 /* Shared memory address for the table we are reading */ 3616 dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B; 3617 3618 /* Shared memory address for the table we are writing */ 3619 basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B; 3620 3621 /* 3622 * for a given rate, the LS-nibble of the PLCP SIGNAL field is 3623 * the index into the rate table. 3624 */ 3625 phy_rate = rate_info[rate] & BRCMS_RATE_MASK; 3626 basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK; 3627 index = phy_rate & 0xf; 3628 basic_index = basic_phy_rate & 0xf; 3629 3630 /* Find the SHM pointer to the ACK rate entry by looking in the 3631 * Direct-map Table 3632 */ 3633 basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2)); 3634 3635 /* Update the SHM BSS-basic-rate-set mapping table with the pointer 3636 * to the correct basic rate for the given incoming rate 3637 */ 3638 brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr); 3639} 3640 3641static const struct brcms_c_rateset * 3642brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc) 3643{ 3644 const struct brcms_c_rateset *rs_dflt; 3645 3646 if (BRCMS_PHY_11N_CAP(wlc->band)) { 3647 if (wlc->band->bandtype == BRCM_BAND_5G) 3648 rs_dflt = &ofdm_mimo_rates; 3649 else 3650 rs_dflt = &cck_ofdm_mimo_rates; 3651 } else if (wlc->band->gmode) 3652 rs_dflt = &cck_ofdm_rates; 3653 else 3654 rs_dflt = &cck_rates; 3655 3656 return rs_dflt; 3657} 3658 3659static void brcms_c_set_ratetable(struct brcms_c_info *wlc) 3660{ 3661 const struct brcms_c_rateset *rs_dflt; 3662 struct brcms_c_rateset rs; 3663 u8 rate, basic_rate; 3664 uint i; 3665 3666 rs_dflt = brcms_c_rateset_get_hwrs(wlc); 3667 3668 brcms_c_rateset_copy(rs_dflt, &rs); 3669 brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams); 3670 3671 /* walk the phy rate table and update SHM basic rate lookup table */ 3672 for (i = 0; i < rs.count; i++) { 3673 rate = rs.rates[i] & BRCMS_RATE_MASK; 3674 3675 /* for a given rate brcms_basic_rate returns the rate at 3676 * which a response ACK/CTS should be sent. 3677 */ 3678 basic_rate = brcms_basic_rate(wlc, rate); 3679 if (basic_rate == 0) 3680 /* This should only happen if we are using a 3681 * restricted rateset. 3682 */ 3683 basic_rate = rs.rates[0] & BRCMS_RATE_MASK; 3684 3685 brcms_c_write_rate_shm(wlc, rate, basic_rate); 3686 } 3687} 3688 3689/* band-specific init */ 3690static void brcms_c_bsinit(struct brcms_c_info *wlc) 3691{ 3692 brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n", 3693 wlc->pub->unit, wlc->band->bandunit); 3694 3695 /* write ucode ACK/CTS rate table */ 3696 brcms_c_set_ratetable(wlc); 3697 3698 /* update some band specific mac configuration */ 3699 brcms_c_ucode_mac_upd(wlc); 3700 3701 /* init antenna selection */ 3702 brcms_c_antsel_init(wlc->asi); 3703 3704} 3705 3706/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ 3707static int 3708brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, 3709 bool writeToShm) 3710{ 3711 int idle_busy_ratio_x_16 = 0; 3712 uint offset = 3713 isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : 3714 M_TX_IDLE_BUSY_RATIO_X_16_CCK; 3715 if (duty_cycle > 100 || duty_cycle < 0) { 3716 brcms_err(wlc->hw->d11core, 3717 "wl%d: duty cycle value off limit\n", 3718 wlc->pub->unit); 3719 return -EINVAL; 3720 } 3721 if (duty_cycle) 3722 idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; 3723 /* Only write to shared memory when wl is up */ 3724 if (writeToShm) 3725 brcms_b_write_shm(wlc->hw, offset, (u16) idle_busy_ratio_x_16); 3726 3727 if (isOFDM) 3728 wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; 3729 else 3730 wlc->tx_duty_cycle_cck = (u16) duty_cycle; 3731 3732 return 0; 3733} 3734 3735/* push sw hps and wake state through hardware */ 3736static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) 3737{ 3738 u32 v1, v2; 3739 bool hps; 3740 bool awake_before; 3741 3742 hps = brcms_c_ps_allowed(wlc); 3743 3744 brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit, 3745 hps); 3746 3747 v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); 3748 v2 = MCTL_WAKE; 3749 if (hps) 3750 v2 |= MCTL_HPS; 3751 3752 brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2); 3753 3754 awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); 3755 3756 if (!awake_before) 3757 brcms_b_wait_for_wake(wlc->hw); 3758} 3759 3760/* 3761 * Write this BSS config's MAC address to core. 3762 * Updates RXE match engine. 3763 */ 3764static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg) 3765{ 3766 int err = 0; 3767 struct brcms_c_info *wlc = bsscfg->wlc; 3768 3769 /* enter the MAC addr into the RXE match registers */ 3770 brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, wlc->pub->cur_etheraddr); 3771 3772 brcms_c_ampdu_macaddr_upd(wlc); 3773 3774 return err; 3775} 3776 3777/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). 3778 * Updates RXE match engine. 3779 */ 3780static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg) 3781{ 3782 /* we need to update BSSID in RXE match registers */ 3783 brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID); 3784} 3785 3786static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot) 3787{ 3788 wlc_hw->shortslot = shortslot; 3789 3790 if (wlc_hw->band->bandtype == BRCM_BAND_2G && wlc_hw->up) { 3791 brcms_c_suspend_mac_and_wait(wlc_hw->wlc); 3792 brcms_b_update_slot_timing(wlc_hw, shortslot); 3793 brcms_c_enable_mac(wlc_hw->wlc); 3794 } 3795} 3796 3797/* 3798 * Suspend the the MAC and update the slot timing 3799 * for standard 11b/g (20us slots) or shortslot 11g (9us slots). 3800 */ 3801static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot) 3802{ 3803 /* use the override if it is set */ 3804 if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO) 3805 shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON); 3806 3807 if (wlc->shortslot == shortslot) 3808 return; 3809 3810 wlc->shortslot = shortslot; 3811 3812 brcms_b_set_shortslot(wlc->hw, shortslot); 3813} 3814 3815static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec) 3816{ 3817 if (wlc->home_chanspec != chanspec) { 3818 wlc->home_chanspec = chanspec; 3819 3820 if (wlc->pub->associated) 3821 wlc->bsscfg->current_bss->chanspec = chanspec; 3822 } 3823} 3824 3825void 3826brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, 3827 bool mute_tx, struct txpwr_limits *txpwr) 3828{ 3829 uint bandunit; 3830 3831 brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit, 3832 chanspec); 3833 3834 wlc_hw->chanspec = chanspec; 3835 3836 /* Switch bands if necessary */ 3837 if (wlc_hw->_nbands > 1) { 3838 bandunit = chspec_bandunit(chanspec); 3839 if (wlc_hw->band->bandunit != bandunit) { 3840 /* brcms_b_setband disables other bandunit, 3841 * use light band switch if not up yet 3842 */ 3843 if (wlc_hw->up) { 3844 wlc_phy_chanspec_radio_set(wlc_hw-> 3845 bandstate[bandunit]-> 3846 pi, chanspec); 3847 brcms_b_setband(wlc_hw, bandunit, chanspec); 3848 } else { 3849 brcms_c_setxband(wlc_hw, bandunit); 3850 } 3851 } 3852 } 3853 3854 wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx); 3855 3856 if (!wlc_hw->up) { 3857 if (wlc_hw->clk) 3858 wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, 3859 chanspec); 3860 wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); 3861 } else { 3862 wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec); 3863 wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); 3864 3865 /* Update muting of the channel */ 3866 brcms_b_mute(wlc_hw, mute_tx); 3867 } 3868} 3869 3870/* switch to and initialize new band */ 3871static void brcms_c_setband(struct brcms_c_info *wlc, 3872 uint bandunit) 3873{ 3874 wlc->band = wlc->bandstate[bandunit]; 3875 3876 if (!wlc->pub->up) 3877 return; 3878 3879 /* wait for at least one beacon before entering sleeping state */ 3880 brcms_c_set_ps_ctrl(wlc); 3881 3882 /* band-specific initializations */ 3883 brcms_c_bsinit(wlc); 3884} 3885 3886static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) 3887{ 3888 uint bandunit; 3889 bool switchband = false; 3890 u16 old_chanspec = wlc->chanspec; 3891 3892 if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { 3893 brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n", 3894 wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); 3895 return; 3896 } 3897 3898 /* Switch bands if necessary */ 3899 if (wlc->pub->_nbands > 1) { 3900 bandunit = chspec_bandunit(chanspec); 3901 if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { 3902 switchband = true; 3903 if (wlc->bandlocked) { 3904 brcms_err(wlc->hw->d11core, 3905 "wl%d: %s: chspec %d band is locked!\n", 3906 wlc->pub->unit, __func__, 3907 CHSPEC_CHANNEL(chanspec)); 3908 return; 3909 } 3910 /* 3911 * should the setband call come after the 3912 * brcms_b_chanspec() ? if the setband updates 3913 * (brcms_c_bsinit) use low level calls to inspect and 3914 * set state, the state inspected may be from the wrong 3915 * band, or the following brcms_b_set_chanspec() may 3916 * undo the work. 3917 */ 3918 brcms_c_setband(wlc, bandunit); 3919 } 3920 } 3921 3922 /* sync up phy/radio chanspec */ 3923 brcms_c_set_phy_chanspec(wlc, chanspec); 3924 3925 /* init antenna selection */ 3926 if (brcms_chspec_bw(old_chanspec) != brcms_chspec_bw(chanspec)) { 3927 brcms_c_antsel_init(wlc->asi); 3928 3929 /* Fix the hardware rateset based on bw. 3930 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz 3931 */ 3932 brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset, 3933 wlc->band->mimo_cap_40 ? brcms_chspec_bw(chanspec) : 0); 3934 } 3935 3936 /* update some mac configuration since chanspec changed */ 3937 brcms_c_ucode_mac_upd(wlc); 3938} 3939 3940/* 3941 * This function changes the phytxctl for beacon based on current 3942 * beacon ratespec AND txant setting as per this table: 3943 * ratespec CCK ant = wlc->stf->txant 3944 * OFDM ant = 3 3945 */ 3946void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, 3947 u32 bcn_rspec) 3948{ 3949 u16 phyctl; 3950 u16 phytxant = wlc->stf->phytxant; 3951 u16 mask = PHY_TXC_ANT_MASK; 3952 3953 /* for non-siso rates or default setting, use the available chains */ 3954 if (BRCMS_PHY_11N_CAP(wlc->band)) 3955 phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec); 3956 3957 phyctl = brcms_b_read_shm(wlc->hw, M_BCN_PCTLWD); 3958 phyctl = (phyctl & ~mask) | phytxant; 3959 brcms_b_write_shm(wlc->hw, M_BCN_PCTLWD, phyctl); 3960} 3961 3962/* 3963 * centralized protection config change function to simplify debugging, no 3964 * consistency checking this should be called only on changes to avoid overhead 3965 * in periodic function 3966 */ 3967void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) 3968{ 3969 /* 3970 * Cannot use brcms_dbg_* here because this function is called 3971 * before wlc is sufficiently initialized. 3972 */ 3973 BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); 3974 3975 switch (idx) { 3976 case BRCMS_PROT_G_SPEC: 3977 wlc->protection->_g = (bool) val; 3978 break; 3979 case BRCMS_PROT_G_OVR: 3980 wlc->protection->g_override = (s8) val; 3981 break; 3982 case BRCMS_PROT_G_USER: 3983 wlc->protection->gmode_user = (u8) val; 3984 break; 3985 case BRCMS_PROT_OVERLAP: 3986 wlc->protection->overlap = (s8) val; 3987 break; 3988 case BRCMS_PROT_N_USER: 3989 wlc->protection->nmode_user = (s8) val; 3990 break; 3991 case BRCMS_PROT_N_CFG: 3992 wlc->protection->n_cfg = (s8) val; 3993 break; 3994 case BRCMS_PROT_N_CFG_OVR: 3995 wlc->protection->n_cfg_override = (s8) val; 3996 break; 3997 case BRCMS_PROT_N_NONGF: 3998 wlc->protection->nongf = (bool) val; 3999 break; 4000 case BRCMS_PROT_N_NONGF_OVR: 4001 wlc->protection->nongf_override = (s8) val; 4002 break; 4003 case BRCMS_PROT_N_PAM_OVR: 4004 wlc->protection->n_pam_override = (s8) val; 4005 break; 4006 case BRCMS_PROT_N_OBSS: 4007 wlc->protection->n_obss = (bool) val; 4008 break; 4009 4010 default: 4011 break; 4012 } 4013 4014} 4015 4016static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val) 4017{ 4018 if (wlc->pub->up) { 4019 brcms_c_update_beacon(wlc); 4020 brcms_c_update_probe_resp(wlc, true); 4021 } 4022} 4023 4024static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val) 4025{ 4026 wlc->stf->ldpc = val; 4027 4028 if (wlc->pub->up) { 4029 brcms_c_update_beacon(wlc); 4030 brcms_c_update_probe_resp(wlc, true); 4031 wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); 4032 } 4033} 4034 4035void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, 4036 const struct ieee80211_tx_queue_params *params, 4037 bool suspend) 4038{ 4039 int i; 4040 struct shm_acparams acp_shm; 4041 u16 *shm_entry; 4042 4043 /* Only apply params if the core is out of reset and has clocks */ 4044 if (!wlc->clk) { 4045 brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n", 4046 wlc->pub->unit, __func__); 4047 return; 4048 } 4049 4050 memset(&acp_shm, 0, sizeof(struct shm_acparams)); 4051 /* fill in shm ac params struct */ 4052 acp_shm.txop = params->txop; 4053 /* convert from units of 32us to us for ucode */ 4054 wlc->edcf_txop[aci & 0x3] = acp_shm.txop = 4055 EDCF_TXOP2USEC(acp_shm.txop); 4056 acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); 4057 4058 if (aci == IEEE80211_AC_VI && acp_shm.txop == 0 4059 && acp_shm.aifs < EDCF_AIFSN_MAX) 4060 acp_shm.aifs++; 4061 4062 if (acp_shm.aifs < EDCF_AIFSN_MIN 4063 || acp_shm.aifs > EDCF_AIFSN_MAX) { 4064 brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad " 4065 "aifs %d\n", wlc->pub->unit, acp_shm.aifs); 4066 } else { 4067 acp_shm.cwmin = params->cw_min; 4068 acp_shm.cwmax = params->cw_max; 4069 acp_shm.cwcur = acp_shm.cwmin; 4070 acp_shm.bslots = 4071 bcma_read16(wlc->hw->d11core, D11REGOFFS(tsf_random)) & 4072 acp_shm.cwcur; 4073 acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; 4074 /* Indicate the new params to the ucode */ 4075 acp_shm.status = brcms_b_read_shm(wlc->hw, (M_EDCF_QINFO + 4076 wme_ac2fifo[aci] * 4077 M_EDCF_QLEN + 4078 M_EDCF_STATUS_OFF)); 4079 acp_shm.status |= WME_STATUS_NEWAC; 4080 4081 /* Fill in shm acparam table */ 4082 shm_entry = (u16 *) &acp_shm; 4083 for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2) 4084 brcms_b_write_shm(wlc->hw, 4085 M_EDCF_QINFO + 4086 wme_ac2fifo[aci] * M_EDCF_QLEN + i, 4087 *shm_entry++); 4088 } 4089 4090 if (suspend) 4091 brcms_c_suspend_mac_and_wait(wlc); 4092 4093 brcms_c_update_beacon(wlc); 4094 brcms_c_update_probe_resp(wlc, false); 4095 4096 if (suspend) 4097 brcms_c_enable_mac(wlc); 4098} 4099 4100static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) 4101{ 4102 u16 aci; 4103 int i_ac; 4104 struct ieee80211_tx_queue_params txq_pars; 4105 static const struct edcf_acparam default_edcf_acparams[] = { 4106 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, EDCF_AC_BE_TXOP_STA}, 4107 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, EDCF_AC_BK_TXOP_STA}, 4108 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, EDCF_AC_VI_TXOP_STA}, 4109 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, EDCF_AC_VO_TXOP_STA} 4110 }; /* ucode needs these parameters during its initialization */ 4111 const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0]; 4112 4113 for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) { 4114 /* find out which ac this set of params applies to */ 4115 aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; 4116 4117 /* fill in shm ac params struct */ 4118 txq_pars.txop = edcf_acp->TXOP; 4119 txq_pars.aifs = edcf_acp->ACI; 4120 4121 /* CWmin = 2^(ECWmin) - 1 */ 4122 txq_pars.cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); 4123 /* CWmax = 2^(ECWmax) - 1 */ 4124 txq_pars.cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) 4125 >> EDCF_ECWMAX_SHIFT); 4126 brcms_c_wme_setparams(wlc, aci, &txq_pars, suspend); 4127 } 4128 4129 if (suspend) { 4130 brcms_c_suspend_mac_and_wait(wlc); 4131 brcms_c_enable_mac(wlc); 4132 } 4133} 4134 4135static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) 4136{ 4137 /* Don't start the timer if HWRADIO feature is disabled */ 4138 if (wlc->radio_monitor) 4139 return; 4140 4141 wlc->radio_monitor = true; 4142 brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_RADIO_MON); 4143 brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); 4144} 4145 4146static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) 4147{ 4148 if (!wlc->radio_monitor) 4149 return true; 4150 4151 wlc->radio_monitor = false; 4152 brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_RADIO_MON); 4153 return brcms_del_timer(wlc->radio_timer); 4154} 4155 4156/* read hwdisable state and propagate to wlc flag */ 4157static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc) 4158{ 4159 if (wlc->pub->hw_off) 4160 return; 4161 4162 if (brcms_b_radio_read_hwdisabled(wlc->hw)) 4163 mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); 4164 else 4165 mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); 4166} 4167 4168/* update hwradio status and return it */ 4169bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) 4170{ 4171 brcms_c_radio_hwdisable_upd(wlc); 4172 4173 return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? 4174 true : false; 4175} 4176 4177/* periodical query hw radio button while driver is "down" */ 4178static void brcms_c_radio_timer(void *arg) 4179{ 4180 struct brcms_c_info *wlc = (struct brcms_c_info *) arg; 4181 4182 if (brcms_deviceremoved(wlc)) { 4183 brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", 4184 wlc->pub->unit, __func__); 4185 brcms_down(wlc->wl); 4186 return; 4187 } 4188 4189 brcms_c_radio_hwdisable_upd(wlc); 4190} 4191 4192/* common low-level watchdog code */ 4193static void brcms_b_watchdog(struct brcms_c_info *wlc) 4194{ 4195 struct brcms_hardware *wlc_hw = wlc->hw; 4196 4197 if (!wlc_hw->up) 4198 return; 4199 4200 /* increment second count */ 4201 wlc_hw->now++; 4202 4203 /* Check for FIFO error interrupts */ 4204 brcms_b_fifoerrors(wlc_hw); 4205 4206 /* make sure RX dma has buffers */ 4207 dma_rxfill(wlc->hw->di[RX_FIFO]); 4208 4209 wlc_phy_watchdog(wlc_hw->band->pi); 4210} 4211 4212/* common watchdog code */ 4213static void brcms_c_watchdog(struct brcms_c_info *wlc) 4214{ 4215 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); 4216 4217 if (!wlc->pub->up) 4218 return; 4219 4220 if (brcms_deviceremoved(wlc)) { 4221 brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", 4222 wlc->pub->unit, __func__); 4223 brcms_down(wlc->wl); 4224 return; 4225 } 4226 4227 /* increment second count */ 4228 wlc->pub->now++; 4229 4230 brcms_c_radio_hwdisable_upd(wlc); 4231 /* if radio is disable, driver may be down, quit here */ 4232 if (wlc->pub->radio_disabled) 4233 return; 4234 4235 brcms_b_watchdog(wlc); 4236 4237 /* 4238 * occasionally sample mac stat counters to 4239 * detect 16-bit counter wrap 4240 */ 4241 if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0) 4242 brcms_c_statsupd(wlc); 4243 4244 if (BRCMS_ISNPHY(wlc->band) && 4245 ((wlc->pub->now - wlc->tempsense_lasttime) >= 4246 BRCMS_TEMPSENSE_PERIOD)) { 4247 wlc->tempsense_lasttime = wlc->pub->now; 4248 brcms_c_tempsense_upd(wlc); 4249 } 4250} 4251 4252static void brcms_c_watchdog_by_timer(void *arg) 4253{ 4254 struct brcms_c_info *wlc = (struct brcms_c_info *) arg; 4255 4256 brcms_c_watchdog(wlc); 4257} 4258 4259static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit) 4260{ 4261 wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer, 4262 wlc, "watchdog"); 4263 if (!wlc->wdtimer) { 4264 wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for wdtimer " 4265 "failed\n", unit); 4266 goto fail; 4267 } 4268 4269 wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer, 4270 wlc, "radio"); 4271 if (!wlc->radio_timer) { 4272 wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for radio_timer " 4273 "failed\n", unit); 4274 goto fail; 4275 } 4276 4277 return true; 4278 4279 fail: 4280 return false; 4281} 4282 4283/* 4284 * Initialize brcms_c_info default values ... 4285 * may get overrides later in this function 4286 */ 4287static void brcms_c_info_init(struct brcms_c_info *wlc, int unit) 4288{ 4289 int i; 4290 4291 /* Save our copy of the chanspec */ 4292 wlc->chanspec = ch20mhz_chspec(1); 4293 4294 /* various 802.11g modes */ 4295 wlc->shortslot = false; 4296 wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO; 4297 4298 brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO); 4299 brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false); 4300 4301 brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR, 4302 BRCMS_PROTECTION_AUTO); 4303 brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF); 4304 brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR, 4305 BRCMS_PROTECTION_AUTO); 4306 brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false); 4307 brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO); 4308 4309 brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP, 4310 BRCMS_PROTECTION_CTL_OVERLAP); 4311 4312 /* 802.11g draft 4.0 NonERP elt advertisement */ 4313 wlc->include_legacy_erp = true; 4314 4315 wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; 4316 wlc->stf->txant = ANT_TX_DEF; 4317 4318 wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT; 4319 4320 wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; 4321 for (i = 0; i < NFIFO; i++) 4322 wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN; 4323 wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN; 4324 4325 /* default rate fallback retry limits */ 4326 wlc->SFBL = RETRY_SHORT_FB; 4327 wlc->LFBL = RETRY_LONG_FB; 4328 4329 /* default mac retry limits */ 4330 wlc->SRL = RETRY_SHORT_DEF; 4331 wlc->LRL = RETRY_LONG_DEF; 4332 4333 /* WME QoS mode is Auto by default */ 4334 wlc->pub->_ampdu = AMPDU_AGG_HOST; 4335} 4336 4337static uint brcms_c_attach_module(struct brcms_c_info *wlc) 4338{ 4339 uint err = 0; 4340 uint unit; 4341 unit = wlc->pub->unit; 4342 4343 wlc->asi = brcms_c_antsel_attach(wlc); 4344 if (wlc->asi == NULL) { 4345 wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach " 4346 "failed\n", unit); 4347 err = 44; 4348 goto fail; 4349 } 4350 4351 wlc->ampdu = brcms_c_ampdu_attach(wlc); 4352 if (wlc->ampdu == NULL) { 4353 wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach " 4354 "failed\n", unit); 4355 err = 50; 4356 goto fail; 4357 } 4358 4359 if ((brcms_c_stf_attach(wlc) != 0)) { 4360 wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach " 4361 "failed\n", unit); 4362 err = 68; 4363 goto fail; 4364 } 4365 fail: 4366 return err; 4367} 4368 4369struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc) 4370{ 4371 return wlc->pub; 4372} 4373 4374/* low level attach 4375 * run backplane attach, init nvram 4376 * run phy attach 4377 * initialize software state for each core and band 4378 * put the whole chip in reset(driver down state), no clock 4379 */ 4380static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, 4381 uint unit, bool piomode) 4382{ 4383 struct brcms_hardware *wlc_hw; 4384 uint err = 0; 4385 uint j; 4386 bool wme = false; 4387 struct shared_phy_params sha_params; 4388 struct wiphy *wiphy = wlc->wiphy; 4389 struct pci_dev *pcidev = core->bus->host_pci; 4390 struct ssb_sprom *sprom = &core->bus->sprom; 4391 4392 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) 4393 brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, 4394 pcidev->vendor, 4395 pcidev->device); 4396 else 4397 brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, 4398 core->bus->boardinfo.vendor, 4399 core->bus->boardinfo.type); 4400 4401 wme = true; 4402 4403 wlc_hw = wlc->hw; 4404 wlc_hw->wlc = wlc; 4405 wlc_hw->unit = unit; 4406 wlc_hw->band = wlc_hw->bandstate[0]; 4407 wlc_hw->_piomode = piomode; 4408 4409 /* populate struct brcms_hardware with default values */ 4410 brcms_b_info_init(wlc_hw); 4411 4412 /* 4413 * Do the hardware portion of the attach. Also initialize software 4414 * state that depends on the particular hardware we are running. 4415 */ 4416 wlc_hw->sih = ai_attach(core->bus); 4417 if (wlc_hw->sih == NULL) { 4418 wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n", 4419 unit); 4420 err = 11; 4421 goto fail; 4422 } 4423 4424 /* verify again the device is supported */ 4425 if (!brcms_c_chipmatch(core)) { 4426 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported device\n", 4427 unit); 4428 err = 12; 4429 goto fail; 4430 } 4431 4432 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { 4433 wlc_hw->vendorid = pcidev->vendor; 4434 wlc_hw->deviceid = pcidev->device; 4435 } else { 4436 wlc_hw->vendorid = core->bus->boardinfo.vendor; 4437 wlc_hw->deviceid = core->bus->boardinfo.type; 4438 } 4439 4440 wlc_hw->d11core = core; 4441 wlc_hw->corerev = core->id.rev; 4442 4443 /* validate chip, chiprev and corerev */ 4444 if (!brcms_c_isgoodchip(wlc_hw)) { 4445 err = 13; 4446 goto fail; 4447 } 4448 4449 /* initialize power control registers */ 4450 ai_clkctl_init(wlc_hw->sih); 4451 4452 /* request fastclock and force fastclock for the rest of attach 4453 * bring the d11 core out of reset. 4454 * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk 4455 * is still false; But it will be called again inside wlc_corereset, 4456 * after d11 is out of reset. 4457 */ 4458 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 4459 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); 4460 4461 if (!brcms_b_validate_chip_access(wlc_hw)) { 4462 wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access " 4463 "failed\n", unit); 4464 err = 14; 4465 goto fail; 4466 } 4467 4468 /* get the board rev, used just below */ 4469 j = sprom->board_rev; 4470 /* promote srom boardrev of 0xFF to 1 */ 4471 if (j == BOARDREV_PROMOTABLE) 4472 j = BOARDREV_PROMOTED; 4473 wlc_hw->boardrev = (u16) j; 4474 if (!brcms_c_validboardtype(wlc_hw)) { 4475 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom " 4476 "board type (0x%x)" " or revision level (0x%x)\n", 4477 unit, ai_get_boardtype(wlc_hw->sih), 4478 wlc_hw->boardrev); 4479 err = 15; 4480 goto fail; 4481 } 4482 wlc_hw->sromrev = sprom->revision; 4483 wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16); 4484 wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16); 4485 4486 if (wlc_hw->boardflags & BFL_NOPLLDOWN) 4487 brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED); 4488 4489 /* check device id(srom, nvram etc.) to set bands */ 4490 if (wlc_hw->deviceid == BCM43224_D11N_ID || 4491 wlc_hw->deviceid == BCM43224_D11N_ID_VEN1 || 4492 wlc_hw->deviceid == BCM43224_CHIP_ID) 4493 /* Dualband boards */ 4494 wlc_hw->_nbands = 2; 4495 else 4496 wlc_hw->_nbands = 1; 4497 4498 if ((ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM43225)) 4499 wlc_hw->_nbands = 1; 4500 4501 /* BMAC_NOTE: remove init of pub values when brcms_c_attach() 4502 * unconditionally does the init of these values 4503 */ 4504 wlc->vendorid = wlc_hw->vendorid; 4505 wlc->deviceid = wlc_hw->deviceid; 4506 wlc->pub->sih = wlc_hw->sih; 4507 wlc->pub->corerev = wlc_hw->corerev; 4508 wlc->pub->sromrev = wlc_hw->sromrev; 4509 wlc->pub->boardrev = wlc_hw->boardrev; 4510 wlc->pub->boardflags = wlc_hw->boardflags; 4511 wlc->pub->boardflags2 = wlc_hw->boardflags2; 4512 wlc->pub->_nbands = wlc_hw->_nbands; 4513 4514 wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); 4515 4516 if (wlc_hw->physhim == NULL) { 4517 wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach " 4518 "failed\n", unit); 4519 err = 25; 4520 goto fail; 4521 } 4522 4523 /* pass all the parameters to wlc_phy_shared_attach in one struct */ 4524 sha_params.sih = wlc_hw->sih; 4525 sha_params.physhim = wlc_hw->physhim; 4526 sha_params.unit = unit; 4527 sha_params.corerev = wlc_hw->corerev; 4528 sha_params.vid = wlc_hw->vendorid; 4529 sha_params.did = wlc_hw->deviceid; 4530 sha_params.chip = ai_get_chip_id(wlc_hw->sih); 4531 sha_params.chiprev = ai_get_chiprev(wlc_hw->sih); 4532 sha_params.chippkg = ai_get_chippkg(wlc_hw->sih); 4533 sha_params.sromrev = wlc_hw->sromrev; 4534 sha_params.boardtype = ai_get_boardtype(wlc_hw->sih); 4535 sha_params.boardrev = wlc_hw->boardrev; 4536 sha_params.boardflags = wlc_hw->boardflags; 4537 sha_params.boardflags2 = wlc_hw->boardflags2; 4538 4539 /* alloc and save pointer to shared phy state area */ 4540 wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params); 4541 if (!wlc_hw->phy_sh) { 4542 err = 16; 4543 goto fail; 4544 } 4545 4546 /* initialize software state for each core and band */ 4547 for (j = 0; j < wlc_hw->_nbands; j++) { 4548 /* 4549 * band0 is always 2.4Ghz 4550 * band1, if present, is 5Ghz 4551 */ 4552 4553 brcms_c_setxband(wlc_hw, j); 4554 4555 wlc_hw->band->bandunit = j; 4556 wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; 4557 wlc->band->bandunit = j; 4558 wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; 4559 wlc->core->coreidx = core->core_index; 4560 4561 wlc_hw->machwcap = bcma_read32(core, D11REGOFFS(machwcap)); 4562 wlc_hw->machwcap_backup = wlc_hw->machwcap; 4563 4564 /* init tx fifo size */ 4565 WARN_ON((wlc_hw->corerev - XMTFIFOTBL_STARTREV) < 0 || 4566 (wlc_hw->corerev - XMTFIFOTBL_STARTREV) > 4567 ARRAY_SIZE(xmtfifo_sz)); 4568 wlc_hw->xmtfifo_sz = 4569 xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; 4570 WARN_ON(!wlc_hw->xmtfifo_sz[0]); 4571 4572 /* Get a phy for this band */ 4573 wlc_hw->band->pi = 4574 wlc_phy_attach(wlc_hw->phy_sh, core, 4575 wlc_hw->band->bandtype, 4576 wlc->wiphy); 4577 if (wlc_hw->band->pi == NULL) { 4578 wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_" 4579 "attach failed\n", unit); 4580 err = 17; 4581 goto fail; 4582 } 4583 4584 wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap); 4585 4586 wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype, 4587 &wlc_hw->band->phyrev, 4588 &wlc_hw->band->radioid, 4589 &wlc_hw->band->radiorev); 4590 wlc_hw->band->abgphy_encore = 4591 wlc_phy_get_encore(wlc_hw->band->pi); 4592 wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi); 4593 wlc_hw->band->core_flags = 4594 wlc_phy_get_coreflags(wlc_hw->band->pi); 4595 4596 /* verify good phy_type & supported phy revision */ 4597 if (BRCMS_ISNPHY(wlc_hw->band)) { 4598 if (NCONF_HAS(wlc_hw->band->phyrev)) 4599 goto good_phy; 4600 else 4601 goto bad_phy; 4602 } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { 4603 if (LCNCONF_HAS(wlc_hw->band->phyrev)) 4604 goto good_phy; 4605 else 4606 goto bad_phy; 4607 } else { 4608 bad_phy: 4609 wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported " 4610 "phy type/rev (%d/%d)\n", unit, 4611 wlc_hw->band->phytype, wlc_hw->band->phyrev); 4612 err = 18; 4613 goto fail; 4614 } 4615 4616 good_phy: 4617 /* 4618 * BMAC_NOTE: wlc->band->pi should not be set below and should 4619 * be done in the high level attach. However we can not make 4620 * that change until all low level access is changed to 4621 * wlc_hw->band->pi. Instead do the wlc->band->pi init below, 4622 * keeping wlc_hw->band->pi as well for incremental update of 4623 * low level fns, and cut over low only init when all fns 4624 * updated. 4625 */ 4626 wlc->band->pi = wlc_hw->band->pi; 4627 wlc->band->phytype = wlc_hw->band->phytype; 4628 wlc->band->phyrev = wlc_hw->band->phyrev; 4629 wlc->band->radioid = wlc_hw->band->radioid; 4630 wlc->band->radiorev = wlc_hw->band->radiorev; 4631 4632 /* default contention windows size limits */ 4633 wlc_hw->band->CWmin = APHY_CWMIN; 4634 wlc_hw->band->CWmax = PHY_CWMAX; 4635 4636 if (!brcms_b_attach_dmapio(wlc, j, wme)) { 4637 err = 19; 4638 goto fail; 4639 } 4640 } 4641 4642 /* disable core to match driver "down" state */ 4643 brcms_c_coredisable(wlc_hw); 4644 4645 /* Match driver "down" state */ 4646 ai_pci_down(wlc_hw->sih); 4647 4648 /* turn off pll and xtal to match driver "down" state */ 4649 brcms_b_xtal(wlc_hw, OFF); 4650 4651 /* ******************************************************************* 4652 * The hardware is in the DOWN state at this point. D11 core 4653 * or cores are in reset with clocks off, and the board PLLs 4654 * are off if possible. 4655 * 4656 * Beyond this point, wlc->sbclk == false and chip registers 4657 * should not be touched. 4658 ********************************************************************* 4659 */ 4660 4661 /* init etheraddr state variables */ 4662 brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr); 4663 4664 if (is_broadcast_ether_addr(wlc_hw->etheraddr) || 4665 is_zero_ether_addr(wlc_hw->etheraddr)) { 4666 wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n", 4667 unit); 4668 err = 22; 4669 goto fail; 4670 } 4671 4672 brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n", 4673 wlc_hw->deviceid, wlc_hw->_nbands, 4674 ai_get_boardtype(wlc_hw->sih)); 4675 4676 return err; 4677 4678 fail: 4679 wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit, 4680 err); 4681 return err; 4682} 4683 4684static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc) 4685{ 4686 uint unit; 4687 unit = wlc->pub->unit; 4688 4689 if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { 4690 /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ 4691 wlc->band->antgain = 8; 4692 } else if (wlc->band->antgain == -1) { 4693 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in" 4694 " srom, using 2dB\n", unit, __func__); 4695 wlc->band->antgain = 8; 4696 } else { 4697 s8 gain, fract; 4698 /* Older sroms specified gain in whole dbm only. In order 4699 * be able to specify qdbm granularity and remain backward 4700 * compatible the whole dbms are now encoded in only 4701 * low 6 bits and remaining qdbms are encoded in the hi 2 bits. 4702 * 6 bit signed number ranges from -32 - 31. 4703 * 4704 * Examples: 4705 * 0x1 = 1 db, 4706 * 0xc1 = 1.75 db (1 + 3 quarters), 4707 * 0x3f = -1 (-1 + 0 quarters), 4708 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm. 4709 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm. 4710 */ 4711 gain = wlc->band->antgain & 0x3f; 4712 gain <<= 2; /* Sign extend */ 4713 gain >>= 2; 4714 fract = (wlc->band->antgain & 0xc0) >> 6; 4715 wlc->band->antgain = 4 * gain + fract; 4716 } 4717} 4718 4719static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) 4720{ 4721 int aa; 4722 uint unit; 4723 int bandtype; 4724 struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; 4725 4726 unit = wlc->pub->unit; 4727 bandtype = wlc->band->bandtype; 4728 4729 /* get antennas available */ 4730 if (bandtype == BRCM_BAND_5G) 4731 aa = sprom->ant_available_a; 4732 else 4733 aa = sprom->ant_available_bg; 4734 4735 if ((aa < 1) || (aa > 15)) { 4736 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in" 4737 " srom (0x%x), using 3\n", unit, __func__, aa); 4738 aa = 3; 4739 } 4740 4741 /* reset the defaults if we have a single antenna */ 4742 if (aa == 1) { 4743 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0; 4744 wlc->stf->txant = ANT_TX_FORCE_0; 4745 } else if (aa == 2) { 4746 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1; 4747 wlc->stf->txant = ANT_TX_FORCE_1; 4748 } else { 4749 } 4750 4751 /* Compute Antenna Gain */ 4752 if (bandtype == BRCM_BAND_5G) 4753 wlc->band->antgain = sprom->antenna_gain.a1; 4754 else 4755 wlc->band->antgain = sprom->antenna_gain.a0; 4756 4757 brcms_c_attach_antgain_init(wlc); 4758 4759 return true; 4760} 4761 4762static void brcms_c_bss_default_init(struct brcms_c_info *wlc) 4763{ 4764 u16 chanspec; 4765 struct brcms_band *band; 4766 struct brcms_bss_info *bi = wlc->default_bss; 4767 4768 /* init default and target BSS with some sane initial values */ 4769 memset(bi, 0, sizeof(*bi)); 4770 bi->beacon_period = BEACON_INTERVAL_DEFAULT; 4771 4772 /* fill the default channel as the first valid channel 4773 * starting from the 2G channels 4774 */ 4775 chanspec = ch20mhz_chspec(1); 4776 wlc->home_chanspec = bi->chanspec = chanspec; 4777 4778 /* find the band of our default channel */ 4779 band = wlc->band; 4780 if (wlc->pub->_nbands > 1 && 4781 band->bandunit != chspec_bandunit(chanspec)) 4782 band = wlc->bandstate[OTHERBANDUNIT(wlc)]; 4783 4784 /* init bss rates to the band specific default rate set */ 4785 brcms_c_rateset_default(&bi->rateset, NULL, band->phytype, 4786 band->bandtype, false, BRCMS_RATE_MASK_FULL, 4787 (bool) (wlc->pub->_n_enab & SUPPORT_11N), 4788 brcms_chspec_bw(chanspec), wlc->stf->txstreams); 4789 4790 if (wlc->pub->_n_enab & SUPPORT_11N) 4791 bi->flags |= BRCMS_BSS_HT; 4792} 4793 4794static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) 4795{ 4796 uint i; 4797 struct brcms_band *band; 4798 4799 for (i = 0; i < wlc->pub->_nbands; i++) { 4800 band = wlc->bandstate[i]; 4801 if (band->bandtype == BRCM_BAND_5G) { 4802 if ((bwcap == BRCMS_N_BW_40ALL) 4803 || (bwcap == BRCMS_N_BW_20IN2G_40IN5G)) 4804 band->mimo_cap_40 = true; 4805 else 4806 band->mimo_cap_40 = false; 4807 } else { 4808 if (bwcap == BRCMS_N_BW_40ALL) 4809 band->mimo_cap_40 = true; 4810 else 4811 band->mimo_cap_40 = false; 4812 } 4813 } 4814} 4815 4816static void brcms_c_timers_deinit(struct brcms_c_info *wlc) 4817{ 4818 /* free timer state */ 4819 if (wlc->wdtimer) { 4820 brcms_free_timer(wlc->wdtimer); 4821 wlc->wdtimer = NULL; 4822 } 4823 if (wlc->radio_timer) { 4824 brcms_free_timer(wlc->radio_timer); 4825 wlc->radio_timer = NULL; 4826 } 4827} 4828 4829static void brcms_c_detach_module(struct brcms_c_info *wlc) 4830{ 4831 if (wlc->asi) { 4832 brcms_c_antsel_detach(wlc->asi); 4833 wlc->asi = NULL; 4834 } 4835 4836 if (wlc->ampdu) { 4837 brcms_c_ampdu_detach(wlc->ampdu); 4838 wlc->ampdu = NULL; 4839 } 4840 4841 brcms_c_stf_detach(wlc); 4842} 4843 4844/* 4845 * low level detach 4846 */ 4847static int brcms_b_detach(struct brcms_c_info *wlc) 4848{ 4849 uint i; 4850 struct brcms_hw_band *band; 4851 struct brcms_hardware *wlc_hw = wlc->hw; 4852 int callbacks; 4853 4854 callbacks = 0; 4855 4856 brcms_b_detach_dmapio(wlc_hw); 4857 4858 band = wlc_hw->band; 4859 for (i = 0; i < wlc_hw->_nbands; i++) { 4860 if (band->pi) { 4861 /* Detach this band's phy */ 4862 wlc_phy_detach(band->pi); 4863 band->pi = NULL; 4864 } 4865 band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)]; 4866 } 4867 4868 /* Free shared phy state */ 4869 kfree(wlc_hw->phy_sh); 4870 4871 wlc_phy_shim_detach(wlc_hw->physhim); 4872 4873 if (wlc_hw->sih) { 4874 ai_detach(wlc_hw->sih); 4875 wlc_hw->sih = NULL; 4876 } 4877 4878 return callbacks; 4879 4880} 4881 4882/* 4883 * Return a count of the number of driver callbacks still pending. 4884 * 4885 * General policy is that brcms_c_detach can only dealloc/free software states. 4886 * It can NOT touch hardware registers since the d11core may be in reset and 4887 * clock may not be available. 4888 * One exception is sb register access, which is possible if crystal is turned 4889 * on after "down" state, driver should avoid software timer with the exception 4890 * of radio_monitor. 4891 */ 4892uint brcms_c_detach(struct brcms_c_info *wlc) 4893{ 4894 uint callbacks = 0; 4895 4896 if (wlc == NULL) 4897 return 0; 4898 4899 callbacks += brcms_b_detach(wlc); 4900 4901 /* delete software timers */ 4902 if (!brcms_c_radio_monitor_stop(wlc)) 4903 callbacks++; 4904 4905 brcms_c_channel_mgr_detach(wlc->cmi); 4906 4907 brcms_c_timers_deinit(wlc); 4908 4909 brcms_c_detach_module(wlc); 4910 4911 brcms_c_detach_mfree(wlc); 4912 return callbacks; 4913} 4914 4915/* update state that depends on the current value of "ap" */ 4916static void brcms_c_ap_upd(struct brcms_c_info *wlc) 4917{ 4918 /* STA-BSS; short capable */ 4919 wlc->PLCPHdr_override = BRCMS_PLCP_SHORT; 4920} 4921 4922/* Initialize just the hardware when coming out of POR or S3/S5 system states */ 4923static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) 4924{ 4925 if (wlc_hw->wlc->pub->hw_up) 4926 return; 4927 4928 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); 4929 4930 /* 4931 * Enable pll and xtal, initialize the power control registers, 4932 * and force fastclock for the remainder of brcms_c_up(). 4933 */ 4934 brcms_b_xtal(wlc_hw, ON); 4935 ai_clkctl_init(wlc_hw->sih); 4936 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 4937 4938 /* 4939 * TODO: test suspend/resume 4940 * 4941 * AI chip doesn't restore bar0win2 on 4942 * hibernation/resume, need sw fixup 4943 */ 4944 4945 /* 4946 * Inform phy that a POR reset has occurred so 4947 * it does a complete phy init 4948 */ 4949 wlc_phy_por_inform(wlc_hw->band->pi); 4950 4951 wlc_hw->ucode_loaded = false; 4952 wlc_hw->wlc->pub->hw_up = true; 4953 4954 if ((wlc_hw->boardflags & BFL_FEM) 4955 && (ai_get_chip_id(wlc_hw->sih) == BCMA_CHIP_ID_BCM4313)) { 4956 if (! 4957 (wlc_hw->boardrev >= 0x1250 4958 && (wlc_hw->boardflags & BFL_FEM_BT))) 4959 ai_epa_4313war(wlc_hw->sih); 4960 } 4961} 4962 4963static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) 4964{ 4965 brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); 4966 4967 /* 4968 * Enable pll and xtal, initialize the power control registers, 4969 * and force fastclock for the remainder of brcms_c_up(). 4970 */ 4971 brcms_b_xtal(wlc_hw, ON); 4972 ai_clkctl_init(wlc_hw->sih); 4973 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 4974 4975 /* 4976 * Configure pci/pcmcia here instead of in brcms_c_attach() 4977 * to allow mfg hotswap: down, hotswap (chip power cycle), up. 4978 */ 4979 bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, 4980 true); 4981 4982 /* 4983 * Need to read the hwradio status here to cover the case where the 4984 * system is loaded with the hw radio disabled. We do not want to 4985 * bring the driver up in this case. 4986 */ 4987 if (brcms_b_radio_read_hwdisabled(wlc_hw)) { 4988 /* put SB PCI in down state again */ 4989 ai_pci_down(wlc_hw->sih); 4990 brcms_b_xtal(wlc_hw, OFF); 4991 return -ENOMEDIUM; 4992 } 4993 4994 ai_pci_up(wlc_hw->sih); 4995 4996 /* reset the d11 core */ 4997 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); 4998 4999 return 0; 5000} 5001 5002static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) 5003{ 5004 wlc_hw->up = true; 5005 wlc_phy_hw_state_upd(wlc_hw->band->pi, true); 5006 5007 /* FULLY enable dynamic power control and d11 core interrupt */ 5008 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC); 5009 brcms_intrson(wlc_hw->wlc->wl); 5010 return 0; 5011} 5012 5013/* 5014 * Write WME tunable parameters for retransmit/max rate 5015 * from wlc struct to ucode 5016 */ 5017static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) 5018{ 5019 int ac; 5020 5021 /* Need clock to do this */ 5022 if (!wlc->clk) 5023 return; 5024 5025 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 5026 brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac), 5027 wlc->wme_retries[ac]); 5028} 5029 5030/* make interface operational */ 5031int brcms_c_up(struct brcms_c_info *wlc) 5032{ 5033 struct ieee80211_channel *ch; 5034 5035 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); 5036 5037 /* HW is turned off so don't try to access it */ 5038 if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) 5039 return -ENOMEDIUM; 5040 5041 if (!wlc->pub->hw_up) { 5042 brcms_b_hw_up(wlc->hw); 5043 wlc->pub->hw_up = true; 5044 } 5045 5046 if ((wlc->pub->boardflags & BFL_FEM) 5047 && (ai_get_chip_id(wlc->hw->sih) == BCMA_CHIP_ID_BCM4313)) { 5048 if (wlc->pub->boardrev >= 0x1250 5049 && (wlc->pub->boardflags & BFL_FEM_BT)) 5050 brcms_b_mhf(wlc->hw, MHF5, MHF5_4313_GPIOCTRL, 5051 MHF5_4313_GPIOCTRL, BRCM_BAND_ALL); 5052 else 5053 brcms_b_mhf(wlc->hw, MHF4, MHF4_EXTPA_ENABLE, 5054 MHF4_EXTPA_ENABLE, BRCM_BAND_ALL); 5055 } 5056 5057 /* 5058 * Need to read the hwradio status here to cover the case where the 5059 * system is loaded with the hw radio disabled. We do not want to bring 5060 * the driver up in this case. If radio is disabled, abort up, lower 5061 * power, start radio timer and return 0(for NDIS) don't call 5062 * radio_update to avoid looping brcms_c_up. 5063 * 5064 * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only 5065 */ 5066 if (!wlc->pub->radio_disabled) { 5067 int status = brcms_b_up_prep(wlc->hw); 5068 if (status == -ENOMEDIUM) { 5069 if (!mboolisset 5070 (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { 5071 struct brcms_bss_cfg *bsscfg = wlc->bsscfg; 5072 mboolset(wlc->pub->radio_disabled, 5073 WL_RADIO_HW_DISABLE); 5074 if (bsscfg->type == BRCMS_TYPE_STATION || 5075 bsscfg->type == BRCMS_TYPE_ADHOC) 5076 brcms_err(wlc->hw->d11core, 5077 "wl%d: up: rfdisable -> " 5078 "bsscfg_disable()\n", 5079 wlc->pub->unit); 5080 } 5081 } 5082 } 5083 5084 if (wlc->pub->radio_disabled) { 5085 brcms_c_radio_monitor_start(wlc); 5086 return 0; 5087 } 5088 5089 /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */ 5090 wlc->clk = true; 5091 5092 brcms_c_radio_monitor_stop(wlc); 5093 5094 /* Set EDCF hostflags */ 5095 brcms_b_mhf(wlc->hw, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL); 5096 5097 brcms_init(wlc->wl); 5098 wlc->pub->up = true; 5099 5100 if (wlc->bandinit_pending) { 5101 ch = wlc->pub->ieee_hw->conf.channel; 5102 brcms_c_suspend_mac_and_wait(wlc); 5103 brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value)); 5104 wlc->bandinit_pending = false; 5105 brcms_c_enable_mac(wlc); 5106 } 5107 5108 brcms_b_up_finish(wlc->hw); 5109 5110 /* Program the TX wme params with the current settings */ 5111 brcms_c_wme_retries_write(wlc); 5112 5113 /* start one second watchdog timer */ 5114 brcms_add_timer(wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); 5115 wlc->WDarmed = true; 5116 5117 /* ensure antenna config is up to date */ 5118 brcms_c_stf_phy_txant_upd(wlc); 5119 /* ensure LDPC config is in sync */ 5120 brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc); 5121 5122 return 0; 5123} 5124 5125static uint brcms_c_down_del_timer(struct brcms_c_info *wlc) 5126{ 5127 uint callbacks = 0; 5128 5129 return callbacks; 5130} 5131 5132static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) 5133{ 5134 bool dev_gone; 5135 uint callbacks = 0; 5136 5137 if (!wlc_hw->up) 5138 return callbacks; 5139 5140 dev_gone = brcms_deviceremoved(wlc_hw->wlc); 5141 5142 /* disable interrupts */ 5143 if (dev_gone) 5144 wlc_hw->wlc->macintmask = 0; 5145 else { 5146 /* now disable interrupts */ 5147 brcms_intrsoff(wlc_hw->wlc->wl); 5148 5149 /* ensure we're running on the pll clock again */ 5150 brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST); 5151 } 5152 /* down phy at the last of this stage */ 5153 callbacks += wlc_phy_down(wlc_hw->band->pi); 5154 5155 return callbacks; 5156} 5157 5158static int brcms_b_down_finish(struct brcms_hardware *wlc_hw) 5159{ 5160 uint callbacks = 0; 5161 bool dev_gone; 5162 5163 if (!wlc_hw->up) 5164 return callbacks; 5165 5166 wlc_hw->up = false; 5167 wlc_phy_hw_state_upd(wlc_hw->band->pi, false); 5168 5169 dev_gone = brcms_deviceremoved(wlc_hw->wlc); 5170 5171 if (dev_gone) { 5172 wlc_hw->sbclk = false; 5173 wlc_hw->clk = false; 5174 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); 5175 5176 /* reclaim any posted packets */ 5177 brcms_c_flushqueues(wlc_hw->wlc); 5178 } else { 5179 5180 /* Reset and disable the core */ 5181 if (bcma_core_is_enabled(wlc_hw->d11core)) { 5182 if (bcma_read32(wlc_hw->d11core, 5183 D11REGOFFS(maccontrol)) & MCTL_EN_MAC) 5184 brcms_c_suspend_mac_and_wait(wlc_hw->wlc); 5185 callbacks += brcms_reset(wlc_hw->wlc->wl); 5186 brcms_c_coredisable(wlc_hw); 5187 } 5188 5189 /* turn off primary xtal and pll */ 5190 if (!wlc_hw->noreset) { 5191 ai_pci_down(wlc_hw->sih); 5192 brcms_b_xtal(wlc_hw, OFF); 5193 } 5194 } 5195 5196 return callbacks; 5197} 5198 5199/* 5200 * Mark the interface nonoperational, stop the software mechanisms, 5201 * disable the hardware, free any transient buffer state. 5202 * Return a count of the number of driver callbacks still pending. 5203 */ 5204uint brcms_c_down(struct brcms_c_info *wlc) 5205{ 5206 5207 uint callbacks = 0; 5208 int i; 5209 bool dev_gone = false; 5210 5211 brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); 5212 5213 /* check if we are already in the going down path */ 5214 if (wlc->going_down) { 5215 brcms_err(wlc->hw->d11core, 5216 "wl%d: %s: Driver going down so return\n", 5217 wlc->pub->unit, __func__); 5218 return 0; 5219 } 5220 if (!wlc->pub->up) 5221 return callbacks; 5222 5223 wlc->going_down = true; 5224 5225 callbacks += brcms_b_bmac_down_prep(wlc->hw); 5226 5227 dev_gone = brcms_deviceremoved(wlc); 5228 5229 /* Call any registered down handlers */ 5230 for (i = 0; i < BRCMS_MAXMODULES; i++) { 5231 if (wlc->modulecb[i].down_fn) 5232 callbacks += 5233 wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); 5234 } 5235 5236 /* cancel the watchdog timer */ 5237 if (wlc->WDarmed) { 5238 if (!brcms_del_timer(wlc->wdtimer)) 5239 callbacks++; 5240 wlc->WDarmed = false; 5241 } 5242 /* cancel all other timers */ 5243 callbacks += brcms_c_down_del_timer(wlc); 5244 5245 wlc->pub->up = false; 5246 5247 wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); 5248 5249 callbacks += brcms_b_down_finish(wlc->hw); 5250 5251 /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ 5252 wlc->clk = false; 5253 5254 wlc->going_down = false; 5255 return callbacks; 5256} 5257 5258/* Set the current gmode configuration */ 5259int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) 5260{ 5261 int ret = 0; 5262 uint i; 5263 struct brcms_c_rateset rs; 5264 /* Default to 54g Auto */ 5265 /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ 5266 s8 shortslot = BRCMS_SHORTSLOT_AUTO; 5267 bool shortslot_restrict = false; /* Restrict association to stations 5268 * that support shortslot 5269 */ 5270 bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ 5271 /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ 5272 int preamble = BRCMS_PLCP_LONG; 5273 bool preamble_restrict = false; /* Restrict association to stations 5274 * that support short preambles 5275 */ 5276 struct brcms_band *band; 5277 5278 /* if N-support is enabled, allow Gmode set as long as requested 5279 * Gmode is not GMODE_LEGACY_B 5280 */ 5281 if ((wlc->pub->_n_enab & SUPPORT_11N) && gmode == GMODE_LEGACY_B) 5282 return -ENOTSUPP; 5283 5284 /* verify that we are dealing with 2G band and grab the band pointer */ 5285 if (wlc->band->bandtype == BRCM_BAND_2G) 5286 band = wlc->band; 5287 else if ((wlc->pub->_nbands > 1) && 5288 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G)) 5289 band = wlc->bandstate[OTHERBANDUNIT(wlc)]; 5290 else 5291 return -EINVAL; 5292 5293 /* update configuration value */ 5294 if (config) 5295 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode); 5296 5297 /* Clear rateset override */ 5298 memset(&rs, 0, sizeof(rs)); 5299 5300 switch (gmode) { 5301 case GMODE_LEGACY_B: 5302 shortslot = BRCMS_SHORTSLOT_OFF; 5303 brcms_c_rateset_copy(&gphy_legacy_rates, &rs); 5304 5305 break; 5306 5307 case GMODE_LRS: 5308 break; 5309 5310 case GMODE_AUTO: 5311 /* Accept defaults */ 5312 break; 5313 5314 case GMODE_ONLY: 5315 ofdm_basic = true; 5316 preamble = BRCMS_PLCP_SHORT; 5317 preamble_restrict = true; 5318 break; 5319 5320 case GMODE_PERFORMANCE: 5321 shortslot = BRCMS_SHORTSLOT_ON; 5322 shortslot_restrict = true; 5323 ofdm_basic = true; 5324 preamble = BRCMS_PLCP_SHORT; 5325 preamble_restrict = true; 5326 break; 5327 5328 default: 5329 /* Error */ 5330 brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n", 5331 wlc->pub->unit, __func__, gmode); 5332 return -ENOTSUPP; 5333 } 5334 5335 band->gmode = gmode; 5336 5337 wlc->shortslot_override = shortslot; 5338 5339 /* Use the default 11g rateset */ 5340 if (!rs.count) 5341 brcms_c_rateset_copy(&cck_ofdm_rates, &rs); 5342 5343 if (ofdm_basic) { 5344 for (i = 0; i < rs.count; i++) { 5345 if (rs.rates[i] == BRCM_RATE_6M 5346 || rs.rates[i] == BRCM_RATE_12M 5347 || rs.rates[i] == BRCM_RATE_24M) 5348 rs.rates[i] |= BRCMS_RATE_FLAG; 5349 } 5350 } 5351 5352 /* Set default bss rateset */ 5353 wlc->default_bss->rateset.count = rs.count; 5354 memcpy(wlc->default_bss->rateset.rates, rs.rates, 5355 sizeof(wlc->default_bss->rateset.rates)); 5356 5357 return ret; 5358} 5359 5360int brcms_c_set_nmode(struct brcms_c_info *wlc) 5361{ 5362 uint i; 5363 s32 nmode = AUTO; 5364 5365 if (wlc->stf->txstreams == WL_11N_3x3) 5366 nmode = WL_11N_3x3; 5367 else 5368 nmode = WL_11N_2x2; 5369 5370 /* force GMODE_AUTO if NMODE is ON */ 5371 brcms_c_set_gmode(wlc, GMODE_AUTO, true); 5372 if (nmode == WL_11N_3x3) 5373 wlc->pub->_n_enab = SUPPORT_HT; 5374 else 5375 wlc->pub->_n_enab = SUPPORT_11N; 5376 wlc->default_bss->flags |= BRCMS_BSS_HT; 5377 /* add the mcs rates to the default and hw ratesets */ 5378 brcms_c_rateset_mcs_build(&wlc->default_bss->rateset, 5379 wlc->stf->txstreams); 5380 for (i = 0; i < wlc->pub->_nbands; i++) 5381 memcpy(wlc->bandstate[i]->hw_rateset.mcs, 5382 wlc->default_bss->rateset.mcs, MCSSET_LEN); 5383 5384 return 0; 5385} 5386 5387static int 5388brcms_c_set_internal_rateset(struct brcms_c_info *wlc, 5389 struct brcms_c_rateset *rs_arg) 5390{ 5391 struct brcms_c_rateset rs, new; 5392 uint bandunit; 5393 5394 memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset)); 5395 5396 /* check for bad count value */ 5397 if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES)) 5398 return -EINVAL; 5399 5400 /* try the current band */ 5401 bandunit = wlc->band->bandunit; 5402 memcpy(&new, &rs, sizeof(struct brcms_c_rateset)); 5403 if (brcms_c_rate_hwrs_filter_sort_validate 5404 (&new, &wlc->bandstate[bandunit]->hw_rateset, true, 5405 wlc->stf->txstreams)) 5406 goto good; 5407 5408 /* try the other band */ 5409 if (brcms_is_mband_unlocked(wlc)) { 5410 bandunit = OTHERBANDUNIT(wlc); 5411 memcpy(&new, &rs, sizeof(struct brcms_c_rateset)); 5412 if (brcms_c_rate_hwrs_filter_sort_validate(&new, 5413 &wlc-> 5414 bandstate[bandunit]-> 5415 hw_rateset, true, 5416 wlc->stf->txstreams)) 5417 goto good; 5418 } 5419 5420 return -EBADE; 5421 5422 good: 5423 /* apply new rateset */ 5424 memcpy(&wlc->default_bss->rateset, &new, 5425 sizeof(struct brcms_c_rateset)); 5426 memcpy(&wlc->bandstate[bandunit]->defrateset, &new, 5427 sizeof(struct brcms_c_rateset)); 5428 return 0; 5429} 5430 5431static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc) 5432{ 5433 u8 r; 5434 bool war = false; 5435 5436 if (wlc->pub->associated) 5437 r = wlc->bsscfg->current_bss->rateset.rates[0]; 5438 else 5439 r = wlc->default_bss->rateset.rates[0]; 5440 5441 wlc_phy_ofdm_rateset_war(wlc->band->pi, war); 5442} 5443 5444int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel) 5445{ 5446 u16 chspec = ch20mhz_chspec(channel); 5447 5448 if (channel < 0 || channel > MAXCHANNEL) 5449 return -EINVAL; 5450 5451 if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec)) 5452 return -EINVAL; 5453 5454 5455 if (!wlc->pub->up && brcms_is_mband_unlocked(wlc)) { 5456 if (wlc->band->bandunit != chspec_bandunit(chspec)) 5457 wlc->bandinit_pending = true; 5458 else 5459 wlc->bandinit_pending = false; 5460 } 5461 5462 wlc->default_bss->chanspec = chspec; 5463 /* brcms_c_BSSinit() will sanitize the rateset before 5464 * using it.. */ 5465 if (wlc->pub->up && (wlc_phy_chanspec_get(wlc->band->pi) != chspec)) { 5466 brcms_c_set_home_chanspec(wlc, chspec); 5467 brcms_c_suspend_mac_and_wait(wlc); 5468 brcms_c_set_chanspec(wlc, chspec); 5469 brcms_c_enable_mac(wlc); 5470 } 5471 return 0; 5472} 5473 5474int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl) 5475{ 5476 int ac; 5477 5478 if (srl < 1 || srl > RETRY_SHORT_MAX || 5479 lrl < 1 || lrl > RETRY_SHORT_MAX) 5480 return -EINVAL; 5481 5482 wlc->SRL = srl; 5483 wlc->LRL = lrl; 5484 5485 brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); 5486 5487 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 5488 wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], 5489 EDCF_SHORT, wlc->SRL); 5490 wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], 5491 EDCF_LONG, wlc->LRL); 5492 } 5493 brcms_c_wme_retries_write(wlc); 5494 5495 return 0; 5496} 5497 5498void brcms_c_get_current_rateset(struct brcms_c_info *wlc, 5499 struct brcm_rateset *currs) 5500{ 5501 struct brcms_c_rateset *rs; 5502 5503 if (wlc->pub->associated) 5504 rs = &wlc->bsscfg->current_bss->rateset; 5505 else 5506 rs = &wlc->default_bss->rateset; 5507 5508 /* Copy only legacy rateset section */ 5509 currs->count = rs->count; 5510 memcpy(&currs->rates, &rs->rates, rs->count); 5511} 5512 5513int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs) 5514{ 5515 struct brcms_c_rateset internal_rs; 5516 int bcmerror; 5517 5518 if (rs->count > BRCMS_NUMRATES) 5519 return -ENOBUFS; 5520 5521 memset(&internal_rs, 0, sizeof(internal_rs)); 5522 5523 /* Copy only legacy rateset section */ 5524 internal_rs.count = rs->count; 5525 memcpy(&internal_rs.rates, &rs->rates, internal_rs.count); 5526 5527 /* merge rateset coming in with the current mcsset */ 5528 if (wlc->pub->_n_enab & SUPPORT_11N) { 5529 struct brcms_bss_info *mcsset_bss; 5530 if (wlc->pub->associated) 5531 mcsset_bss = wlc->bsscfg->current_bss; 5532 else 5533 mcsset_bss = wlc->default_bss; 5534 memcpy(internal_rs.mcs, &mcsset_bss->rateset.mcs[0], 5535 MCSSET_LEN); 5536 } 5537 5538 bcmerror = brcms_c_set_internal_rateset(wlc, &internal_rs); 5539 if (!bcmerror) 5540 brcms_c_ofdm_rateset_war(wlc); 5541 5542 return bcmerror; 5543} 5544 5545static void brcms_c_time_lock(struct brcms_c_info *wlc) 5546{ 5547 bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD); 5548 /* Commit the write */ 5549 bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); 5550} 5551 5552static void brcms_c_time_unlock(struct brcms_c_info *wlc) 5553{ 5554 bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD); 5555 /* Commit the write */ 5556 bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); 5557} 5558 5559int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period) 5560{ 5561 u32 bcnint_us; 5562 5563 if (period == 0) 5564 return -EINVAL; 5565 5566 wlc->default_bss->beacon_period = period; 5567 5568 bcnint_us = period << 10; 5569 brcms_c_time_lock(wlc); 5570 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfprep), 5571 (bcnint_us << CFPREP_CBI_SHIFT)); 5572 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfpstart), bcnint_us); 5573 brcms_c_time_unlock(wlc); 5574 5575 return 0; 5576} 5577 5578u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx) 5579{ 5580 return wlc->band->phytype; 5581} 5582 5583void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override) 5584{ 5585 wlc->shortslot_override = sslot_override; 5586 5587 /* 5588 * shortslot is an 11g feature, so no more work if we are 5589 * currently on the 5G band 5590 */ 5591 if (wlc->band->bandtype == BRCM_BAND_5G) 5592 return; 5593 5594 if (wlc->pub->up && wlc->pub->associated) { 5595 /* let watchdog or beacon processing update shortslot */ 5596 } else if (wlc->pub->up) { 5597 /* unassociated shortslot is off */ 5598 brcms_c_switch_shortslot(wlc, false); 5599 } else { 5600 /* driver is down, so just update the brcms_c_info 5601 * value */ 5602 if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO) 5603 wlc->shortslot = false; 5604 else 5605 wlc->shortslot = 5606 (wlc->shortslot_override == 5607 BRCMS_SHORTSLOT_ON); 5608 } 5609} 5610 5611/* 5612 * register watchdog and down handlers. 5613 */ 5614int brcms_c_module_register(struct brcms_pub *pub, 5615 const char *name, struct brcms_info *hdl, 5616 int (*d_fn)(void *handle)) 5617{ 5618 struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc; 5619 int i; 5620 5621 /* find an empty entry and just add, no duplication check! */ 5622 for (i = 0; i < BRCMS_MAXMODULES; i++) { 5623 if (wlc->modulecb[i].name[0] == '\0') { 5624 strncpy(wlc->modulecb[i].name, name, 5625 sizeof(wlc->modulecb[i].name) - 1); 5626 wlc->modulecb[i].hdl = hdl; 5627 wlc->modulecb[i].down_fn = d_fn; 5628 return 0; 5629 } 5630 } 5631 5632 return -ENOSR; 5633} 5634 5635/* unregister module callbacks */ 5636int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, 5637 struct brcms_info *hdl) 5638{ 5639 struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc; 5640 int i; 5641 5642 if (wlc == NULL) 5643 return -ENODATA; 5644 5645 for (i = 0; i < BRCMS_MAXMODULES; i++) { 5646 if (!strcmp(wlc->modulecb[i].name, name) && 5647 (wlc->modulecb[i].hdl == hdl)) { 5648 memset(&wlc->modulecb[i], 0, sizeof(wlc->modulecb[i])); 5649 return 0; 5650 } 5651 } 5652 5653 /* table not found! */ 5654 return -ENODATA; 5655} 5656 5657static bool brcms_c_chipmatch_pci(struct bcma_device *core) 5658{ 5659 struct pci_dev *pcidev = core->bus->host_pci; 5660 u16 vendor = pcidev->vendor; 5661 u16 device = pcidev->device; 5662 5663 if (vendor != PCI_VENDOR_ID_BROADCOM) { 5664 pr_err("unknown vendor id %04x\n", vendor); 5665 return false; 5666 } 5667 5668 if (device == BCM43224_D11N_ID_VEN1 || device == BCM43224_CHIP_ID) 5669 return true; 5670 if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) 5671 return true; 5672 if (device == BCM4313_D11N2G_ID) 5673 return true; 5674 if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) 5675 return true; 5676 5677 pr_err("unknown device id %04x\n", device); 5678 return false; 5679} 5680 5681static bool brcms_c_chipmatch_soc(struct bcma_device *core) 5682{ 5683 struct bcma_chipinfo *chipinfo = &core->bus->chipinfo; 5684 5685 if (chipinfo->id == BCMA_CHIP_ID_BCM4716) 5686 return true; 5687 5688 pr_err("unknown chip id %04x\n", chipinfo->id); 5689 return false; 5690} 5691 5692bool brcms_c_chipmatch(struct bcma_device *core) 5693{ 5694 switch (core->bus->hosttype) { 5695 case BCMA_HOSTTYPE_PCI: 5696 return brcms_c_chipmatch_pci(core); 5697 case BCMA_HOSTTYPE_SOC: 5698 return brcms_c_chipmatch_soc(core); 5699 default: 5700 pr_err("unknown host type: %i\n", core->bus->hosttype); 5701 return false; 5702 } 5703} 5704 5705u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) 5706{ 5707 u16 table_ptr; 5708 u8 phy_rate, index; 5709 5710 /* get the phy specific rate encoding for the PLCP SIGNAL field */ 5711 if (is_ofdm_rate(rate)) 5712 table_ptr = M_RT_DIRMAP_A; 5713 else 5714 table_ptr = M_RT_DIRMAP_B; 5715 5716 /* for a given rate, the LS-nibble of the PLCP SIGNAL field is 5717 * the index into the rate table. 5718 */ 5719 phy_rate = rate_info[rate] & BRCMS_RATE_MASK; 5720 index = phy_rate & 0xf; 5721 5722 /* Find the SHM pointer to the rate table entry by looking in the 5723 * Direct-map Table 5724 */ 5725 return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); 5726} 5727 5728/* 5729 * bcmc_fid_generate: 5730 * Generate frame ID for a BCMC packet. The frag field is not used 5731 * for MC frames so is used as part of the sequence number. 5732 */ 5733static inline u16 5734bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg, 5735 struct d11txh *txh) 5736{ 5737 u16 frameid; 5738 5739 frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK | 5740 TXFID_QUEUE_MASK); 5741 frameid |= 5742 (((wlc-> 5743 mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | 5744 TX_BCMC_FIFO; 5745 5746 return frameid; 5747} 5748 5749static uint 5750brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec, 5751 u8 preamble_type) 5752{ 5753 uint dur = 0; 5754 5755 /* 5756 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that 5757 * is less than or equal to the rate of the immediately previous 5758 * frame in the FES 5759 */ 5760 rspec = brcms_basic_rate(wlc, rspec); 5761 /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ 5762 dur = 5763 brcms_c_calc_frame_time(wlc, rspec, preamble_type, 5764 (DOT11_ACK_LEN + FCS_LEN)); 5765 return dur; 5766} 5767 5768static uint 5769brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, 5770 u8 preamble_type) 5771{ 5772 return brcms_c_calc_ack_time(wlc, rspec, preamble_type); 5773} 5774 5775static uint 5776brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, 5777 u8 preamble_type) 5778{ 5779 /* 5780 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that 5781 * is less than or equal to the rate of the immediately previous 5782 * frame in the FES 5783 */ 5784 rspec = brcms_basic_rate(wlc, rspec); 5785 /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ 5786 return brcms_c_calc_frame_time(wlc, rspec, preamble_type, 5787 (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + 5788 FCS_LEN)); 5789} 5790 5791/* brcms_c_compute_frame_dur() 5792 * 5793 * Calculate the 802.11 MAC header DUR field for MPDU 5794 * DUR for a single frame = 1 SIFS + 1 ACK 5795 * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time 5796 * 5797 * rate MPDU rate in unit of 500kbps 5798 * next_frag_len next MPDU length in bytes 5799 * preamble_type use short/GF or long/MM PLCP header 5800 */ 5801static u16 5802brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate, 5803 u8 preamble_type, uint next_frag_len) 5804{ 5805 u16 dur, sifs; 5806 5807 sifs = get_sifs(wlc->band); 5808 5809 dur = sifs; 5810 dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type); 5811 5812 if (next_frag_len) { 5813 /* Double the current DUR to get 2 SIFS + 2 ACKs */ 5814 dur *= 2; 5815 /* add another SIFS and the frag time */ 5816 dur += sifs; 5817 dur += 5818 (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type, 5819 next_frag_len); 5820 } 5821 return dur; 5822} 5823 5824/* The opposite of brcms_c_calc_frame_time */ 5825static uint 5826brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec, 5827 u8 preamble_type, uint dur) 5828{ 5829 uint nsyms, mac_len, Ndps, kNdps; 5830 uint rate = rspec2rate(ratespec); 5831 5832 if (is_mcs_rate(ratespec)) { 5833 uint mcs = ratespec & RSPEC_RATE_MASK; 5834 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); 5835 dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); 5836 /* payload calculation matches that of regular ofdm */ 5837 if (wlc->band->bandtype == BRCM_BAND_2G) 5838 dur -= DOT11_OFDM_SIGNAL_EXTENSION; 5839 /* kNdbps = kbps * 4 */ 5840 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec), 5841 rspec_issgi(ratespec)) * 4; 5842 nsyms = dur / APHY_SYMBOL_TIME; 5843 mac_len = 5844 ((nsyms * kNdps) - 5845 ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000; 5846 } else if (is_ofdm_rate(ratespec)) { 5847 dur -= APHY_PREAMBLE_TIME; 5848 dur -= APHY_SIGNAL_TIME; 5849 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ 5850 Ndps = rate * 2; 5851 nsyms = dur / APHY_SYMBOL_TIME; 5852 mac_len = 5853 ((nsyms * Ndps) - 5854 (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; 5855 } else { 5856 if (preamble_type & BRCMS_SHORT_PREAMBLE) 5857 dur -= BPHY_PLCP_SHORT_TIME; 5858 else 5859 dur -= BPHY_PLCP_TIME; 5860 mac_len = dur * rate; 5861 /* divide out factor of 2 in rate (1/2 mbps) */ 5862 mac_len = mac_len / 8 / 2; 5863 } 5864 return mac_len; 5865} 5866 5867/* 5868 * Return true if the specified rate is supported by the specified band. 5869 * BRCM_BAND_AUTO indicates the current band. 5870 */ 5871static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band, 5872 bool verbose) 5873{ 5874 struct brcms_c_rateset *hw_rateset; 5875 uint i; 5876 5877 if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype)) 5878 hw_rateset = &wlc->band->hw_rateset; 5879 else if (wlc->pub->_nbands > 1) 5880 hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; 5881 else 5882 /* other band specified and we are a single band device */ 5883 return false; 5884 5885 /* check if this is a mimo rate */ 5886 if (is_mcs_rate(rspec)) { 5887 if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE) 5888 goto error; 5889 5890 return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK)); 5891 } 5892 5893 for (i = 0; i < hw_rateset->count; i++) 5894 if (hw_rateset->rates[i] == rspec2rate(rspec)) 5895 return true; 5896 error: 5897 if (verbose) 5898 brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x " 5899 "not in hw_rateset\n", wlc->pub->unit, rspec); 5900 5901 return false; 5902} 5903 5904static u32 5905mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, 5906 u32 int_val) 5907{ 5908 struct bcma_device *core = wlc->hw->d11core; 5909 u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; 5910 u8 rate = int_val & NRATE_RATE_MASK; 5911 u32 rspec; 5912 bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); 5913 bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); 5914 bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) 5915 == NRATE_OVERRIDE_MCS_ONLY); 5916 int bcmerror = 0; 5917 5918 if (!ismcs) 5919 return (u32) rate; 5920 5921 /* validate the combination of rate/mcs/stf is allowed */ 5922 if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { 5923 /* mcs only allowed when nmode */ 5924 if (stf > PHY_TXC1_MODE_SDM) { 5925 brcms_err(core, "wl%d: %s: Invalid stf\n", 5926 wlc->pub->unit, __func__); 5927 bcmerror = -EINVAL; 5928 goto done; 5929 } 5930 5931 /* mcs 32 is a special case, DUP mode 40 only */ 5932 if (rate == 32) { 5933 if (!CHSPEC_IS40(wlc->home_chanspec) || 5934 ((stf != PHY_TXC1_MODE_SISO) 5935 && (stf != PHY_TXC1_MODE_CDD))) { 5936 brcms_err(core, "wl%d: %s: Invalid mcs 32\n", 5937 wlc->pub->unit, __func__); 5938 bcmerror = -EINVAL; 5939 goto done; 5940 } 5941 /* mcs > 7 must use stf SDM */ 5942 } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { 5943 /* mcs > 7 must use stf SDM */ 5944 if (stf != PHY_TXC1_MODE_SDM) { 5945 brcms_dbg_mac80211(core, "wl%d: enabling " 5946 "SDM mode for mcs %d\n", 5947 wlc->pub->unit, rate); 5948 stf = PHY_TXC1_MODE_SDM; 5949 } 5950 } else { 5951 /* 5952 * MCS 0-7 may use SISO, CDD, and for 5953 * phy_rev >= 3 STBC 5954 */ 5955 if ((stf > PHY_TXC1_MODE_STBC) || 5956 (!BRCMS_STBC_CAP_PHY(wlc) 5957 && (stf == PHY_TXC1_MODE_STBC))) { 5958 brcms_err(core, "wl%d: %s: Invalid STBC\n", 5959 wlc->pub->unit, __func__); 5960 bcmerror = -EINVAL; 5961 goto done; 5962 } 5963 } 5964 } else if (is_ofdm_rate(rate)) { 5965 if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { 5966 brcms_err(core, "wl%d: %s: Invalid OFDM\n", 5967 wlc->pub->unit, __func__); 5968 bcmerror = -EINVAL; 5969 goto done; 5970 } 5971 } else if (is_cck_rate(rate)) { 5972 if ((cur_band->bandtype != BRCM_BAND_2G) 5973 || (stf != PHY_TXC1_MODE_SISO)) { 5974 brcms_err(core, "wl%d: %s: Invalid CCK\n", 5975 wlc->pub->unit, __func__); 5976 bcmerror = -EINVAL; 5977 goto done; 5978 } 5979 } else { 5980 brcms_err(core, "wl%d: %s: Unknown rate type\n", 5981 wlc->pub->unit, __func__); 5982 bcmerror = -EINVAL; 5983 goto done; 5984 } 5985 /* make sure multiple antennae are available for non-siso rates */ 5986 if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { 5987 brcms_err(core, "wl%d: %s: SISO antenna but !SISO " 5988 "request\n", wlc->pub->unit, __func__); 5989 bcmerror = -EINVAL; 5990 goto done; 5991 } 5992 5993 rspec = rate; 5994 if (ismcs) { 5995 rspec |= RSPEC_MIMORATE; 5996 /* For STBC populate the STC field of the ratespec */ 5997 if (stf == PHY_TXC1_MODE_STBC) { 5998 u8 stc; 5999 stc = 1; /* Nss for single stream is always 1 */ 6000 rspec |= (stc << RSPEC_STC_SHIFT); 6001 } 6002 } 6003 6004 rspec |= (stf << RSPEC_STF_SHIFT); 6005 6006 if (override_mcs_only) 6007 rspec |= RSPEC_OVERRIDE_MCS_ONLY; 6008 6009 if (issgi) 6010 rspec |= RSPEC_SHORT_GI; 6011 6012 if ((rate != 0) 6013 && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true)) 6014 return rate; 6015 6016 return rspec; 6017done: 6018 return rate; 6019} 6020 6021/* 6022 * Compute PLCP, but only requires actual rate and length of pkt. 6023 * Rate is given in the driver standard multiple of 500 kbps. 6024 * le is set for 11 Mbps rate if necessary. 6025 * Broken out for PRQ. 6026 */ 6027 6028static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, 6029 uint length, u8 *plcp) 6030{ 6031 u16 usec = 0; 6032 u8 le = 0; 6033 6034 switch (rate_500) { 6035 case BRCM_RATE_1M: 6036 usec = length << 3; 6037 break; 6038 case BRCM_RATE_2M: 6039 usec = length << 2; 6040 break; 6041 case BRCM_RATE_5M5: 6042 usec = (length << 4) / 11; 6043 if ((length << 4) - (usec * 11) > 0) 6044 usec++; 6045 break; 6046 case BRCM_RATE_11M: 6047 usec = (length << 3) / 11; 6048 if ((length << 3) - (usec * 11) > 0) { 6049 usec++; 6050 if ((usec * 11) - (length << 3) >= 8) 6051 le = D11B_PLCP_SIGNAL_LE; 6052 } 6053 break; 6054 6055 default: 6056 brcms_err(wlc->hw->d11core, 6057 "brcms_c_cck_plcp_set: unsupported rate %d\n", 6058 rate_500); 6059 rate_500 = BRCM_RATE_1M; 6060 usec = length << 3; 6061 break; 6062 } 6063 /* PLCP signal byte */ 6064 plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */ 6065 /* PLCP service byte */ 6066 plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED); 6067 /* PLCP length u16, little endian */ 6068 plcp[2] = usec & 0xff; 6069 plcp[3] = (usec >> 8) & 0xff; 6070 /* PLCP CRC16 */ 6071 plcp[4] = 0; 6072 plcp[5] = 0; 6073} 6074 6075/* Rate: 802.11 rate code, length: PSDU length in octets */ 6076static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp) 6077{ 6078 u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); 6079 plcp[0] = mcs; 6080 if (rspec_is40mhz(rspec) || (mcs == 32)) 6081 plcp[0] |= MIMO_PLCP_40MHZ; 6082 BRCMS_SET_MIMO_PLCP_LEN(plcp, length); 6083 plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */ 6084 plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ 6085 plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ 6086 plcp[5] = 0; 6087} 6088 6089/* Rate: 802.11 rate code, length: PSDU length in octets */ 6090static void 6091brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp) 6092{ 6093 u8 rate_signal; 6094 u32 tmp = 0; 6095 int rate = rspec2rate(rspec); 6096 6097 /* 6098 * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb 6099 * transmitted first 6100 */ 6101 rate_signal = rate_info[rate] & BRCMS_RATE_MASK; 6102 memset(plcp, 0, D11_PHY_HDR_LEN); 6103 D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal); 6104 6105 tmp = (length & 0xfff) << 5; 6106 plcp[2] |= (tmp >> 16) & 0xff; 6107 plcp[1] |= (tmp >> 8) & 0xff; 6108 plcp[0] |= tmp & 0xff; 6109} 6110 6111/* Rate: 802.11 rate code, length: PSDU length in octets */ 6112static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec, 6113 uint length, u8 *plcp) 6114{ 6115 int rate = rspec2rate(rspec); 6116 6117 brcms_c_cck_plcp_set(wlc, rate, length, plcp); 6118} 6119 6120static void 6121brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec, 6122 uint length, u8 *plcp) 6123{ 6124 if (is_mcs_rate(rspec)) 6125 brcms_c_compute_mimo_plcp(rspec, length, plcp); 6126 else if (is_ofdm_rate(rspec)) 6127 brcms_c_compute_ofdm_plcp(rspec, length, plcp); 6128 else 6129 brcms_c_compute_cck_plcp(wlc, rspec, length, plcp); 6130} 6131 6132/* brcms_c_compute_rtscts_dur() 6133 * 6134 * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame 6135 * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK 6136 * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK 6137 * 6138 * cts cts-to-self or rts/cts 6139 * rts_rate rts or cts rate in unit of 500kbps 6140 * rate next MPDU rate in unit of 500kbps 6141 * frame_len next MPDU frame length in bytes 6142 */ 6143u16 6144brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, 6145 u32 rts_rate, 6146 u32 frame_rate, u8 rts_preamble_type, 6147 u8 frame_preamble_type, uint frame_len, bool ba) 6148{ 6149 u16 dur, sifs; 6150 6151 sifs = get_sifs(wlc->band); 6152 6153 if (!cts_only) { 6154 /* RTS/CTS */ 6155 dur = 3 * sifs; 6156 dur += 6157 (u16) brcms_c_calc_cts_time(wlc, rts_rate, 6158 rts_preamble_type); 6159 } else { 6160 /* CTS-TO-SELF */ 6161 dur = 2 * sifs; 6162 } 6163 6164 dur += 6165 (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type, 6166 frame_len); 6167 if (ba) 6168 dur += 6169 (u16) brcms_c_calc_ba_time(wlc, frame_rate, 6170 BRCMS_SHORT_PREAMBLE); 6171 else 6172 dur += 6173 (u16) brcms_c_calc_ack_time(wlc, frame_rate, 6174 frame_preamble_type); 6175 return dur; 6176} 6177 6178static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) 6179{ 6180 u16 phyctl1 = 0; 6181 u16 bw; 6182 6183 if (BRCMS_ISLCNPHY(wlc->band)) { 6184 bw = PHY_TXC1_BW_20MHZ; 6185 } else { 6186 bw = rspec_get_bw(rspec); 6187 /* 10Mhz is not supported yet */ 6188 if (bw < PHY_TXC1_BW_20MHZ) { 6189 brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is " 6190 "not supported yet, set to 20L\n", bw); 6191 bw = PHY_TXC1_BW_20MHZ; 6192 } 6193 } 6194 6195 if (is_mcs_rate(rspec)) { 6196 uint mcs = rspec & RSPEC_RATE_MASK; 6197 6198 /* bw, stf, coding-type is part of rspec_phytxbyte2 returns */ 6199 phyctl1 = rspec_phytxbyte2(rspec); 6200 /* set the upper byte of phyctl1 */ 6201 phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); 6202 } else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band) 6203 && !BRCMS_ISSSLPNPHY(wlc->band)) { 6204 /* 6205 * In CCK mode LPPHY overloads OFDM Modulation bits with CCK 6206 * Data Rate. Eventually MIMOPHY would also be converted to 6207 * this format 6208 */ 6209 /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ 6210 phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT)); 6211 } else { /* legacy OFDM/CCK */ 6212 s16 phycfg; 6213 /* get the phyctl byte from rate phycfg table */ 6214 phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); 6215 if (phycfg == -1) { 6216 brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong " 6217 "legacy OFDM/CCK rate\n"); 6218 phycfg = 0; 6219 } 6220 /* set the upper byte of phyctl1 */ 6221 phyctl1 = 6222 (bw | (phycfg << 8) | 6223 (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT)); 6224 } 6225 return phyctl1; 6226} 6227 6228/* 6229 * Add struct d11txh, struct cck_phy_hdr. 6230 * 6231 * 'p' data must start with 802.11 MAC header 6232 * 'p' must allow enough bytes of local headers to be "pushed" onto the packet 6233 * 6234 * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) 6235 * 6236 */ 6237static u16 6238brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, 6239 struct sk_buff *p, struct scb *scb, uint frag, 6240 uint nfrags, uint queue, uint next_frag_len) 6241{ 6242 struct ieee80211_hdr *h; 6243 struct d11txh *txh; 6244 u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; 6245 int len, phylen, rts_phylen; 6246 u16 mch, phyctl, xfts, mainrates; 6247 u16 seq = 0, mcl = 0, status = 0, frameid = 0; 6248 u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M }; 6249 u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M }; 6250 bool use_rts = false; 6251 bool use_cts = false; 6252 bool use_rifs = false; 6253 bool short_preamble[2] = { false, false }; 6254 u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE }; 6255 u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE }; 6256 u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; 6257 struct ieee80211_rts *rts = NULL; 6258 bool qos; 6259 uint ac; 6260 bool hwtkmic = false; 6261 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; 6262#define ANTCFG_NONE 0xFF 6263 u8 antcfg = ANTCFG_NONE; 6264 u8 fbantcfg = ANTCFG_NONE; 6265 uint phyctl1_stf = 0; 6266 u16 durid = 0; 6267 struct ieee80211_tx_rate *txrate[2]; 6268 int k; 6269 struct ieee80211_tx_info *tx_info; 6270 bool is_mcs; 6271 u16 mimo_txbw; 6272 u8 mimo_preamble_type; 6273 6274 /* locate 802.11 MAC header */ 6275 h = (struct ieee80211_hdr *)(p->data); 6276 qos = ieee80211_is_data_qos(h->frame_control); 6277 6278 /* compute length of frame in bytes for use in PLCP computations */ 6279 len = p->len; 6280 phylen = len + FCS_LEN; 6281 6282 /* Get tx_info */ 6283 tx_info = IEEE80211_SKB_CB(p); 6284 6285 /* add PLCP */ 6286 plcp = skb_push(p, D11_PHY_HDR_LEN); 6287 6288 /* add Broadcom tx descriptor header */ 6289 txh = (struct d11txh *) skb_push(p, D11_TXH_LEN); 6290 memset(txh, 0, D11_TXH_LEN); 6291 6292 /* setup frameid */ 6293 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 6294 /* non-AP STA should never use BCMC queue */ 6295 if (queue == TX_BCMC_FIFO) { 6296 brcms_err(wlc->hw->d11core, 6297 "wl%d: %s: ASSERT queue == TX_BCMC!\n", 6298 wlc->pub->unit, __func__); 6299 frameid = bcmc_fid_generate(wlc, NULL, txh); 6300 } else { 6301 /* Increment the counter for first fragment */ 6302 if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) 6303 scb->seqnum[p->priority]++; 6304 6305 /* extract fragment number from frame first */ 6306 seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK; 6307 seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT); 6308 h->seq_ctrl = cpu_to_le16(seq); 6309 6310 frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | 6311 (queue & TXFID_QUEUE_MASK); 6312 } 6313 } 6314 frameid |= queue & TXFID_QUEUE_MASK; 6315 6316 /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ 6317 if (ieee80211_is_beacon(h->frame_control)) 6318 mcl |= TXC_IGNOREPMQ; 6319 6320 txrate[0] = tx_info->control.rates; 6321 txrate[1] = txrate[0] + 1; 6322 6323 /* 6324 * if rate control algorithm didn't give us a fallback 6325 * rate, use the primary rate 6326 */ 6327 if (txrate[1]->idx < 0) 6328 txrate[1] = txrate[0]; 6329 6330 for (k = 0; k < hw->max_rates; k++) { 6331 is_mcs = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; 6332 if (!is_mcs) { 6333 if ((txrate[k]->idx >= 0) 6334 && (txrate[k]->idx < 6335 hw->wiphy->bands[tx_info->band]->n_bitrates)) { 6336 rspec[k] = 6337 hw->wiphy->bands[tx_info->band]-> 6338 bitrates[txrate[k]->idx].hw_value; 6339 short_preamble[k] = 6340 txrate[k]-> 6341 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? 6342 true : false; 6343 } else { 6344 rspec[k] = BRCM_RATE_1M; 6345 } 6346 } else { 6347 rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, 6348 NRATE_MCS_INUSE | txrate[k]->idx); 6349 } 6350 6351 /* 6352 * Currently only support same setting for primay and 6353 * fallback rates. Unify flags for each rate into a 6354 * single value for the frame 6355 */ 6356 use_rts |= 6357 txrate[k]-> 6358 flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false; 6359 use_cts |= 6360 txrate[k]-> 6361 flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false; 6362 6363 6364 /* 6365 * (1) RATE: 6366 * determine and validate primary rate 6367 * and fallback rates 6368 */ 6369 if (!rspec_active(rspec[k])) { 6370 rspec[k] = BRCM_RATE_1M; 6371 } else { 6372 if (!is_multicast_ether_addr(h->addr1)) { 6373 /* set tx antenna config */ 6374 brcms_c_antsel_antcfg_get(wlc->asi, false, 6375 false, 0, 0, &antcfg, &fbantcfg); 6376 } 6377 } 6378 } 6379 6380 phyctl1_stf = wlc->stf->ss_opmode; 6381 6382 if (wlc->pub->_n_enab & SUPPORT_11N) { 6383 for (k = 0; k < hw->max_rates; k++) { 6384 /* 6385 * apply siso/cdd to single stream mcs's or ofdm 6386 * if rspec is auto selected 6387 */ 6388 if (((is_mcs_rate(rspec[k]) && 6389 is_single_stream(rspec[k] & RSPEC_RATE_MASK)) || 6390 is_ofdm_rate(rspec[k])) 6391 && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY) 6392 || !(rspec[k] & RSPEC_OVERRIDE))) { 6393 rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK); 6394 6395 /* For SISO MCS use STBC if possible */ 6396 if (is_mcs_rate(rspec[k]) 6397 && BRCMS_STF_SS_STBC_TX(wlc, scb)) { 6398 u8 stc; 6399 6400 /* Nss for single stream is always 1 */ 6401 stc = 1; 6402 rspec[k] |= (PHY_TXC1_MODE_STBC << 6403 RSPEC_STF_SHIFT) | 6404 (stc << RSPEC_STC_SHIFT); 6405 } else 6406 rspec[k] |= 6407 (phyctl1_stf << RSPEC_STF_SHIFT); 6408 } 6409 6410 /* 6411 * Is the phy configured to use 40MHZ frames? If 6412 * so then pick the desired txbw 6413 */ 6414 if (brcms_chspec_bw(wlc->chanspec) == BRCMS_40_MHZ) { 6415 /* default txbw is 20in40 SB */ 6416 mimo_ctlchbw = mimo_txbw = 6417 CHSPEC_SB_UPPER(wlc_phy_chanspec_get( 6418 wlc->band->pi)) 6419 ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; 6420 6421 if (is_mcs_rate(rspec[k])) { 6422 /* mcs 32 must be 40b/w DUP */ 6423 if ((rspec[k] & RSPEC_RATE_MASK) 6424 == 32) { 6425 mimo_txbw = 6426 PHY_TXC1_BW_40MHZ_DUP; 6427 /* use override */ 6428 } else if (wlc->mimo_40txbw != AUTO) 6429 mimo_txbw = wlc->mimo_40txbw; 6430 /* else check if dst is using 40 Mhz */ 6431 else if (scb->flags & SCB_IS40) 6432 mimo_txbw = PHY_TXC1_BW_40MHZ; 6433 } else if (is_ofdm_rate(rspec[k])) { 6434 if (wlc->ofdm_40txbw != AUTO) 6435 mimo_txbw = wlc->ofdm_40txbw; 6436 } else if (wlc->cck_40txbw != AUTO) { 6437 mimo_txbw = wlc->cck_40txbw; 6438 } 6439 } else { 6440 /* 6441 * mcs32 is 40 b/w only. 6442 * This is possible for probe packets on 6443 * a STA during SCAN 6444 */ 6445 if ((rspec[k] & RSPEC_RATE_MASK) == 32) 6446 /* mcs 0 */ 6447 rspec[k] = RSPEC_MIMORATE; 6448 6449 mimo_txbw = PHY_TXC1_BW_20MHZ; 6450 } 6451 6452 /* Set channel width */ 6453 rspec[k] &= ~RSPEC_BW_MASK; 6454 if ((k == 0) || ((k > 0) && is_mcs_rate(rspec[k]))) 6455 rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT); 6456 else 6457 rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); 6458 6459 /* Disable short GI, not supported yet */ 6460 rspec[k] &= ~RSPEC_SHORT_GI; 6461 6462 mimo_preamble_type = BRCMS_MM_PREAMBLE; 6463 if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) 6464 mimo_preamble_type = BRCMS_GF_PREAMBLE; 6465 6466 if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) 6467 && (!is_mcs_rate(rspec[k]))) { 6468 brcms_warn(wlc->hw->d11core, 6469 "wl%d: %s: IEEE80211_TX_RC_MCS != is_mcs_rate(rspec)\n", 6470 wlc->pub->unit, __func__); 6471 } 6472 6473 if (is_mcs_rate(rspec[k])) { 6474 preamble_type[k] = mimo_preamble_type; 6475 6476 /* 6477 * if SGI is selected, then forced mm 6478 * for single stream 6479 */ 6480 if ((rspec[k] & RSPEC_SHORT_GI) 6481 && is_single_stream(rspec[k] & 6482 RSPEC_RATE_MASK)) 6483 preamble_type[k] = BRCMS_MM_PREAMBLE; 6484 } 6485 6486 /* should be better conditionalized */ 6487 if (!is_mcs_rate(rspec[0]) 6488 && (tx_info->control.rates[0]. 6489 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) 6490 preamble_type[k] = BRCMS_SHORT_PREAMBLE; 6491 } 6492 } else { 6493 for (k = 0; k < hw->max_rates; k++) { 6494 /* Set ctrlchbw as 20Mhz */ 6495 rspec[k] &= ~RSPEC_BW_MASK; 6496 rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); 6497 6498 /* for nphy, stf of ofdm frames must follow policies */ 6499 if (BRCMS_ISNPHY(wlc->band) && is_ofdm_rate(rspec[k])) { 6500 rspec[k] &= ~RSPEC_STF_MASK; 6501 rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; 6502 } 6503 } 6504 } 6505 6506 /* Reset these for use with AMPDU's */ 6507 txrate[0]->count = 0; 6508 txrate[1]->count = 0; 6509 6510 /* (2) PROTECTION, may change rspec */ 6511 if ((ieee80211_is_data(h->frame_control) || 6512 ieee80211_is_mgmt(h->frame_control)) && 6513 (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1)) 6514 use_rts = true; 6515 6516 /* (3) PLCP: determine PLCP header and MAC duration, 6517 * fill struct d11txh */ 6518 brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp); 6519 brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); 6520 memcpy(&txh->FragPLCPFallback, 6521 plcp_fallback, sizeof(txh->FragPLCPFallback)); 6522 6523 /* Length field now put in CCK FBR CRC field */ 6524 if (is_cck_rate(rspec[1])) { 6525 txh->FragPLCPFallback[4] = phylen & 0xff; 6526 txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8; 6527 } 6528 6529 /* MIMO-RATE: need validation ?? */ 6530 mainrates = is_ofdm_rate(rspec[0]) ? 6531 D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) : 6532 plcp[0]; 6533 6534 /* DUR field for main rate */ 6535 if (!ieee80211_is_pspoll(h->frame_control) && 6536 !is_multicast_ether_addr(h->addr1) && !use_rifs) { 6537 durid = 6538 brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0], 6539 next_frag_len); 6540 h->duration_id = cpu_to_le16(durid); 6541 } else if (use_rifs) { 6542 /* NAV protect to end of next max packet size */ 6543 durid = 6544 (u16) brcms_c_calc_frame_time(wlc, rspec[0], 6545 preamble_type[0], 6546 DOT11_MAX_FRAG_LEN); 6547 durid += RIFS_11N_TIME; 6548 h->duration_id = cpu_to_le16(durid); 6549 } 6550 6551 /* DUR field for fallback rate */ 6552 if (ieee80211_is_pspoll(h->frame_control)) 6553 txh->FragDurFallback = h->duration_id; 6554 else if (is_multicast_ether_addr(h->addr1) || use_rifs) 6555 txh->FragDurFallback = 0; 6556 else { 6557 durid = brcms_c_compute_frame_dur(wlc, rspec[1], 6558 preamble_type[1], next_frag_len); 6559 txh->FragDurFallback = cpu_to_le16(durid); 6560 } 6561 6562 /* (4) MAC-HDR: MacTxControlLow */ 6563 if (frag == 0) 6564 mcl |= TXC_STARTMSDU; 6565 6566 if (!is_multicast_ether_addr(h->addr1)) 6567 mcl |= TXC_IMMEDACK; 6568 6569 if (wlc->band->bandtype == BRCM_BAND_5G) 6570 mcl |= TXC_FREQBAND_5G; 6571 6572 if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc->band->pi))) 6573 mcl |= TXC_BW_40; 6574 6575 /* set AMIC bit if using hardware TKIP MIC */ 6576 if (hwtkmic) 6577 mcl |= TXC_AMIC; 6578 6579 txh->MacTxControlLow = cpu_to_le16(mcl); 6580 6581 /* MacTxControlHigh */ 6582 mch = 0; 6583 6584 /* Set fallback rate preamble type */ 6585 if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) || 6586 (preamble_type[1] == BRCMS_GF_PREAMBLE)) { 6587 if (rspec2rate(rspec[1]) != BRCM_RATE_1M) 6588 mch |= TXC_PREAMBLE_DATA_FB_SHORT; 6589 } 6590 6591 /* MacFrameControl */ 6592 memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16)); 6593 txh->TxFesTimeNormal = cpu_to_le16(0); 6594 6595 txh->TxFesTimeFallback = cpu_to_le16(0); 6596 6597 /* TxFrameRA */ 6598 memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN); 6599 6600 /* TxFrameID */ 6601 txh->TxFrameID = cpu_to_le16(frameid); 6602 6603 /* 6604 * TxStatus, Note the case of recreating the first frag of a suppressed 6605 * frame then we may need to reset the retry cnt's via the status reg 6606 */ 6607 txh->TxStatus = cpu_to_le16(status); 6608 6609 /* 6610 * extra fields for ucode AMPDU aggregation, the new fields are added to 6611 * the END of previous structure so that it's compatible in driver. 6612 */ 6613 txh->MaxNMpdus = cpu_to_le16(0); 6614 txh->MaxABytes_MRT = cpu_to_le16(0); 6615 txh->MaxABytes_FBR = cpu_to_le16(0); 6616 txh->MinMBytes = cpu_to_le16(0); 6617 6618 /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, 6619 * furnish struct d11txh */ 6620 /* RTS PLCP header and RTS frame */ 6621 if (use_rts || use_cts) { 6622 if (use_rts && use_cts) 6623 use_cts = false; 6624 6625 for (k = 0; k < 2; k++) { 6626 rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k], 6627 false, 6628 mimo_ctlchbw); 6629 } 6630 6631 if (!is_ofdm_rate(rts_rspec[0]) && 6632 !((rspec2rate(rts_rspec[0]) == BRCM_RATE_1M) || 6633 (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) { 6634 rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE; 6635 mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; 6636 } 6637 6638 if (!is_ofdm_rate(rts_rspec[1]) && 6639 !((rspec2rate(rts_rspec[1]) == BRCM_RATE_1M) || 6640 (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) { 6641 rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE; 6642 mch |= TXC_PREAMBLE_RTS_FB_SHORT; 6643 } 6644 6645 /* RTS/CTS additions to MacTxControlLow */ 6646 if (use_cts) { 6647 txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS); 6648 } else { 6649 txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS); 6650 txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME); 6651 } 6652 6653 /* RTS PLCP header */ 6654 rts_plcp = txh->RTSPhyHeader; 6655 if (use_cts) 6656 rts_phylen = DOT11_CTS_LEN + FCS_LEN; 6657 else 6658 rts_phylen = DOT11_RTS_LEN + FCS_LEN; 6659 6660 brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); 6661 6662 /* fallback rate version of RTS PLCP header */ 6663 brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen, 6664 rts_plcp_fallback); 6665 memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback, 6666 sizeof(txh->RTSPLCPFallback)); 6667 6668 /* RTS frame fields... */ 6669 rts = (struct ieee80211_rts *)&txh->rts_frame; 6670 6671 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], 6672 rspec[0], rts_preamble_type[0], 6673 preamble_type[0], phylen, false); 6674 rts->duration = cpu_to_le16(durid); 6675 /* fallback rate version of RTS DUR field */ 6676 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, 6677 rts_rspec[1], rspec[1], 6678 rts_preamble_type[1], 6679 preamble_type[1], phylen, false); 6680 txh->RTSDurFallback = cpu_to_le16(durid); 6681 6682 if (use_cts) { 6683 rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | 6684 IEEE80211_STYPE_CTS); 6685 6686 memcpy(&rts->ra, &h->addr2, ETH_ALEN); 6687 } else { 6688 rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | 6689 IEEE80211_STYPE_RTS); 6690 6691 memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN); 6692 } 6693 6694 /* mainrate 6695 * low 8 bits: main frag rate/mcs, 6696 * high 8 bits: rts/cts rate/mcs 6697 */ 6698 mainrates |= (is_ofdm_rate(rts_rspec[0]) ? 6699 D11A_PHY_HDR_GRATE( 6700 (struct ofdm_phy_hdr *) rts_plcp) : 6701 rts_plcp[0]) << 8; 6702 } else { 6703 memset(txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); 6704 memset(&txh->rts_frame, 0, sizeof(struct ieee80211_rts)); 6705 memset(txh->RTSPLCPFallback, 0, sizeof(txh->RTSPLCPFallback)); 6706 txh->RTSDurFallback = 0; 6707 } 6708 6709#ifdef SUPPORT_40MHZ 6710 /* add null delimiter count */ 6711 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && is_mcs_rate(rspec)) 6712 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 6713 brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); 6714 6715#endif 6716 6717 /* 6718 * Now that RTS/RTS FB preamble types are updated, write 6719 * the final value 6720 */ 6721 txh->MacTxControlHigh = cpu_to_le16(mch); 6722 6723 /* 6724 * MainRates (both the rts and frag plcp rates have 6725 * been calculated now) 6726 */ 6727 txh->MainRates = cpu_to_le16(mainrates); 6728 6729 /* XtraFrameTypes */ 6730 xfts = frametype(rspec[1], wlc->mimoft); 6731 xfts |= (frametype(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); 6732 xfts |= (frametype(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); 6733 xfts |= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc->band->pi)) << 6734 XFTS_CHANNEL_SHIFT; 6735 txh->XtraFrameTypes = cpu_to_le16(xfts); 6736 6737 /* PhyTxControlWord */ 6738 phyctl = frametype(rspec[0], wlc->mimoft); 6739 if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) || 6740 (preamble_type[0] == BRCMS_GF_PREAMBLE)) { 6741 if (rspec2rate(rspec[0]) != BRCM_RATE_1M) 6742 phyctl |= PHY_TXC_SHORT_HDR; 6743 } 6744 6745 /* phytxant is properly bit shifted */ 6746 phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); 6747 txh->PhyTxControlWord = cpu_to_le16(phyctl); 6748 6749 /* PhyTxControlWord_1 */ 6750 if (BRCMS_PHY_11N_CAP(wlc->band)) { 6751 u16 phyctl1 = 0; 6752 6753 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]); 6754 txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1); 6755 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]); 6756 txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1); 6757 6758 if (use_rts || use_cts) { 6759 phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]); 6760 txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1); 6761 phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]); 6762 txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1); 6763 } 6764 6765 /* 6766 * For mcs frames, if mixedmode(overloaded with long preamble) 6767 * is going to be set, fill in non-zero MModeLen and/or 6768 * MModeFbrLen it will be unnecessary if they are separated 6769 */ 6770 if (is_mcs_rate(rspec[0]) && 6771 (preamble_type[0] == BRCMS_MM_PREAMBLE)) { 6772 u16 mmodelen = 6773 brcms_c_calc_lsig_len(wlc, rspec[0], phylen); 6774 txh->MModeLen = cpu_to_le16(mmodelen); 6775 } 6776 6777 if (is_mcs_rate(rspec[1]) && 6778 (preamble_type[1] == BRCMS_MM_PREAMBLE)) { 6779 u16 mmodefbrlen = 6780 brcms_c_calc_lsig_len(wlc, rspec[1], phylen); 6781 txh->MModeFbrLen = cpu_to_le16(mmodefbrlen); 6782 } 6783 } 6784 6785 ac = skb_get_queue_mapping(p); 6786 if ((scb->flags & SCB_WMECAP) && qos && wlc->edcf_txop[ac]) { 6787 uint frag_dur, dur, dur_fallback; 6788 6789 /* WME: Update TXOP threshold */ 6790 if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) { 6791 frag_dur = 6792 brcms_c_calc_frame_time(wlc, rspec[0], 6793 preamble_type[0], phylen); 6794 6795 if (rts) { 6796 /* 1 RTS or CTS-to-self frame */ 6797 dur = 6798 brcms_c_calc_cts_time(wlc, rts_rspec[0], 6799 rts_preamble_type[0]); 6800 dur_fallback = 6801 brcms_c_calc_cts_time(wlc, rts_rspec[1], 6802 rts_preamble_type[1]); 6803 /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ 6804 dur += le16_to_cpu(rts->duration); 6805 dur_fallback += 6806 le16_to_cpu(txh->RTSDurFallback); 6807 } else if (use_rifs) { 6808 dur = frag_dur; 6809 dur_fallback = 0; 6810 } else { 6811 /* frame + SIFS + ACK */ 6812 dur = frag_dur; 6813 dur += 6814 brcms_c_compute_frame_dur(wlc, rspec[0], 6815 preamble_type[0], 0); 6816 6817 dur_fallback = 6818 brcms_c_calc_frame_time(wlc, rspec[1], 6819 preamble_type[1], 6820 phylen); 6821 dur_fallback += 6822 brcms_c_compute_frame_dur(wlc, rspec[1], 6823 preamble_type[1], 0); 6824 } 6825 /* NEED to set TxFesTimeNormal (hard) */ 6826 txh->TxFesTimeNormal = cpu_to_le16((u16) dur); 6827 /* 6828 * NEED to set fallback rate version of 6829 * TxFesTimeNormal (hard) 6830 */ 6831 txh->TxFesTimeFallback = 6832 cpu_to_le16((u16) dur_fallback); 6833 6834 /* 6835 * update txop byte threshold (txop minus intraframe 6836 * overhead) 6837 */ 6838 if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { 6839 uint newfragthresh; 6840 6841 newfragthresh = 6842 brcms_c_calc_frame_len(wlc, 6843 rspec[0], preamble_type[0], 6844 (wlc->edcf_txop[ac] - 6845 (dur - frag_dur))); 6846 /* range bound the fragthreshold */ 6847 if (newfragthresh < DOT11_MIN_FRAG_LEN) 6848 newfragthresh = 6849 DOT11_MIN_FRAG_LEN; 6850 else if (newfragthresh > 6851 wlc->usr_fragthresh) 6852 newfragthresh = 6853 wlc->usr_fragthresh; 6854 /* update the fragthresh and do txc update */ 6855 if (wlc->fragthresh[queue] != 6856 (u16) newfragthresh) 6857 wlc->fragthresh[queue] = 6858 (u16) newfragthresh; 6859 } else { 6860 brcms_warn(wlc->hw->d11core, 6861 "wl%d: %s txop invalid for rate %d\n", 6862 wlc->pub->unit, fifo_names[queue], 6863 rspec2rate(rspec[0])); 6864 } 6865 6866 if (dur > wlc->edcf_txop[ac]) 6867 brcms_warn(wlc->hw->d11core, 6868 "wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", 6869 wlc->pub->unit, __func__, 6870 fifo_names[queue], 6871 phylen, wlc->fragthresh[queue], 6872 dur, wlc->edcf_txop[ac]); 6873 } 6874 } 6875 6876 return 0; 6877} 6878 6879static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) 6880{ 6881 struct dma_pub *dma; 6882 int fifo, ret = -ENOSPC; 6883 struct d11txh *txh; 6884 u16 frameid = INVALIDFID; 6885 6886 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb)); 6887 dma = wlc->hw->di[fifo]; 6888 txh = (struct d11txh *)(skb->data); 6889 6890 if (dma->txavail == 0) { 6891 /* 6892 * We sometimes get a frame from mac80211 after stopping 6893 * the queues. This only ever seems to be a single frame 6894 * and is seems likely to be a race. TX_HEADROOM should 6895 * ensure that we have enough space to handle these stray 6896 * packets, so warn if there isn't. If we're out of space 6897 * in the tx ring and the tx queue isn't stopped then 6898 * we've really got a bug; warn loudly if that happens. 6899 */ 6900 brcms_warn(wlc->hw->d11core, 6901 "Received frame for tx with no space in DMA ring\n"); 6902 WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw, 6903 skb_get_queue_mapping(skb))); 6904 return -ENOSPC; 6905 } 6906 6907 /* When a BC/MC frame is being committed to the BCMC fifo 6908 * via DMA (NOT PIO), update ucode or BSS info as appropriate. 6909 */ 6910 if (fifo == TX_BCMC_FIFO) 6911 frameid = le16_to_cpu(txh->TxFrameID); 6912 6913 /* Commit BCMC sequence number in the SHM frame ID location */ 6914 if (frameid != INVALIDFID) { 6915 /* 6916 * To inform the ucode of the last mcast frame posted 6917 * so that it can clear moredata bit 6918 */ 6919 brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); 6920 } 6921 6922 ret = brcms_c_txfifo(wlc, fifo, skb); 6923 /* 6924 * The only reason for brcms_c_txfifo to fail is because 6925 * there weren't any DMA descriptors, but we've already 6926 * checked for that. So if it does fail yell loudly. 6927 */ 6928 WARN_ON_ONCE(ret); 6929 6930 return ret; 6931} 6932 6933bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, 6934 struct ieee80211_hw *hw) 6935{ 6936 uint fifo; 6937 struct scb *scb = &wlc->pri_scb; 6938 6939 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); 6940 brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0); 6941 if (!brcms_c_tx(wlc, sdu)) 6942 return true; 6943 6944 /* packet discarded */ 6945 dev_kfree_skb_any(sdu); 6946 return false; 6947} 6948 6949int 6950brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p) 6951{ 6952 struct dma_pub *dma = wlc->hw->di[fifo]; 6953 int ret; 6954 u16 queue; 6955 6956 ret = dma_txfast(wlc, dma, p); 6957 if (ret < 0) 6958 wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); 6959 6960 /* 6961 * Stop queue if DMA ring is full. Reserve some free descriptors, 6962 * as we sometimes receive a frame from mac80211 after the queues 6963 * are stopped. 6964 */ 6965 queue = skb_get_queue_mapping(p); 6966 if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO && 6967 !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue)) 6968 ieee80211_stop_queue(wlc->pub->ieee_hw, queue); 6969 6970 return ret; 6971} 6972 6973u32 6974brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, 6975 bool use_rspec, u16 mimo_ctlchbw) 6976{ 6977 u32 rts_rspec = 0; 6978 6979 if (use_rspec) 6980 /* use frame rate as rts rate */ 6981 rts_rspec = rspec; 6982 else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec)) 6983 /* Use 11Mbps as the g protection RTS target rate and fallback. 6984 * Use the brcms_basic_rate() lookup to find the best basic rate 6985 * under the target in case 11 Mbps is not Basic. 6986 * 6 and 9 Mbps are not usually selected by rate selection, but 6987 * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11 6988 * is more robust. 6989 */ 6990 rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M); 6991 else 6992 /* calculate RTS rate and fallback rate based on the frame rate 6993 * RTS must be sent at a basic rate since it is a 6994 * control frame, sec 9.6 of 802.11 spec 6995 */ 6996 rts_rspec = brcms_basic_rate(wlc, rspec); 6997 6998 if (BRCMS_PHY_11N_CAP(wlc->band)) { 6999 /* set rts txbw to correct side band */ 7000 rts_rspec &= ~RSPEC_BW_MASK; 7001 7002 /* 7003 * if rspec/rspec_fallback is 40MHz, then send RTS on both 7004 * 20MHz channel (DUP), otherwise send RTS on control channel 7005 */ 7006 if (rspec_is40mhz(rspec) && !is_cck_rate(rts_rspec)) 7007 rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); 7008 else 7009 rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT); 7010 7011 /* pick siso/cdd as default for ofdm */ 7012 if (is_ofdm_rate(rts_rspec)) { 7013 rts_rspec &= ~RSPEC_STF_MASK; 7014 rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); 7015 } 7016 } 7017 return rts_rspec; 7018} 7019 7020/* Update beacon listen interval in shared memory */ 7021static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) 7022{ 7023 /* wake up every DTIM is the default */ 7024 if (wlc->bcn_li_dtim == 1) 7025 brcms_b_write_shm(wlc->hw, M_BCN_LI, 0); 7026 else 7027 brcms_b_write_shm(wlc->hw, M_BCN_LI, 7028 (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); 7029} 7030 7031static void 7032brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr, 7033 u32 *tsf_h_ptr) 7034{ 7035 struct bcma_device *core = wlc_hw->d11core; 7036 7037 /* read the tsf timer low, then high to get an atomic read */ 7038 *tsf_l_ptr = bcma_read32(core, D11REGOFFS(tsf_timerlow)); 7039 *tsf_h_ptr = bcma_read32(core, D11REGOFFS(tsf_timerhigh)); 7040} 7041 7042/* 7043 * recover 64bit TSF value from the 16bit TSF value in the rx header 7044 * given the assumption that the TSF passed in header is within 65ms 7045 * of the current tsf. 7046 * 7047 * 6 5 4 4 3 2 1 7048 * 3.......6.......8.......0.......2.......4.......6.......8......0 7049 * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->| 7050 * 7051 * The RxTSFTime are the lowest 16 bits and provided by the ucode. The 7052 * tsf_l is filled in by brcms_b_recv, which is done earlier in the 7053 * receive call sequence after rx interrupt. Only the higher 16 bits 7054 * are used. Finally, the tsf_h is read from the tsf register. 7055 */ 7056static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc, 7057 struct d11rxhdr *rxh) 7058{ 7059 u32 tsf_h, tsf_l; 7060 u16 rx_tsf_0_15, rx_tsf_16_31; 7061 7062 brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h); 7063 7064 rx_tsf_16_31 = (u16)(tsf_l >> 16); 7065 rx_tsf_0_15 = rxh->RxTSFTime; 7066 7067 /* 7068 * a greater tsf time indicates the low 16 bits of 7069 * tsf_l wrapped, so decrement the high 16 bits. 7070 */ 7071 if ((u16)tsf_l < rx_tsf_0_15) { 7072 rx_tsf_16_31 -= 1; 7073 if (rx_tsf_16_31 == 0xffff) 7074 tsf_h -= 1; 7075 } 7076 7077 return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15); 7078} 7079 7080static void 7081prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, 7082 struct sk_buff *p, 7083 struct ieee80211_rx_status *rx_status) 7084{ 7085 int preamble; 7086 int channel; 7087 u32 rspec; 7088 unsigned char *plcp; 7089 7090 /* fill in TSF and flag its presence */ 7091 rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh); 7092 rx_status->flag |= RX_FLAG_MACTIME_START; 7093 7094 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); 7095 7096 rx_status->band = 7097 channel > 14 ? IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; 7098 rx_status->freq = 7099 ieee80211_channel_to_frequency(channel, rx_status->band); 7100 7101 rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh); 7102 7103 /* noise */ 7104 /* qual */ 7105 rx_status->antenna = 7106 (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; 7107 7108 plcp = p->data; 7109 7110 rspec = brcms_c_compute_rspec(rxh, plcp); 7111 if (is_mcs_rate(rspec)) { 7112 rx_status->rate_idx = rspec & RSPEC_RATE_MASK; 7113 rx_status->flag |= RX_FLAG_HT; 7114 if (rspec_is40mhz(rspec)) 7115 rx_status->flag |= RX_FLAG_40MHZ; 7116 } else { 7117 switch (rspec2rate(rspec)) { 7118 case BRCM_RATE_1M: 7119 rx_status->rate_idx = 0; 7120 break; 7121 case BRCM_RATE_2M: 7122 rx_status->rate_idx = 1; 7123 break; 7124 case BRCM_RATE_5M5: 7125 rx_status->rate_idx = 2; 7126 break; 7127 case BRCM_RATE_11M: 7128 rx_status->rate_idx = 3; 7129 break; 7130 case BRCM_RATE_6M: 7131 rx_status->rate_idx = 4; 7132 break; 7133 case BRCM_RATE_9M: 7134 rx_status->rate_idx = 5; 7135 break; 7136 case BRCM_RATE_12M: 7137 rx_status->rate_idx = 6; 7138 break; 7139 case BRCM_RATE_18M: 7140 rx_status->rate_idx = 7; 7141 break; 7142 case BRCM_RATE_24M: 7143 rx_status->rate_idx = 8; 7144 break; 7145 case BRCM_RATE_36M: 7146 rx_status->rate_idx = 9; 7147 break; 7148 case BRCM_RATE_48M: 7149 rx_status->rate_idx = 10; 7150 break; 7151 case BRCM_RATE_54M: 7152 rx_status->rate_idx = 11; 7153 break; 7154 default: 7155 brcms_err(wlc->hw->d11core, 7156 "%s: Unknown rate\n", __func__); 7157 } 7158 7159 /* 7160 * For 5GHz, we should decrease the index as it is 7161 * a subset of the 2.4G rates. See bitrates field 7162 * of brcms_band_5GHz_nphy (in mac80211_if.c). 7163 */ 7164 if (rx_status->band == IEEE80211_BAND_5GHZ) 7165 rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET; 7166 7167 /* Determine short preamble and rate_idx */ 7168 preamble = 0; 7169 if (is_cck_rate(rspec)) { 7170 if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) 7171 rx_status->flag |= RX_FLAG_SHORTPRE; 7172 } else if (is_ofdm_rate(rspec)) { 7173 rx_status->flag |= RX_FLAG_SHORTPRE; 7174 } else { 7175 brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n", 7176 __func__); 7177 } 7178 } 7179 7180 if (plcp3_issgi(plcp[3])) 7181 rx_status->flag |= RX_FLAG_SHORT_GI; 7182 7183 if (rxh->RxStatus1 & RXS_DECERR) { 7184 rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; 7185 brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_PLCP_CRC\n", 7186 __func__); 7187 } 7188 if (rxh->RxStatus1 & RXS_FCSERR) { 7189 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 7190 brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_FCS_CRC\n", 7191 __func__); 7192 } 7193} 7194 7195static void 7196brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, 7197 struct sk_buff *p) 7198{ 7199 int len_mpdu; 7200 struct ieee80211_rx_status rx_status; 7201 struct ieee80211_hdr *hdr; 7202 7203 memset(&rx_status, 0, sizeof(rx_status)); 7204 prep_mac80211_status(wlc, rxh, p, &rx_status); 7205 7206 /* mac header+body length, exclude CRC and plcp header */ 7207 len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; 7208 skb_pull(p, D11_PHY_HDR_LEN); 7209 __skb_trim(p, len_mpdu); 7210 7211 /* unmute transmit */ 7212 if (wlc->hw->suspended_fifos) { 7213 hdr = (struct ieee80211_hdr *)p->data; 7214 if (ieee80211_is_beacon(hdr->frame_control)) 7215 brcms_b_mute(wlc->hw, false); 7216 } 7217 7218 memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); 7219 ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); 7220} 7221 7222/* calculate frame duration for Mixed-mode L-SIG spoofing, return 7223 * number of bytes goes in the length field 7224 * 7225 * Formula given by HT PHY Spec v 1.13 7226 * len = 3(nsyms + nstream + 3) - 3 7227 */ 7228u16 7229brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, 7230 uint mac_len) 7231{ 7232 uint nsyms, len = 0, kNdps; 7233 7234 if (is_mcs_rate(ratespec)) { 7235 uint mcs = ratespec & RSPEC_RATE_MASK; 7236 int tot_streams = (mcs_2_txstreams(mcs) + 1) + 7237 rspec_stc(ratespec); 7238 7239 /* 7240 * the payload duration calculation matches that 7241 * of regular ofdm 7242 */ 7243 /* 1000Ndbps = kbps * 4 */ 7244 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec), 7245 rspec_issgi(ratespec)) * 4; 7246 7247 if (rspec_stc(ratespec) == 0) 7248 nsyms = 7249 CEIL((APHY_SERVICE_NBITS + 8 * mac_len + 7250 APHY_TAIL_NBITS) * 1000, kNdps); 7251 else 7252 /* STBC needs to have even number of symbols */ 7253 nsyms = 7254 2 * 7255 CEIL((APHY_SERVICE_NBITS + 8 * mac_len + 7256 APHY_TAIL_NBITS) * 1000, 2 * kNdps); 7257 7258 /* (+3) account for HT-SIG(2) and HT-STF(1) */ 7259 nsyms += (tot_streams + 3); 7260 /* 7261 * 3 bytes/symbol @ legacy 6Mbps rate 7262 * (-3) excluding service bits and tail bits 7263 */ 7264 len = (3 * nsyms) - 3; 7265 } 7266 7267 return (u16) len; 7268} 7269 7270static void 7271brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len) 7272{ 7273 const struct brcms_c_rateset *rs_dflt; 7274 struct brcms_c_rateset rs; 7275 u8 rate; 7276 u16 entry_ptr; 7277 u8 plcp[D11_PHY_HDR_LEN]; 7278 u16 dur, sifs; 7279 uint i; 7280 7281 sifs = get_sifs(wlc->band); 7282 7283 rs_dflt = brcms_c_rateset_get_hwrs(wlc); 7284 7285 brcms_c_rateset_copy(rs_dflt, &rs); 7286 brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams); 7287 7288 /* 7289 * walk the phy rate table and update MAC core SHM 7290 * basic rate table entries 7291 */ 7292 for (i = 0; i < rs.count; i++) { 7293 rate = rs.rates[i] & BRCMS_RATE_MASK; 7294 7295 entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate); 7296 7297 /* Calculate the Probe Response PLCP for the given rate */ 7298 brcms_c_compute_plcp(wlc, rate, frame_len, plcp); 7299 7300 /* 7301 * Calculate the duration of the Probe Response 7302 * frame plus SIFS for the MAC 7303 */ 7304 dur = (u16) brcms_c_calc_frame_time(wlc, rate, 7305 BRCMS_LONG_PREAMBLE, frame_len); 7306 dur += sifs; 7307 7308 /* Update the SHM Rate Table entry Probe Response values */ 7309 brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS, 7310 (u16) (plcp[0] + (plcp[1] << 8))); 7311 brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2, 7312 (u16) (plcp[2] + (plcp[3] << 8))); 7313 brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur); 7314 } 7315} 7316 7317/* Max buffering needed for beacon template/prb resp template is 142 bytes. 7318 * 7319 * PLCP header is 6 bytes. 7320 * 802.11 A3 header is 24 bytes. 7321 * Max beacon frame body template length is 112 bytes. 7322 * Max probe resp frame body template length is 110 bytes. 7323 * 7324 * *len on input contains the max length of the packet available. 7325 * 7326 * The *len value is set to the number of bytes in buf used, and starts 7327 * with the PLCP and included up to, but not including, the 4 byte FCS. 7328 */ 7329static void 7330brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type, 7331 u32 bcn_rspec, 7332 struct brcms_bss_cfg *cfg, u16 *buf, int *len) 7333{ 7334 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; 7335 struct cck_phy_hdr *plcp; 7336 struct ieee80211_mgmt *h; 7337 int hdr_len, body_len; 7338 7339 hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; 7340 7341 /* calc buffer size provided for frame body */ 7342 body_len = *len - hdr_len; 7343 /* return actual size */ 7344 *len = hdr_len + body_len; 7345 7346 /* format PHY and MAC headers */ 7347 memset(buf, 0, hdr_len); 7348 7349 plcp = (struct cck_phy_hdr *) buf; 7350 7351 /* 7352 * PLCP for Probe Response frames are filled in from 7353 * core's rate table 7354 */ 7355 if (type == IEEE80211_STYPE_BEACON) 7356 /* fill in PLCP */ 7357 brcms_c_compute_plcp(wlc, bcn_rspec, 7358 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), 7359 (u8 *) plcp); 7360 7361 /* "Regular" and 16 MBSS but not for 4 MBSS */ 7362 /* Update the phytxctl for the beacon based on the rspec */ 7363 brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec); 7364 7365 h = (struct ieee80211_mgmt *)&plcp[1]; 7366 7367 /* fill in 802.11 header */ 7368 h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type); 7369 7370 /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ 7371 /* A1 filled in by MAC for prb resp, broadcast for bcn */ 7372 if (type == IEEE80211_STYPE_BEACON) 7373 memcpy(&h->da, ðer_bcast, ETH_ALEN); 7374 memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN); 7375 memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN); 7376 7377 /* SEQ filled in by MAC */ 7378} 7379 7380int brcms_c_get_header_len(void) 7381{ 7382 return TXOFF; 7383} 7384 7385static void brcms_c_beacon_write(struct brcms_c_info *wlc, 7386 struct sk_buff *beacon, u16 tim_offset, 7387 u16 dtim_period, bool bcn0, bool bcn1) 7388{ 7389 size_t len; 7390 struct ieee80211_tx_info *tx_info; 7391 struct brcms_hardware *wlc_hw = wlc->hw; 7392 struct ieee80211_hw *ieee_hw = brcms_c_pub(wlc)->ieee_hw; 7393 7394 /* Get tx_info */ 7395 tx_info = IEEE80211_SKB_CB(beacon); 7396 7397 len = min_t(size_t, beacon->len, BCN_TMPL_LEN); 7398 wlc->bcn_rspec = ieee80211_get_tx_rate(ieee_hw, tx_info)->hw_value; 7399 7400 brcms_c_compute_plcp(wlc, wlc->bcn_rspec, 7401 len + FCS_LEN - D11_PHY_HDR_LEN, beacon->data); 7402 7403 /* "Regular" and 16 MBSS but not for 4 MBSS */ 7404 /* Update the phytxctl for the beacon based on the rspec */ 7405 brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); 7406 7407 if (bcn0) { 7408 /* write the probe response into the template region */ 7409 brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, 7410 (len + 3) & ~3, beacon->data); 7411 7412 /* write beacon length to SCR */ 7413 brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); 7414 } 7415 if (bcn1) { 7416 /* write the probe response into the template region */ 7417 brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, 7418 (len + 3) & ~3, beacon->data); 7419 7420 /* write beacon length to SCR */ 7421 brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); 7422 } 7423 7424 if (tim_offset != 0) { 7425 brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON, 7426 tim_offset + D11B_PHY_HDR_LEN); 7427 brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, dtim_period); 7428 } else { 7429 brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON, 7430 len + D11B_PHY_HDR_LEN); 7431 brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, 0); 7432 } 7433} 7434 7435static void brcms_c_update_beacon_hw(struct brcms_c_info *wlc, 7436 struct sk_buff *beacon, u16 tim_offset, 7437 u16 dtim_period) 7438{ 7439 struct brcms_hardware *wlc_hw = wlc->hw; 7440 struct bcma_device *core = wlc_hw->d11core; 7441 7442 /* Hardware beaconing for this config */ 7443 u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; 7444 7445 /* Check if both templates are in use, if so sched. an interrupt 7446 * that will call back into this routine 7447 */ 7448 if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) 7449 /* clear any previous status */ 7450 bcma_write32(core, D11REGOFFS(macintstatus), MI_BCNTPL); 7451 7452 if (wlc->beacon_template_virgin) { 7453 wlc->beacon_template_virgin = false; 7454 brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true, 7455 true); 7456 /* mark beacon0 valid */ 7457 bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD); 7458 return; 7459 } 7460 7461 /* Check that after scheduling the interrupt both of the 7462 * templates are still busy. if not clear the int. & remask 7463 */ 7464 if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) { 7465 wlc->defmacintmask |= MI_BCNTPL; 7466 return; 7467 } 7468 7469 if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN0VLD)) { 7470 brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true, 7471 false); 7472 /* mark beacon0 valid */ 7473 bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD); 7474 return; 7475 } 7476 if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN1VLD)) { 7477 brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, 7478 false, true); 7479 /* mark beacon0 valid */ 7480 bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN1VLD); 7481 return; 7482 } 7483 return; 7484} 7485 7486/* 7487 * Update all beacons for the system. 7488 */ 7489void brcms_c_update_beacon(struct brcms_c_info *wlc) 7490{ 7491 struct brcms_bss_cfg *bsscfg = wlc->bsscfg; 7492 7493 if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP || 7494 bsscfg->type == BRCMS_TYPE_ADHOC)) { 7495 /* Clear the soft intmask */ 7496 wlc->defmacintmask &= ~MI_BCNTPL; 7497 if (!wlc->beacon) 7498 return; 7499 brcms_c_update_beacon_hw(wlc, wlc->beacon, 7500 wlc->beacon_tim_offset, 7501 wlc->beacon_dtim_period); 7502 } 7503} 7504 7505void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon, 7506 u16 tim_offset, u16 dtim_period) 7507{ 7508 if (!beacon) 7509 return; 7510 if (wlc->beacon) 7511 dev_kfree_skb_any(wlc->beacon); 7512 wlc->beacon = beacon; 7513 7514 /* add PLCP */ 7515 skb_push(wlc->beacon, D11_PHY_HDR_LEN); 7516 wlc->beacon_tim_offset = tim_offset; 7517 wlc->beacon_dtim_period = dtim_period; 7518 brcms_c_update_beacon(wlc); 7519} 7520 7521/* Write ssid into shared memory */ 7522static void 7523brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg) 7524{ 7525 u8 *ssidptr = cfg->SSID; 7526 u16 base = M_SSID; 7527 u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; 7528 7529 /* padding the ssid with zero and copy it into shm */ 7530 memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); 7531 memcpy(ssidbuf, ssidptr, cfg->SSID_len); 7532 7533 brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); 7534 brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len); 7535} 7536 7537static void 7538brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, 7539 struct brcms_bss_cfg *cfg, 7540 bool suspend) 7541{ 7542 u16 *prb_resp; 7543 int len = BCN_TMPL_LEN; 7544 7545 prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC); 7546 if (!prb_resp) 7547 return; 7548 7549 /* 7550 * write the probe response to hardware, or save in 7551 * the config structure 7552 */ 7553 7554 /* create the probe response template */ 7555 brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, 7556 cfg, prb_resp, &len); 7557 7558 if (suspend) 7559 brcms_c_suspend_mac_and_wait(wlc); 7560 7561 /* write the probe response into the template region */ 7562 brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE, 7563 (len + 3) & ~3, prb_resp); 7564 7565 /* write the length of the probe response frame (+PLCP/-FCS) */ 7566 brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len); 7567 7568 /* write the SSID and SSID length */ 7569 brcms_c_shm_ssid_upd(wlc, cfg); 7570 7571 /* 7572 * Write PLCP headers and durations for probe response frames 7573 * at all rates. Use the actual frame length covered by the 7574 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table() 7575 * by subtracting the PLCP len and adding the FCS. 7576 */ 7577 len += (-D11_PHY_HDR_LEN + FCS_LEN); 7578 brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len); 7579 7580 if (suspend) 7581 brcms_c_enable_mac(wlc); 7582 7583 kfree(prb_resp); 7584} 7585 7586void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) 7587{ 7588 struct brcms_bss_cfg *bsscfg = wlc->bsscfg; 7589 7590 /* update AP or IBSS probe responses */ 7591 if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP || 7592 bsscfg->type == BRCMS_TYPE_ADHOC)) 7593 brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); 7594} 7595 7596int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, 7597 uint *blocks) 7598{ 7599 if (fifo >= NFIFO) 7600 return -EINVAL; 7601 7602 *blocks = wlc_hw->xmtfifo_sz[fifo]; 7603 7604 return 0; 7605} 7606 7607void 7608brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset, 7609 const u8 *addr) 7610{ 7611 brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr); 7612 if (match_reg_offset == RCM_BSSID_OFFSET) 7613 memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN); 7614} 7615 7616/* 7617 * Flag 'scan in progress' to withhold dynamic phy calibration 7618 */ 7619void brcms_c_scan_start(struct brcms_c_info *wlc) 7620{ 7621 wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true); 7622} 7623 7624void brcms_c_scan_stop(struct brcms_c_info *wlc) 7625{ 7626 wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false); 7627} 7628 7629void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state) 7630{ 7631 wlc->pub->associated = state; 7632} 7633 7634/* 7635 * When a remote STA/AP is removed by Mac80211, or when it can no longer accept 7636 * AMPDU traffic, packets pending in hardware have to be invalidated so that 7637 * when later on hardware releases them, they can be handled appropriately. 7638 */ 7639void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, 7640 struct ieee80211_sta *sta, 7641 void (*dma_callback_fn)) 7642{ 7643 struct dma_pub *dmah; 7644 int i; 7645 for (i = 0; i < NFIFO; i++) { 7646 dmah = hw->di[i]; 7647 if (dmah != NULL) 7648 dma_walk_packets(dmah, dma_callback_fn, sta); 7649 } 7650} 7651 7652int brcms_c_get_curband(struct brcms_c_info *wlc) 7653{ 7654 return wlc->band->bandunit; 7655} 7656 7657bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc) 7658{ 7659 int i; 7660 7661 /* Kick DMA to send any pending AMPDU */ 7662 for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) 7663 if (wlc->hw->di[i]) 7664 dma_kick_tx(wlc->hw->di[i]); 7665 7666 return !brcms_txpktpendtot(wlc); 7667} 7668 7669void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) 7670{ 7671 wlc->bcn_li_bcn = interval; 7672 if (wlc->pub->up) 7673 brcms_c_bcn_li_upd(wlc); 7674} 7675 7676u64 brcms_c_tsf_get(struct brcms_c_info *wlc) 7677{ 7678 u32 tsf_h, tsf_l; 7679 u64 tsf; 7680 7681 brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h); 7682 7683 tsf = tsf_h; 7684 tsf <<= 32; 7685 tsf |= tsf_l; 7686 7687 return tsf; 7688} 7689 7690void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf) 7691{ 7692 u32 tsf_h, tsf_l; 7693 7694 brcms_c_time_lock(wlc); 7695 7696 tsf_l = tsf; 7697 tsf_h = (tsf >> 32); 7698 7699 /* read the tsf timer low, then high to get an atomic read */ 7700 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l); 7701 bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h); 7702 7703 brcms_c_time_unlock(wlc); 7704} 7705 7706int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr) 7707{ 7708 uint qdbm; 7709 7710 /* Remove override bit and clip to max qdbm value */ 7711 qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff); 7712 return wlc_phy_txpower_set(wlc->band->pi, qdbm, false); 7713} 7714 7715int brcms_c_get_tx_power(struct brcms_c_info *wlc) 7716{ 7717 uint qdbm; 7718 bool override; 7719 7720 wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); 7721 7722 /* Return qdbm units */ 7723 return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR); 7724} 7725 7726/* Process received frames */ 7727/* 7728 * Return true if more frames need to be processed. false otherwise. 7729 * Param 'bound' indicates max. # frames to process before break out. 7730 */ 7731static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) 7732{ 7733 struct d11rxhdr *rxh; 7734 struct ieee80211_hdr *h; 7735 uint len; 7736 bool is_amsdu; 7737 7738 /* frame starts with rxhdr */ 7739 rxh = (struct d11rxhdr *) (p->data); 7740 7741 /* strip off rxhdr */ 7742 skb_pull(p, BRCMS_HWRXOFF); 7743 7744 /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ 7745 if (rxh->RxStatus1 & RXS_PBPRES) { 7746 if (p->len < 2) { 7747 brcms_err(wlc->hw->d11core, 7748 "wl%d: recv: rcvd runt of len %d\n", 7749 wlc->pub->unit, p->len); 7750 goto toss; 7751 } 7752 skb_pull(p, 2); 7753 } 7754 7755 h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); 7756 len = p->len; 7757 7758 if (rxh->RxStatus1 & RXS_FCSERR) { 7759 if (!(wlc->filter_flags & FIF_FCSFAIL)) 7760 goto toss; 7761 } 7762 7763 /* check received pkt has at least frame control field */ 7764 if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) 7765 goto toss; 7766 7767 /* not supporting A-MSDU */ 7768 is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; 7769 if (is_amsdu) 7770 goto toss; 7771 7772 brcms_c_recvctl(wlc, rxh, p); 7773 return; 7774 7775 toss: 7776 brcmu_pkt_buf_free_skb(p); 7777} 7778 7779/* Process received frames */ 7780/* 7781 * Return true if more frames need to be processed. false otherwise. 7782 * Param 'bound' indicates max. # frames to process before break out. 7783 */ 7784static bool 7785brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) 7786{ 7787 struct sk_buff *p; 7788 struct sk_buff *next = NULL; 7789 struct sk_buff_head recv_frames; 7790 7791 uint n = 0; 7792 uint bound_limit = bound ? RXBND : -1; 7793 bool morepending = false; 7794 7795 skb_queue_head_init(&recv_frames); 7796 7797 /* gather received frames */ 7798 do { 7799 /* !give others some time to run! */ 7800 if (n >= bound_limit) 7801 break; 7802 7803 morepending = dma_rx(wlc_hw->di[fifo], &recv_frames); 7804 n++; 7805 } while (morepending); 7806 7807 /* post more rbufs */ 7808 dma_rxfill(wlc_hw->di[fifo]); 7809 7810 /* process each frame */ 7811 skb_queue_walk_safe(&recv_frames, p, next) { 7812 struct d11rxhdr_le *rxh_le; 7813 struct d11rxhdr *rxh; 7814 7815 skb_unlink(p, &recv_frames); 7816 rxh_le = (struct d11rxhdr_le *)p->data; 7817 rxh = (struct d11rxhdr *)p->data; 7818 7819 /* fixup rx header endianness */ 7820 rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize); 7821 rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0); 7822 rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1); 7823 rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2); 7824 rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3); 7825 rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4); 7826 rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5); 7827 rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1); 7828 rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2); 7829 rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime); 7830 rxh->RxChan = le16_to_cpu(rxh_le->RxChan); 7831 7832 brcms_c_recv(wlc_hw->wlc, p); 7833 } 7834 7835 return morepending; 7836} 7837 7838/* second-level interrupt processing 7839 * Return true if another dpc needs to be re-scheduled. false otherwise. 7840 * Param 'bounded' indicates if applicable loops should be bounded. 7841 */ 7842bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) 7843{ 7844 u32 macintstatus; 7845 struct brcms_hardware *wlc_hw = wlc->hw; 7846 struct bcma_device *core = wlc_hw->d11core; 7847 7848 if (brcms_deviceremoved(wlc)) { 7849 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, 7850 __func__); 7851 brcms_down(wlc->wl); 7852 return false; 7853 } 7854 7855 /* grab and clear the saved software intstatus bits */ 7856 macintstatus = wlc->macintstatus; 7857 wlc->macintstatus = 0; 7858 7859 brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n", 7860 wlc_hw->unit, macintstatus); 7861 7862 WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ 7863 7864 /* tx status */ 7865 if (macintstatus & MI_TFS) { 7866 bool fatal; 7867 if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) 7868 wlc->macintstatus |= MI_TFS; 7869 if (fatal) { 7870 brcms_err(core, "MI_TFS: fatal\n"); 7871 goto fatal; 7872 } 7873 } 7874 7875 if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) 7876 brcms_c_tbtt(wlc); 7877 7878 /* ATIM window end */ 7879 if (macintstatus & MI_ATIMWINEND) { 7880 brcms_dbg_info(core, "end of ATIM window\n"); 7881 bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); 7882 wlc->qvalid = 0; 7883 } 7884 7885 /* 7886 * received data or control frame, MI_DMAINT is 7887 * indication of RX_FIFO interrupt 7888 */ 7889 if (macintstatus & MI_DMAINT) 7890 if (brcms_b_recv(wlc_hw, RX_FIFO, bounded)) 7891 wlc->macintstatus |= MI_DMAINT; 7892 7893 /* noise sample collected */ 7894 if (macintstatus & MI_BG_NOISE) 7895 wlc_phy_noise_sample_intr(wlc_hw->band->pi); 7896 7897 if (macintstatus & MI_GP0) { 7898 brcms_err(core, "wl%d: PSM microcode watchdog fired at %d " 7899 "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); 7900 7901 printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", 7902 __func__, ai_get_chip_id(wlc_hw->sih), 7903 ai_get_chiprev(wlc_hw->sih)); 7904 brcms_fatal_error(wlc_hw->wlc->wl); 7905 } 7906 7907 /* gptimer timeout */ 7908 if (macintstatus & MI_TO) 7909 bcma_write32(core, D11REGOFFS(gptimer), 0); 7910 7911 if (macintstatus & MI_RFDISABLE) { 7912 brcms_dbg_info(core, "wl%d: BMAC Detected a change on the" 7913 " RF Disable Input\n", wlc_hw->unit); 7914 brcms_rfkill_set_hw_state(wlc->wl); 7915 } 7916 7917 /* BCN template is available */ 7918 if (macintstatus & MI_BCNTPL) 7919 brcms_c_update_beacon(wlc); 7920 7921 /* it isn't done and needs to be resched if macintstatus is non-zero */ 7922 return wlc->macintstatus != 0; 7923 7924 fatal: 7925 brcms_fatal_error(wlc_hw->wlc->wl); 7926 return wlc->macintstatus != 0; 7927} 7928 7929void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) 7930{ 7931 struct bcma_device *core = wlc->hw->d11core; 7932 struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; 7933 u16 chanspec; 7934 7935 brcms_dbg_info(core, "wl%d\n", wlc->pub->unit); 7936 7937 chanspec = ch20mhz_chspec(ch->hw_value); 7938 7939 brcms_b_init(wlc->hw, chanspec); 7940 7941 /* update beacon listen interval */ 7942 brcms_c_bcn_li_upd(wlc); 7943 7944 /* write ethernet address to core */ 7945 brcms_c_set_mac(wlc->bsscfg); 7946 brcms_c_set_bssid(wlc->bsscfg); 7947 7948 /* Update tsf_cfprep if associated and up */ 7949 if (wlc->pub->associated && wlc->pub->up) { 7950 u32 bi; 7951 7952 /* get beacon period and convert to uS */ 7953 bi = wlc->bsscfg->current_bss->beacon_period << 10; 7954 /* 7955 * update since init path would reset 7956 * to default value 7957 */ 7958 bcma_write32(core, D11REGOFFS(tsf_cfprep), 7959 bi << CFPREP_CBI_SHIFT); 7960 7961 /* Update maccontrol PM related bits */ 7962 brcms_c_set_ps_ctrl(wlc); 7963 } 7964 7965 brcms_c_bandinit_ordered(wlc, chanspec); 7966 7967 /* init probe response timeout */ 7968 brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout); 7969 7970 /* init max burst txop (framebursting) */ 7971 brcms_b_write_shm(wlc->hw, M_MBURST_TXOP, 7972 (wlc-> 7973 _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); 7974 7975 /* initialize maximum allowed duty cycle */ 7976 brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); 7977 brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); 7978 7979 /* 7980 * Update some shared memory locations related to 7981 * max AMPDU size allowed to received 7982 */ 7983 brcms_c_ampdu_shm_upd(wlc->ampdu); 7984 7985 /* band-specific inits */ 7986 brcms_c_bsinit(wlc); 7987 7988 /* Enable EDCF mode (while the MAC is suspended) */ 7989 bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); 7990 brcms_c_edcf_setparams(wlc, false); 7991 7992 /* read the ucode version if we have not yet done so */ 7993 if (wlc->ucode_rev == 0) { 7994 u16 rev; 7995 u16 patch; 7996 7997 rev = brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR); 7998 patch = brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR); 7999 wlc->ucode_rev = (rev << NBITS(u16)) | patch; 8000 snprintf(wlc->wiphy->fw_version, 8001 sizeof(wlc->wiphy->fw_version), "%u.%u", rev, patch); 8002 } 8003 8004 /* ..now really unleash hell (allow the MAC out of suspend) */ 8005 brcms_c_enable_mac(wlc); 8006 8007 /* suspend the tx fifos and mute the phy for preism cac time */ 8008 if (mute_tx) 8009 brcms_b_mute(wlc->hw, true); 8010 8011 /* enable the RF Disable Delay timer */ 8012 bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); 8013 8014 /* 8015 * Initialize WME parameters; if they haven't been set by some other 8016 * mechanism (IOVar, etc) then read them from the hardware. 8017 */ 8018 if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) { 8019 /* Uninitialized; read from HW */ 8020 int ac; 8021 8022 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 8023 wlc->wme_retries[ac] = 8024 brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac)); 8025 } 8026} 8027 8028/* 8029 * The common driver entry routine. Error codes should be unique 8030 */ 8031struct brcms_c_info * 8032brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, 8033 bool piomode, uint *perr) 8034{ 8035 struct brcms_c_info *wlc; 8036 uint err = 0; 8037 uint i, j; 8038 struct brcms_pub *pub; 8039 8040 /* allocate struct brcms_c_info state and its substructures */ 8041 wlc = brcms_c_attach_malloc(unit, &err, 0); 8042 if (wlc == NULL) 8043 goto fail; 8044 wlc->wiphy = wl->wiphy; 8045 pub = wlc->pub; 8046 8047#if defined(DEBUG) 8048 wlc_info_dbg = wlc; 8049#endif 8050 8051 wlc->band = wlc->bandstate[0]; 8052 wlc->core = wlc->corestate; 8053 wlc->wl = wl; 8054 pub->unit = unit; 8055 pub->_piomode = piomode; 8056 wlc->bandinit_pending = false; 8057 wlc->beacon_template_virgin = true; 8058 8059 /* populate struct brcms_c_info with default values */ 8060 brcms_c_info_init(wlc, unit); 8061 8062 /* update sta/ap related parameters */ 8063 brcms_c_ap_upd(wlc); 8064 8065 /* 8066 * low level attach steps(all hw accesses go 8067 * inside, no more in rest of the attach) 8068 */ 8069 err = brcms_b_attach(wlc, core, unit, piomode); 8070 if (err) 8071 goto fail; 8072 8073 brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF); 8074 8075 pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band); 8076 8077 /* disable allowed duty cycle */ 8078 wlc->tx_duty_cycle_ofdm = 0; 8079 wlc->tx_duty_cycle_cck = 0; 8080 8081 brcms_c_stf_phy_chain_calc(wlc); 8082 8083 /* txchain 1: txant 0, txchain 2: txant 1 */ 8084 if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) 8085 wlc->stf->txant = wlc->stf->hw_txchain - 1; 8086 8087 /* push to BMAC driver */ 8088 wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, 8089 wlc->stf->hw_rxchain); 8090 8091 /* pull up some info resulting from the low attach */ 8092 for (i = 0; i < NFIFO; i++) 8093 wlc->core->txavail[i] = wlc->hw->txavail[i]; 8094 8095 memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN); 8096 memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN); 8097 8098 for (j = 0; j < wlc->pub->_nbands; j++) { 8099 wlc->band = wlc->bandstate[j]; 8100 8101 if (!brcms_c_attach_stf_ant_init(wlc)) { 8102 err = 24; 8103 goto fail; 8104 } 8105 8106 /* default contention windows size limits */ 8107 wlc->band->CWmin = APHY_CWMIN; 8108 wlc->band->CWmax = PHY_CWMAX; 8109 8110 /* init gmode value */ 8111 if (wlc->band->bandtype == BRCM_BAND_2G) { 8112 wlc->band->gmode = GMODE_AUTO; 8113 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, 8114 wlc->band->gmode); 8115 } 8116 8117 /* init _n_enab supported mode */ 8118 if (BRCMS_PHY_11N_CAP(wlc->band)) { 8119 pub->_n_enab = SUPPORT_11N; 8120 brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER, 8121 ((pub->_n_enab == 8122 SUPPORT_11N) ? WL_11N_2x2 : 8123 WL_11N_3x3)); 8124 } 8125 8126 /* init per-band default rateset, depend on band->gmode */ 8127 brcms_default_rateset(wlc, &wlc->band->defrateset); 8128 8129 /* fill in hw_rateset */ 8130 brcms_c_rateset_filter(&wlc->band->defrateset, 8131 &wlc->band->hw_rateset, false, 8132 BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK, 8133 (bool) (wlc->pub->_n_enab & SUPPORT_11N)); 8134 } 8135 8136 /* 8137 * update antenna config due to 8138 * wlc->stf->txant/txchain/ant_rx_ovr change 8139 */ 8140 brcms_c_stf_phy_txant_upd(wlc); 8141 8142 /* attach each modules */ 8143 err = brcms_c_attach_module(wlc); 8144 if (err != 0) 8145 goto fail; 8146 8147 if (!brcms_c_timers_init(wlc, unit)) { 8148 wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit, 8149 __func__); 8150 err = 32; 8151 goto fail; 8152 } 8153 8154 /* depend on rateset, gmode */ 8155 wlc->cmi = brcms_c_channel_mgr_attach(wlc); 8156 if (!wlc->cmi) { 8157 wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed" 8158 "\n", unit, __func__); 8159 err = 33; 8160 goto fail; 8161 } 8162 8163 /* init default when all parameters are ready, i.e. ->rateset */ 8164 brcms_c_bss_default_init(wlc); 8165 8166 /* 8167 * Complete the wlc default state initializations.. 8168 */ 8169 8170 wlc->bsscfg->wlc = wlc; 8171 8172 wlc->mimoft = FT_HT; 8173 wlc->mimo_40txbw = AUTO; 8174 wlc->ofdm_40txbw = AUTO; 8175 wlc->cck_40txbw = AUTO; 8176 brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G); 8177 8178 /* Set default values of SGI */ 8179 if (BRCMS_SGI_CAP_PHY(wlc)) { 8180 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 | 8181 BRCMS_N_SGI_40)); 8182 } else if (BRCMS_ISSSLPNPHY(wlc->band)) { 8183 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 | 8184 BRCMS_N_SGI_40)); 8185 } else { 8186 brcms_c_ht_update_sgi_rx(wlc, 0); 8187 } 8188 8189 brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail); 8190 8191 if (perr) 8192 *perr = 0; 8193 8194 return wlc; 8195 8196 fail: 8197 wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n", 8198 unit, __func__, err); 8199 if (wlc) 8200 brcms_c_detach(wlc); 8201 8202 if (perr) 8203 *perr = err; 8204 return NULL; 8205} 8206