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