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