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