15b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/*
25b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Copyright (c) 2010 Broadcom Corporation
35b435de0d786869c95d1962121af0d7df2542009Arend van Spriel *
45b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Permission to use, copy, modify, and/or distribute this software for any
55b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * purpose with or without fee is hereby granted, provided that the above
65b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * copyright notice and this permission notice appear in all copies.
75b435de0d786869c95d1962121af0d7df2542009Arend van Spriel *
85b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
95b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */
165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <linux/kernel.h>
175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <linux/delay.h>
185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <linux/bitops.h>
195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <brcm_hw_ids.h>
215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <chipcommon.h>
225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <aiutils.h>
235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <d11.h>
245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <phy_shim.h>
255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "phy_hal.h"
265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "phy_int.h"
275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "phy_radio.h"
285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "phy_lcn.h"
295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "phyreg_n.h"
305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || \
325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				 (radioid == BCM2056_ID) || \
335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				 (radioid == BCM2057_ID))
345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define VALID_LCN_RADIO(radioid)	(radioid == BCM2064_ID)
365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define VALID_RADIO(pi, radioid)        ( \
385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* basic mux operation - can be optimized on several architectures */
425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define MUX(pred, true, false) ((pred) ? (true) : (false))
435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* modulo inc/dec - assumes x E [0, bound - 1] */
455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* modulo inc/dec, bound = 2^k */
485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
515b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct chan_info_basic {
525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 chan;
535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 freq;
545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel};
555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
565b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct chan_info_basic chan_info_all[] = {
575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{1, 2412},
585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{2, 2417},
595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{3, 2422},
605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{4, 2427},
615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{5, 2432},
625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{6, 2437},
635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{7, 2442},
645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{8, 2447},
655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{9, 2452},
665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{10, 2457},
675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{11, 2462},
685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{12, 2467},
695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{13, 2472},
705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{14, 2484},
715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{34, 5170},
735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{38, 5190},
745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{42, 5210},
755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{46, 5230},
765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{36, 5180},
785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{40, 5200},
795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{44, 5220},
805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{48, 5240},
815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{52, 5260},
825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{56, 5280},
835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{60, 5300},
845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{64, 5320},
855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{100, 5500},
875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{104, 5520},
885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{108, 5540},
895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{112, 5560},
905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{116, 5580},
915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{120, 5600},
925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{124, 5620},
935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{128, 5640},
945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{132, 5660},
955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{136, 5680},
965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{140, 5700},
975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{149, 5745},
995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{153, 5765},
1005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{157, 5785},
1015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{161, 5805},
1025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{165, 5825},
1035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{184, 4920},
1055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{188, 4940},
1065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{192, 4960},
1075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{196, 4980},
1085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{200, 5000},
1095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{204, 5020},
1105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{208, 5040},
1115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	{212, 5060},
1128906c43cb160abc89c3d7e0721cacb8bc54be927Alwin Beukers	{216, 5080}
1135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel};
1145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1151433c59bcc404cd4bd54333d23ce06242d8e32b7Arend van Sprielstatic const u8 ofdm_rate_lookup[] = {
1165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_48M,
1185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_24M,
1195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_12M,
1205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_6M,
1215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_54M,
1225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_36M,
1235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_18M,
1245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	BRCM_RATE_9M
1255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel};
1265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define PHY_WREG_LIMIT  24
1285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1295b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phyreg_enter(struct brcms_phy_pub *pih)
1305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
1315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
1325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
1335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
1345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1355b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phyreg_exit(struct brcms_phy_pub *pih)
1365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
1375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
1385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
1395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
1405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1415b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_radioreg_enter(struct brcms_phy_pub *pih)
1425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
1435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
1445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
1455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	udelay(10);
1475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
1485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1495b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_radioreg_exit(struct brcms_phy_pub *pih)
1505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
1515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
1525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1534b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
1545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg = 0;
1555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
1565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
1575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1585b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu16 read_radio_reg(struct brcms_phy *pi, u16 addr)
1595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
1605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 data;
1615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((addr == RADIO_IDCODE))
1635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return 0xffff;
1645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	switch (pi->pubpi.phy_type) {
1665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_TYPE_N:
1675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!CONF_HAS(PHYTYPE, PHY_TYPE_N))
1685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			break;
1695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (NREV_GE(pi->pubpi.phy_rev, 7))
1705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			addr |= RADIO_2057_READ_OFF;
1715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		else
1725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			addr |= RADIO_2055_READ_OFF;
1735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
1745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_TYPE_LCN:
1765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!CONF_HAS(PHYTYPE, PHY_TYPE_LCN))
1775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			break;
1785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		addr |= RADIO_2064_READ_OFF;
1795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
1805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	default:
1825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
1835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
1845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((D11REV_GE(pi->sh->corerev, 24)) ||
1865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (D11REV_IS(pi->sh->corerev, 22)
1875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
1884b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
1894b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		data = bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
1905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
1914b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
1924b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		data = bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
1935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
1945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg = 0;
1955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return data;
1975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
1985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
1995b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
2005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((D11REV_GE(pi->sh->corerev, 24)) ||
2025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (D11REV_IS(pi->sh->corerev, 22)
2035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
2045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2054b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
2064b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_write16(pi->d11core, D11REGOFFS(radioregdata), val);
2075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
2084b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
2094b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_write16(pi->d11core, D11REGOFFS(phy4wdatalo), val);
2105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
2115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
2134b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
2145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phy_wreg = 0;
2155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
2165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2185b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic u32 read_radio_id(struct brcms_phy *pi)
2195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 id;
2215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (D11REV_GE(pi->sh->corerev, 24)) {
2235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u32 b0, b1, b2;
2245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2254b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 0);
2264b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		b0 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
2274b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 1);
2284b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		b1 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
2294b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 2);
2304b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		b2 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
2315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
2335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel								      & 0xf);
2345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
2354b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), RADIO_IDCODE);
2364b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		id = (u32) bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
2374b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		id |= (u32) bcma_read16(pi->d11core,
2384b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel					D11REGOFFS(phy4wdatahi)) << 16;
2395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
2405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg = 0;
2415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return id;
2425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2445b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
2455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 rval;
2475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	rval = read_radio_reg(pi, addr);
2495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_radio_reg(pi, addr, (rval & val));
2505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2525b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
2535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 rval;
2555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	rval = read_radio_reg(pi, addr);
2575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_radio_reg(pi, addr, (rval | val));
2585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2605b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask)
2615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 rval;
2635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	rval = read_radio_reg(pi, addr);
2655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_radio_reg(pi, addr, (rval ^ mask));
2665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2685b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
2695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 rval;
2715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	rval = read_radio_reg(pi, addr);
2735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
2745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2765b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid write_phy_channel_reg(struct brcms_phy *pi, uint val)
2775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2784b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(pi->d11core, D11REGOFFS(phychannel), val);
2795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2815b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu16 read_phy_reg(struct brcms_phy *pi, u16 addr)
2825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2834b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
2845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg = 0;
2864b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	return bcma_read16(pi->d11core, D11REGOFFS(phyregdata));
2875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2895b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
2905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#ifdef CONFIG_BCM47XX
2924b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
2934b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(pi->d11core, D11REGOFFS(phyregdata), val);
2945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (addr == 0x72)
2954b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
2965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#else
2974b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write32(pi->d11core, D11REGOFFS(phyregaddr), addr | (val << 16));
2985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
2995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phy_wreg = 0;
3004b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
3015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
3025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#endif
3035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
3045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3055b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
3065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
3074b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
3084b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_mask16(pi->d11core, D11REGOFFS(phyregdata), val);
3095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg = 0;
3105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
3115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3125b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
3135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
3144b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
3154b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_set16(pi->d11core, D11REGOFFS(phyregdata), val);
3165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg = 0;
3175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
3185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3195b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
3205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
3214b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	val &= mask;
3224b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
3234b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_maskset16(pi->d11core, D11REGOFFS(phyregdata), ~mask, val);
3245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg = 0;
3255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
3265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3275b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void wlc_set_phy_uninitted(struct brcms_phy *pi)
3285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
3295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int i, j;
3305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->initialized = false;
3325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->tx_vos = 0xffff;
3345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nrssi_table_delta = 0x7fffffff;
3355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->rc_cal = 0xffff;
3365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->mintxbias = 0xffff;
3375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->txpwridx = -1;
3385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
3395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phy_spuravoid = SPURAVOID_DISABLE;
3405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (NREV_GE(pi->pubpi.phy_rev, 3)
3425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    && NREV_LT(pi->pubpi.phy_rev, 7))
3435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->phy_spuravoid = SPURAVOID_AUTO;
3445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_papd_skip = 0;
3465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_papd_epsilon_offset[0] = 0xf588;
3475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_papd_epsilon_offset[1] = 0xf588;
3485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_txpwr_idx[0] = 128;
3495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_txpwr_idx[1] = 128;
3505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_txpwrindex[0].index_internal = 40;
3515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_txpwrindex[1].index_internal = 40;
3525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phy_pabias = 0;
3535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
3545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phy_spuravoid = SPURAVOID_AUTO;
3555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
3565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->radiopwr = 0xffff;
3575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < STATIC_NUM_RF; i++) {
3585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (j = 0; j < STATIC_NUM_BB; j++)
3595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->stats_11b_txpower[i][j] = -1;
3605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
3615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
3625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3635b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
3645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
3655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct shared_phy *sh;
3665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC);
3685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (sh == NULL)
3695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return NULL;
3705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->sih = shp->sih;
3725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->physhim = shp->physhim;
3735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->unit = shp->unit;
3745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->corerev = shp->corerev;
3755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->vid = shp->vid;
3775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->did = shp->did;
3785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->chip = shp->chip;
3795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->chiprev = shp->chiprev;
3805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->chippkg = shp->chippkg;
3815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->sromrev = shp->sromrev;
3825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->boardtype = shp->boardtype;
3835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->boardrev = shp->boardrev;
3845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->boardflags = shp->boardflags;
3855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->boardflags2 = shp->boardflags2;
3865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->fast_timer = PHY_SW_TIMER_FAST;
3885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->slow_timer = PHY_SW_TIMER_SLOW;
3895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
3905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->rssi_mode = RSSI_ANT_MERGE_MAX;
3925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return sh;
3945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
3955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
3965b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void wlc_phy_timercb_phycal(struct brcms_phy *pi)
3975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
3985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint delay = 5;
3995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
4015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!pi->sh->up) {
4025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_cal_perical_mphase_reset(pi);
4035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			return;
4045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
4055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
4075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			delay = 1000;
4095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_cal_perical_mphase_restart(pi);
4105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else
4115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
412be69c4ef462a476523f89c74e7db29f6ad207a1aRoland Vossen		wlapi_add_timer(pi->phycal_timer, delay, 0);
4135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
4145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
4155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
4175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4185b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic u32 wlc_phy_get_radio_ver(struct brcms_phy *pi)
4195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
4205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 ver;
4215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	ver = read_radio_id(pi);
4235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return ver;
4255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
4265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4275b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct brcms_phy_pub *
4284b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Sprielwlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core,
4295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       int bandtype, struct wiphy *wiphy)
4305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
4315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi;
4325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 sflags = 0;
4335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint phyversion;
4345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 idcode;
4355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int i;
4365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (D11REV_IS(sh->corerev, 4))
4385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		sflags = SISF_2G_PHY | SISF_5G_PHY;
4395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
440a8779e4a8e7f0f90ae169393cd72105134ce7c7bArend van Spriel		sflags = bcma_aread32(d11core, BCMA_IOST);
4415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (bandtype == BRCM_BAND_5G) {
4435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0)
4445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			return NULL;
4455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
4465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi = sh->phy_head;
4485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((sflags & SISF_DB_PHY) && pi) {
4495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
4505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->refcnt++;
4515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return &pi->pubpi_ro;
4525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
4535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC);
4555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi == NULL)
4565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return NULL;
4575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->wiphy = wiphy;
4584b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	pi->d11core = d11core;
4595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh = sh;
4605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_init_por = true;
4615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_wreg_limit = PHY_WREG_LIMIT;
4625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->txpwr_percent = 100;
4645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->do_initcal = true;
4665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phycal_tempdelta = 0;
4685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (bandtype == BRCM_BAND_2G && (sflags & SISF_2G_PHY))
4705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->pubpi.coreflags = SICF_GMODE;
4715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
4734b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	phyversion = bcma_read16(pi->d11core, D11REGOFFS(phyversion));
4745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.phy_type = PHY_TYPE(phyversion);
4765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
4775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
4795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->pubpi.phy_type = PHY_TYPE_N;
4805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->pubpi.phy_rev += LCNXN_BASEREV;
4815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
4825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
4835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
4845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
485aa1f2f0a3218a9b6ce979fca3d6ebdb1c5544dd8Dan Carpenter	if (pi->pubpi.phy_type != PHY_TYPE_N &&
486aa1f2f0a3218a9b6ce979fca3d6ebdb1c5544dd8Dan Carpenter	    pi->pubpi.phy_type != PHY_TYPE_LCN)
4875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		goto err;
4885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (bandtype == BRCM_BAND_5G) {
4905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!ISNPHY(pi))
4915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			goto err;
4925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
4935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		goto err;
4945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
4955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_anacore((struct brcms_phy_pub *) pi, ON);
4975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
4985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	idcode = wlc_phy_get_radio_ver(pi);
4995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.radioid =
5005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
5015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.radiorev =
5025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
5035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.radiover =
5045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
5055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!VALID_RADIO(pi, pi->pubpi.radioid))
5065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		goto err;
5075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, OFF);
5095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_set_phy_uninitted(pi);
5115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->bw = WL_CHANSPEC_BW_20;
5135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->radio_chanspec = (bandtype == BRCM_BAND_2G) ?
5145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     ch20mhz_chspec(1) : ch20mhz_chspec(36);
5155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
5175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->rxiq_antsel = ANT_RX_DIV_DEF;
5185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->watchdog_override = true;
5205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->cal_type_override = PHY_PERICAL_AUTO;
5225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_saved_noisevars.bufcount = 0;
5245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi))
5265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->min_txpower = PHY_TXPWR_MIN_NPHY;
5275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
5285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->min_txpower = PHY_TXPWR_MIN;
5295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->phyrxchain = 0x3;
5315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->rx2tx_biasentry = -1;
5335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
5355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_txcore_enable_temp =
5365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
5375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_tempsense_offset = 0;
5385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_txcore_heatedup = false;
5395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_lastcal_temp = -50;
5415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phynoise_polling = true;
5435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi) || ISLCNPHY(pi))
5445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phynoise_polling = false;
5455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < TXP_NUM_RATES; i++) {
5475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_limit[i] = BRCMS_TXPWR_MAX;
5485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
5495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->tx_user_target[i] = BRCMS_TXPWR_MAX;
5505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
5515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
5535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->user_txpwr_at_rfport = false;
5555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
5575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
5595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						    wlc_phy_timercb_phycal,
5605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						    pi, "phycal");
5615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!pi->phycal_timer)
5625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			goto err;
5635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!wlc_phy_attach_nphy(pi))
5655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			goto err;
5665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (ISLCNPHY(pi)) {
5685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!wlc_phy_attach_lcnphy(pi))
5695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			goto err;
5705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
5725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->refcnt++;
5745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->next = pi->sh->phy_head;
5755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	sh->phy_head = pi;
5765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(struct brcms_phy_pub));
5785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return &pi->pubpi_ro;
5805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5815b435de0d786869c95d1962121af0d7df2542009Arend van Sprielerr:
5825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	kfree(pi);
5835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return NULL;
5845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
5855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5865b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_detach(struct brcms_phy_pub *pih)
5875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
5885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
5895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pih) {
5915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (--pi->refcnt)
5925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			return;
5935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->phycal_timer) {
595be69c4ef462a476523f89c74e7db29f6ad207a1aRoland Vossen			wlapi_free_timer(pi->phycal_timer);
5965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->phycal_timer = NULL;
5975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
5985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
5995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->sh->phy_head == pi)
6005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->sh->phy_head = pi->next;
6015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		else if (pi->sh->phy_head->next == pi)
6025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->sh->phy_head->next = NULL;
6035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->pi_fptr.detach)
6055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			(pi->pi_fptr.detach)(pi);
6065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		kfree(pi);
6085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
6095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
6105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6115b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbool
6125b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
6135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		       u16 *radioid, u16 *radiover)
6145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
6155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
6165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*phytype = (u16) pi->pubpi.phy_type;
6175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*phyrev = (u16) pi->pubpi.phy_rev;
6185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*radioid = pi->pubpi.radioid;
6195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*radiover = pi->pubpi.radiorev;
6205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return true;
6225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
6235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6245b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbool wlc_phy_get_encore(struct brcms_phy_pub *pih)
6255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
6265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
6275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return pi->pubpi.abgphy_encore;
6285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
6295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6305b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih)
6315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
6325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
6335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return pi->pubpi.coreflags;
6345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
6355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6365b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
6375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
6385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
6395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
6415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (on) {
6425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
6435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa6, 0x0d);
6445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0x8f, 0x0);
6455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa7, 0x0d);
6465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa5, 0x0);
6475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			} else {
6485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa5, 0x0);
6495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
6505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
6515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
6525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0x8f, 0x07ff);
6535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa6, 0x0fd);
6545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa5, 0x07ff);
6555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa7, 0x0fd);
6565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			} else {
6575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_phy_reg(pi, 0xa5, 0x7fff);
6585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
6595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
6605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (ISLCNPHY(pi)) {
6615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (on) {
6625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x43b,
6635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
6645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
6655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			or_phy_reg(pi, 0x43c,
6665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
6675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			or_phy_reg(pi, 0x43b,
6685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
6695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
6705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
6715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
6725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6735b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
6745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
6755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
6765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 phy_bw_clkbits = 0;
6785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
6805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		switch (pi->bw) {
6815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		case WL_CHANSPEC_BW_10:
6825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			phy_bw_clkbits = SICF_BW10;
6835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			break;
6845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		case WL_CHANSPEC_BW_20:
6855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			phy_bw_clkbits = SICF_BW20;
6865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			break;
6875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		case WL_CHANSPEC_BW_40:
6885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			phy_bw_clkbits = SICF_BW40;
6895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			break;
6905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		default:
6915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			break;
6925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
6935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
6945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return phy_bw_clkbits;
6965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
6975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
6985b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_por_inform(struct brcms_phy_pub *ppi)
6995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
7005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
7015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_init_por = true;
7035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
7045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7055b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
7065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
7075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
7085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->edcrs_threshold_lock = lock;
7105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_phy_reg(pi, 0x22c, 0x46b);
7125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_phy_reg(pi, 0x22d, 0x46b);
7135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_phy_reg(pi, 0x22e, 0x3c0);
7145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_phy_reg(pi, 0x22f, 0x3c0);
7155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
7165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7175b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal)
7185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
7195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
7205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->do_initcal = initcal;
7225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
7235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7245b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
7255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
7265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
7275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi || !pi->sh)
7295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
7305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->clk = newstate;
7325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
7335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7345b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate)
7355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
7365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
7375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi || !pi->sh)
7395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
7405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->up = newstate;
7425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
7435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7445b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
7455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
7465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 mc;
7475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	void (*phy_init)(struct brcms_phy *) = NULL;
7485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
7495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->init_in_progress)
7515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
7525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->init_in_progress = true;
7545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->radio_chanspec = chanspec;
7565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7574b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
7585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
7595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
7605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
7625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
7635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
764a8779e4a8e7f0f90ae169393cd72105134ce7c7bArend van Spriel	if (WARN(!(bcma_aread32(pi->d11core, BCMA_IOST) & SISF_FCLKA),
7655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		 "HW error SISF_FCLKA\n"))
7665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
7675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	phy_init = pi->pi_fptr.init;
7695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (phy_init == NULL)
7715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
7725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_anacore(pih, ON);
7745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
7765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_bw_set(pi->sh->physhim,
7775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				  CHSPEC_BW(pi->radio_chanspec));
7785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_gain_boost = true;
7805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON);
7825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	(*phy_init)(pi);
7845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phy_init_por = false;
7865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
7885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_do_dummy_tx(pi, true, OFF);
7895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!(ISNPHY(pi)))
7915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_txpower_update_shm(pi);
7925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, pi->sh->rx_antdiv);
7945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->init_in_progress = false;
7965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
7975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
7985b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_cal_init(struct brcms_phy_pub *pih)
7995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
8005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
8015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	void (*cal_init)(struct brcms_phy *) = NULL;
8025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8034b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
8044b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		  MCTL_EN_MAC) != 0, "HW error: MAC enabled during phy cal\n"))
8055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
8065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->initialized) {
8085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		cal_init = pi->pi_fptr.calinit;
8095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (cal_init)
8105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			(*cal_init)(pi);
8115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->initialized = true;
8135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
8145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
8155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8165b435de0d786869c95d1962121af0d7df2542009Arend van Sprielint wlc_phy_down(struct brcms_phy_pub *pih)
8175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
8185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
8195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int callbacks = 0;
8205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->phycal_timer
822be69c4ef462a476523f89c74e7db29f6ad207a1aRoland Vossen	    && !wlapi_del_timer(pi->phycal_timer))
8235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		callbacks++;
8245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_iqcal_chanspec_2G = 0;
8265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_iqcal_chanspec_5G = 0;
8275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return callbacks;
8295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
8305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8315b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
8325b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset,
8335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
8345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
8355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
8365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->tbl_data_hi = tblDataHi;
8385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->tbl_data_lo = tblDataLo;
8395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->sh->chip == BCM43224_CHIP_ID &&
8415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    pi->sh->chiprev == 1) {
8425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->tbl_addr = tblAddr;
8435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->tbl_save_id = tbl_id;
8445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->tbl_save_offset = tbl_offset;
8455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
8465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
8475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8485b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val)
8495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
8505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((pi->sh->chip == BCM43224_CHIP_ID) &&
8515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (pi->sh->chiprev == 1) &&
8525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
8535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		read_phy_reg(pi, pi->tbl_data_lo);
8545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		write_phy_reg(pi, pi->tbl_addr,
8565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			      (pi->tbl_save_id << 10) | pi->tbl_save_offset);
8575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->tbl_save_offset++;
8585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
8595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (width == 32) {
8615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
8625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
8635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
8645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
8655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
8665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
8675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8685b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
8695b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
8705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
8715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
8725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint idx;
8735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint tbl_id = ptbl_info->tbl_id;
8745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint tbl_offset = ptbl_info->tbl_offset;
8755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint tbl_width = ptbl_info->tbl_width;
8765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
8775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
8785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
8795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
8815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
8835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
8855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    (pi->sh->chiprev == 1) &&
8865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
8875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			read_phy_reg(pi, tblDataLo);
8885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			write_phy_reg(pi, tblAddr,
8905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      (tbl_id << 10) | (tbl_offset + idx));
8915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
8925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
8935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (tbl_width == 32) {
8945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			write_phy_reg(pi, tblDataHi,
8955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      (u16) (ptbl_32b[idx] >> 16));
8965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
8975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else if (tbl_width == 16) {
8985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
8995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
9005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
9015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
9025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
9035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
9045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9055b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
9065b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
9075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
9085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
9095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint idx;
9105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint tbl_id = ptbl_info->tbl_id;
9115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint tbl_offset = ptbl_info->tbl_offset;
9125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint tbl_width = ptbl_info->tbl_width;
9135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
9145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
9155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
9165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
9185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
9205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
9225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    (pi->sh->chiprev == 1)) {
9235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			(void)read_phy_reg(pi, tblDataLo);
9245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			write_phy_reg(pi, tblAddr,
9265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      (tbl_id << 10) | (tbl_offset + idx));
9275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
9285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (tbl_width == 32) {
9305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
9315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
9325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else if (tbl_width == 16) {
9335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
9345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
9355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
9365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
9375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
9385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
9395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9405b435de0d786869c95d1962121af0d7df2542009Arend van Sprieluint
9415b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
9425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				 struct radio_20xx_regs *radioregs)
9435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
9445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint i = 0;
9455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	do {
9475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (radioregs[i].do_init)
9485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			write_radio_reg(pi, radioregs[i].address,
9495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					(u16) radioregs[i].init);
9505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		i++;
9525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} while (radioregs[i].address != 0xffff);
9535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return i;
9555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
9565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9575b435de0d786869c95d1962121af0d7df2542009Arend van Sprieluint
9585b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_init_radio_regs(struct brcms_phy *pi,
9595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			const struct radio_regs *radioregs,
9605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			u16 core_offset)
9615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
9625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint i = 0;
9635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint count = 0;
9645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	do {
9665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (CHSPEC_IS5G(pi->radio_chanspec)) {
9675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (radioregs[i].do_init_a) {
9685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_radio_reg(pi,
9695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						radioregs[i].
9705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						address | core_offset,
9715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						(u16) radioregs[i].init_a);
9725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				if (ISNPHY(pi) && (++count % 4 == 0))
9735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					BRCMS_PHY_WAR_PR51571(pi);
9745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
9755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
9765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (radioregs[i].do_init_g) {
9775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				write_radio_reg(pi,
9785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						radioregs[i].
9795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						address | core_offset,
9805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						(u16) radioregs[i].init_g);
9815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				if (ISNPHY(pi) && (++count % 4 == 0))
9825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					BRCMS_PHY_WAR_PR51571(pi);
9835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
9845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
9855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		i++;
9875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} while (radioregs[i].address != 0xffff);
9885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return i;
9905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
9915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
9925b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
9935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
9945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define DUMMY_PKT_LEN   20
9954b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	struct bcma_device *core = pi->d11core;
9965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int i, count;
9975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 ofdmpkt[DUMMY_PKT_LEN] = {
9985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
9995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
10005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	};
10015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 cckpkt[DUMMY_PKT_LEN] = {
10025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
10035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
10045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	};
10055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 *dummypkt;
10065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
10085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
10095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      dummypkt);
10105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10114b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(xmtsel), 0);
10125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (D11REV_GE(pi->sh->corerev, 11))
10144b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_write16(core, D11REGOFFS(wepctl), 0x100);
10155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
10164b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_write16(core, D11REGOFFS(wepctl), 0);
10175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10184b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(txe_phyctl),
10194b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		     (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
10205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi) || ISLCNPHY(pi))
10214b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_write16(core, D11REGOFFS(txe_phyctl1), 0x1A02);
10225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10234b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(txe_wm_0), 0);
10244b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(txe_wm_1), 0);
10255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10264b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(xmttplatetxptr), 0);
10274b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(xmttxcnt), DUMMY_PKT_LEN);
10285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10294b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(xmtsel),
10304b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		     ((8 << 8) | (1 << 5) | (1 << 2) | 2));
10315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10324b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	bcma_write16(core, D11REGOFFS(txe_ctl), 0);
10335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pa_on) {
10355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (ISNPHY(pi))
10365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_pa_override_nphy(pi, OFF);
10375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
10385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi) || ISLCNPHY(pi))
10404b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_write16(core, D11REGOFFS(txe_aux), 0xD0);
10415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
10424b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		bcma_write16(core, D11REGOFFS(txe_aux), ((1 << 5) | (1 << 4)));
10435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10444b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	(void)bcma_read16(core, D11REGOFFS(txe_aux));
10455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	i = 0;
10475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	count = ofdm ? 30 : 250;
10485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	while ((i++ < count)
10494b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	       && (bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 7)))
10505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		udelay(10);
10515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	i = 0;
10535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10544b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	while ((i++ < 10) &&
10554b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	       ((bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 10)) == 0))
10565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		udelay(10);
10575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	i = 0;
10595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10604b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	while ((i++ < 10) &&
10614b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	       ((bcma_read16(core, D11REGOFFS(ifsstat)) & (1 << 8))))
10625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		udelay(10);
10635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pa_on) {
10655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (ISNPHY(pi))
10665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_pa_override_nphy(pi, ON);
10675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
10685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
10695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10705b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set)
10715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
10725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
10735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (set)
10755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		mboolset(pi->measure_hold, id);
10765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
10775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		mboolclr(pi->measure_hold, id);
10785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return;
10805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
10815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10825b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags)
10835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
10845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
10855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (mute)
10875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
10885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
10895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
10905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!mute && (flags & PHY_MUTE_FOR_PREISM))
10925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
10935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return;
10945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
10955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
10965b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_clear_tssi(struct brcms_phy_pub *pih)
10975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
10985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
10995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
11015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
11025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
11035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
11045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
11055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
11065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
11075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
11085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11105b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
11115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return false;
11135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11155b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
11165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
11184b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
11195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
11215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_switch_radio_nphy(pi, on);
11225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (ISLCNPHY(pi)) {
11235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (on) {
11245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x44c,
11255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    ~((0x1 << 8) |
11265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      (0x1 << 9) |
11275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
11285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
11295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
11305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
11315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x44d,
11325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    ~((0x1 << 10) |
11335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      (0x1 << 11) |
11345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				      (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
11355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			or_phy_reg(pi, 0x44c,
11365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				   (0x1 << 8) |
11375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				   (0x1 << 9) |
11385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				   (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
11395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
11415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
11425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
11435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
11445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			or_phy_reg(pi, 0x4f9, (0x1 << 3));
11455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
11465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
11475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11495b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi)
11505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
11525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return pi->bw;
11545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11565b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw)
11575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
11595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->bw = bw;
11615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11635b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch)
11645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
11665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->radio_chanspec = newch;
11675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11705b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi)
11715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
11735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return pi->radio_chanspec;
11755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11775b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec)
11785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
11805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 m_cur_channel;
11815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	void (*chanspec_set)(struct brcms_phy *, u16) = NULL;
11825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	m_cur_channel = CHSPEC_CHANNEL(chanspec);
11835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (CHSPEC_IS5G(chanspec))
11845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		m_cur_channel |= D11_CURCHANNEL_5G;
11855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (CHSPEC_IS40(chanspec))
11865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		m_cur_channel |= D11_CURCHANNEL_40;
11875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
11885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	chanspec_set = pi->pi_fptr.chanset;
11905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (chanspec_set)
11915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(*chanspec_set)(pi, chanspec);
11925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
11945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11955b435de0d786869c95d1962121af0d7df2542009Arend van Sprielint wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
11965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
11975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int range = -1;
11985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
11995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (freq < 2500)
12005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		range = WL_CHAN_FREQ_RANGE_2G;
12015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else if (freq <= 5320)
12025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		range = WL_CHAN_FREQ_RANGE_5GL;
12035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else if (freq <= 5700)
12045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		range = WL_CHAN_FREQ_RANGE_5GM;
12055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
12065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		range = WL_CHAN_FREQ_RANGE_5GH;
12075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return range;
12095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
12105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12115b435de0d786869c95d1962121af0d7df2542009Arend van Sprielint wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec)
12125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
12135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int range = -1;
12145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint channel = CHSPEC_CHANNEL(chanspec);
12155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint freq = wlc_phy_channel2freq(channel);
12165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi))
12185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
12195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else if (ISLCNPHY(pi))
12205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
12215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return range;
12235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
12245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12255b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
12265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					  bool wide_filter)
12275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
12285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
12295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->channel_14_wide_filter = wide_filter;
12315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
12335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12345b435de0d786869c95d1962121af0d7df2542009Arend van Sprielint wlc_phy_channel2freq(uint channel)
12355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
12365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint i;
12375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
12395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (chan_info_all[i].chan == channel)
12405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			return chan_info_all[i].freq;
12415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return 0;
12425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
12435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12445b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
12455b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
12465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			      struct brcms_chanvec *channels)
12475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
12485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
12495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint i;
12505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint channel;
12515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memset(channels, 0, sizeof(struct brcms_chanvec));
12535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
12555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		channel = chan_info_all[i].chan;
12565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
12585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    && (channel <= LAST_REF5_CHANNUM))
12595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			continue;
12605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
12625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
12635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			setbit(channels->vec, channel);
12645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
12655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
12665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12675b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
12685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
12695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
12705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint i;
12715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint channel;
12725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 chspec;
12735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
12755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		channel = chan_info_all[i].chan;
12765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (ISNPHY(pi) && pi->bw == WL_CHANSPEC_BW_40) {
12785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			uint j;
12795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
12815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				if (chan_info_all[j].chan ==
12825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    channel + CH_10MHZ_APART)
12835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					break;
12845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
12855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (j == ARRAY_SIZE(chan_info_all))
12875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				continue;
12885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			channel = upper_20_sb(channel);
12905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			chspec =  channel | WL_CHANSPEC_BW_40 |
12915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				  WL_CHANSPEC_CTL_SB_LOWER;
12925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (band == BRCM_BAND_2G)
12935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				chspec |= WL_CHANSPEC_BAND_2G;
12945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			else
12955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				chspec |= WL_CHANSPEC_BAND_5G;
12965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else
12975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			chspec = ch20mhz_chspec(channel);
12985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
12995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
13005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    && (channel <= LAST_REF5_CHANNUM))
13015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			continue;
13025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
13045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
13055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			return chspec;
13065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
13075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return (u16) INVCHANSPEC;
13095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
13105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13115b435de0d786869c95d1962121af0d7df2542009Arend van Sprielint wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override)
13125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
13135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
13145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*qdbm = pi->tx_user_target[0];
13165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (override != NULL)
13175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		*override = pi->txpwroverride;
13185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return 0;
13195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
13205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13215b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
13225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				struct txpwr_limits *txpwr)
13235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
13245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	bool mac_enabled = false;
13255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
13265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
13285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->cck[0], BRCMS_NUM_RATES_CCK);
13295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
13315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->ofdm[0], BRCMS_NUM_RATES_OFDM);
13325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
13335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->ofdm_cdd[0], BRCMS_NUM_RATES_OFDM);
13345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
13365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->ofdm_40_siso[0], BRCMS_NUM_RATES_OFDM);
13375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
13385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->ofdm_40_cdd[0], BRCMS_NUM_RATES_OFDM);
13395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
13415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_20_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
13425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
13435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_20_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
13445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
13455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_20_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
13465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
13475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_20_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
13485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
13505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_40_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
13515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
13525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_40_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
13535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
13545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_40_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
13555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
13565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	       &txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
13575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13584b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	if (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
13595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		mac_enabled = true;
13605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (mac_enabled)
13625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_suspend_mac_and_wait(pi->sh->physhim);
13635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_txpower_recalc_target(pi);
13655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_cal_txpower_recalc_sw(pi);
13665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (mac_enabled)
13685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_enable_mac(pi->sh->physhim);
13695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
13705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13715b435de0d786869c95d1962121af0d7df2542009Arend van Sprielint wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
13725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
13735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
13745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int i;
13755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (qdbm > 127)
13775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return -EINVAL;
13785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < TXP_NUM_RATES; i++)
13805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->tx_user_target[i] = (u8) qdbm;
13815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->txpwroverride = false;
13835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->sh->up) {
13855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!SCAN_INPROG_PHY(pi)) {
13865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			bool suspend;
13875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13884b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			suspend = (0 == (bcma_read32(pi->d11core,
13894b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel						     D11REGOFFS(maccontrol)) &
13905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					 MCTL_EN_MAC));
13915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (!suspend)
13935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				wlapi_suspend_mac_and_wait(pi->sh->physhim);
13945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_txpower_recalc_target(pi);
13965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_cal_txpower_recalc_sw(pi);
13975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
13985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (!suspend)
13995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				wlapi_enable_mac(pi->sh->physhim);
14005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
14015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
14025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return 0;
14035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
14045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14055b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
14065b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr,
14075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			  u8 *max_pwr, int txp_rate_idx)
14085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
14095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
14105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint i;
14115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR;
14135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
14155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (txp_rate_idx < 0)
14165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			txp_rate_idx = TXP_FIRST_CCK;
14175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
14185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						   (u8) txp_rate_idx);
14195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if ((channel <= CH_MAX_2G_CHANNEL)) {
14215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (txp_rate_idx < 0)
14225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			txp_rate_idx = TXP_FIRST_CCK;
14235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
14245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
14255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		*max_pwr = BRCMS_TXPWR_MAX;
14275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (txp_rate_idx < 0)
14295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			txp_rate_idx = TXP_FIRST_OFDM;
14305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
14325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (channel == chan_info_all[i].chan)
14335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
14345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
14355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->hwtxpwr) {
14375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			*max_pwr = pi->hwtxpwr[i];
14385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
14395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
14415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				*max_pwr =
14425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
14435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if ((i >= FIRST_HIGH_5G_CHAN)
14445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			    && (i <= LAST_HIGH_5G_CHAN))
14455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				*max_pwr =
14465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
14475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
14485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				*max_pwr =
14495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    pi->tx_srom_max_rate_5g_low[txp_rate_idx];
14505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
14515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
14525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
14535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14545b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
14555b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
14565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				  u8 *max_txpwr, u8 *min_txpwr)
14575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
14585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
14595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 tx_pwr_max = 0;
14605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 tx_pwr_min = 255;
14615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 max_num_rate;
14625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 maxtxpwr, mintxpwr, rate, pactrl;
14635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pactrl = 0;
14655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
14675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		       ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 +
14685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				       1) : (TXP_LAST_OFDM + 1);
14695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (rate = 0; rate < max_num_rate; rate++) {
14715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
14735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					  rate);
14745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
14765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
14785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tx_pwr_max = max(tx_pwr_max, maxtxpwr);
14805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tx_pwr_min = min(tx_pwr_min, maxtxpwr);
14815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
14825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*max_txpwr = tx_pwr_max;
14835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*min_txpwr = tx_pwr_min;
14845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
14855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14865b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
14875b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit,
14885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				s32 *max_pwr, s32 *min_pwr, u32 *step_pwr)
14895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
14905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return;
14915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
14925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14935b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi)
14945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
14955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
14965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
14975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return pi->tx_power_min;
14985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
14995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15005b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi)
15015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
15025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
15035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return pi->tx_power_max;
15055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
15065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15075b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi)
15085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
15095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi))
15105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return wlc_lcnphy_vbatsense(pi, 0);
15115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
15125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return 0;
15135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
15145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15155b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi)
15165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
15175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi))
15185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return wlc_lcnphy_tempsense_degree(pi, 0);
15195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
15205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return 0;
15215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
15225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15235b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band)
15245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
15255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 i;
15265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s8 temp, vbat;
15275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < TXP_NUM_RATES; i++)
15295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
15305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	vbat = wlc_phy_env_measure_vbat(pi);
15325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	temp = wlc_phy_env_measure_temperature(pi);
15335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
15355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15365b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic s8
15375b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
15385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				 u8 rate)
15395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
15405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s8 offset = 0;
15415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->user_txpwr_at_rfport)
15435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return offset;
15445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return offset;
15455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
15465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15475b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
15485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
15495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 maxtxpwr, mintxpwr, rate, pactrl;
15505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint target_chan;
15515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 tx_pwr_target[TXP_NUM_RATES];
15525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 tx_pwr_max = 0;
15535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 tx_pwr_min = 255;
15545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 tx_pwr_max_rate_ind = 0;
15555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 max_num_rate;
15565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 start_rate = 0;
15575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 chspec;
15585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 band = CHSPEC2BAND(pi->radio_chanspec);
15595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	void (*txpwr_recalc_fn)(struct brcms_phy *) = NULL;
15605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	chspec = pi->radio_chanspec;
15625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
15635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		target_chan = CHSPEC_CHANNEL(chspec);
15645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
15655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		target_chan = upper_20_sb(CHSPEC_CHANNEL(chspec));
15665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
15675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		target_chan = lower_20_sb(CHSPEC_CHANNEL(chspec));
15685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pactrl = 0;
15705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
15715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u32 offset_mcs, i;
15725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (CHSPEC_IS40(pi->radio_chanspec)) {
15745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			offset_mcs = pi->mcs40_po;
15755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (i = TXP_FIRST_SISO_MCS_20;
15765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     i <= TXP_LAST_SISO_MCS_20; i++) {
15775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->tx_srom_max_rate_2g[i - 8] =
15785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					pi->tx_srom_max_2g -
15795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					((offset_mcs & 0xf) * 2);
15805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				offset_mcs >>= 4;
15815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
15825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
15835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			offset_mcs = pi->mcs20_po;
15845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (i = TXP_FIRST_SISO_MCS_20;
15855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     i <= TXP_LAST_SISO_MCS_20; i++) {
15865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->tx_srom_max_rate_2g[i - 8] =
15875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					pi->tx_srom_max_2g -
15885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					((offset_mcs & 0xf) * 2);
15895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				offset_mcs >>= 4;
15905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
15915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
15925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
15935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
15955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			((ISLCNPHY(pi)) ?
15965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
15975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
15985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_upd_env_txpwr_rate_limits(pi, band);
15995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (rate = start_rate; rate < max_num_rate; rate++) {
16015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tx_pwr_target[rate] = pi->tx_user_target[rate];
16035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->user_txpwr_at_rfport)
16055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			tx_pwr_target[rate] +=
16065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				wlc_user_txpwr_antport_to_rfport(pi,
16075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel								 target_chan,
16085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel								 band,
16095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel								 rate);
16105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_txpower_sromlimit((struct brcms_phy_pub *) pi,
16125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					  target_chan,
16135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					  &mintxpwr, &maxtxpwr, rate);
16145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
16165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
16185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
16205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
16225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->txpwr_percent <= 100)
16245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
16255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
16275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tx_pwr_target[rate] =
16295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
16305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (tx_pwr_target[rate] > tx_pwr_max)
16325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			tx_pwr_max_rate_ind = rate;
16335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
16355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
16365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
16375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
16395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->tx_power_max = tx_pwr_max;
16405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->tx_power_min = tx_pwr_min;
16415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
16425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (rate = 0; rate < max_num_rate; rate++) {
16435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->tx_power_target[rate] = tx_pwr_target[rate];
16455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!pi->hwpwrctrl || ISNPHY(pi))
16475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->tx_power_offset[rate] =
16485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->tx_power_max - pi->tx_power_target[rate];
16495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		else
16505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->tx_power_offset[rate] =
16515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->tx_power_target[rate] - pi->tx_power_min;
16525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
16535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
16555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (txpwr_recalc_fn)
16565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(*txpwr_recalc_fn)(pi);
16575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
16585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16595b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void
16605b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr,
16615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			       u16 chanspec)
16625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
16635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM];
16645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
16655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int rate_start_index = 0, rate1, rate2, k;
16665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
16685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	     rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
16695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_limit[rate1] = txpwr->cck[rate2];
16705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
16725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	     rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
16735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
16745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
16765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (k = 0; k < 4; k++) {
16785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			switch (k) {
16795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 0:
16805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_20_siso;
16825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->ofdm;
16835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_OFDM_FIRST;
16845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
16855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 1:
16865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_20_cdd;
16885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->ofdm_cdd;
16895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
16905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
16915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 2:
16925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
16935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_40_siso;
16945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->ofdm_40_siso;
16955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index =
16965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					WL_TX_POWER_OFDM40_SISO_FIRST;
16975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
16985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 3:
16995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_40_cdd;
17015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->ofdm_40_cdd;
17025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
17035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
17055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
17075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate2++) {
17085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				tmp_txpwr_limit[rate2] = 0;
17095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
17105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					txpwr_ptr1[rate2];
17115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
17125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_mcs_to_ofdm_powers_nphy(
17135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				tmp_txpwr_limit, 0,
17145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				BRCMS_NUM_RATES_OFDM -
17155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				1, BRCMS_NUM_RATES_OFDM);
17165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (rate1 = rate_start_index, rate2 = 0;
17175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++)
17185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->txpwr_limit[rate1] =
17195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					min(txpwr_ptr2[rate2],
17205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					    tmp_txpwr_limit[rate2]);
17215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
17225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (k = 0; k < 4; k++) {
17245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			switch (k) {
17255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 0:
17265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->ofdm;
17285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->mcs_20_siso;
17295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
17305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 1:
17325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->ofdm_cdd;
17345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->mcs_20_cdd;
17355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
17365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 2:
17385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->ofdm_40_siso;
17405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->mcs_40_siso;
17415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
17425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 3:
17445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->ofdm_40_cdd;
17465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr2 = txpwr->mcs_40_cdd;
17475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
17485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
17505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
17515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate2++) {
17525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				tmp_txpwr_limit[rate2] = 0;
17535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
17545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					txpwr_ptr1[rate2];
17555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
17565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_ofdm_to_mcs_powers_nphy(
17575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				tmp_txpwr_limit, 0,
17585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				BRCMS_NUM_RATES_OFDM -
17595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				1, BRCMS_NUM_RATES_OFDM);
17605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (rate1 = rate_start_index, rate2 = 0;
17615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
17625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate1++, rate2++)
17635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->txpwr_limit[rate1] =
17645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					min(txpwr_ptr2[rate2],
17655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					    tmp_txpwr_limit[rate2]);
17665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
17675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (k = 0; k < 2; k++) {
17695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			switch (k) {
17705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 0:
17715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
17735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_20_stbc;
17745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 1:
17765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
17785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_40_stbc;
17795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
17815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (rate1 = rate_start_index, rate2 = 0;
17825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
17835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate1++, rate2++)
17845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
17855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
17865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (k = 0; k < 2; k++) {
17885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			switch (k) {
17895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 0:
17905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
17925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_20_mimo;
17935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			case 1:
17955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
17965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
17975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				txpwr_ptr1 = txpwr->mcs_40_mimo;
17985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				break;
17995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
18005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (rate1 = rate_start_index, rate2 = 0;
18015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate2 < BRCMS_NUM_RATES_MCS_2_STREAM;
18025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     rate1++, rate2++)
18035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
18045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
18055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
18075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
18095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
18105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			    pi->txpwr_limit[WL_TX_POWER_MCS_32]);
18115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->txpwr_limit[WL_TX_POWER_MCS_32] =
18125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
18135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
18145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
18155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18165b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent)
18175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
18185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
18195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->txpwr_percent = txpwr_percent;
18215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
18225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18235b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap)
18245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
18255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
18265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->machwcap = machwcap;
18285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
18295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18305b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
18315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
18325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
18335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 rxc;
18345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	rxc = 0;
18355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (start_end == ON) {
18375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!ISNPHY(pi))
18385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			return;
18395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (NREV_IS(pi->pubpi.phy_rev, 3)
18415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
18424b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
18434b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel				      0xa0);
18444b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			bcma_set16(pi->d11core, D11REGOFFS(phyregdata),
18454b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel				   0x1 << 15);
18465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
18475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
18485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (NREV_IS(pi->pubpi.phy_rev, 3)
18495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
18504b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
18514b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel				      0xa0);
18524b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			bcma_write16(pi->d11core, D11REGOFFS(phyregdata), rxc);
18535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
18545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_por_inform(ppi);
18565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
18575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
18585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18595b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
18605b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
18615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			  u16 chanspec)
18625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
18635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
18645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
18665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
18685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		int i, j;
18695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
18705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		     j < BRCMS_NUM_RATES_MCS_1_STREAM; i++, j++) {
18715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (txpwr->mcs_20_siso[j])
18725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
18735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			else
18745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->txpwr_limit[i] = txpwr->ofdm[j];
18755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
18765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
18775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_suspend_mac_and_wait(pi->sh->physhim);
18795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_txpower_recalc_target(pi);
18815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_cal_txpower_recalc_sw(pi);
18825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlapi_enable_mac(pi->sh->physhim);
18835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
18845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18855b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war)
18865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
18875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
18885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->ofdm_rateset_war = war;
18905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
18915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18925b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt)
18935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
18945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
18955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->bf_preempt_4306 = bf_preempt;
18975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
18985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
18995b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_txpower_update_shm(struct brcms_phy *pi)
19005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
19015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int j;
19025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi))
19035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
19045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->sh->clk)
19065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
19075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->hwpwrctrl) {
19095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u16 offset;
19105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
19125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
19135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				     1 << NUM_TSSI_FRAMES);
19145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
19165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				     pi->tx_power_min << NUM_TSSI_FRAMES);
19175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
19195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				     pi->hwpwr_txcur);
19205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
19225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			const u8 ucode_ofdm_rates[] = {
19235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
19245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			};
19255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			offset = wlapi_bmac_rate_shm_offset(
19265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->sh->physhim,
19275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				ucode_ofdm_rates[j - TXP_FIRST_OFDM]);
19285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
19295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					     pi->tx_power_offset[j]);
19305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
19315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					     -(pi->tx_power_offset[j] / 2));
19325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
19335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
19355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			       MHF2_HWPWRCTL, BRCM_BAND_ALL);
19365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
19375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		int i;
19385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
19405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->tx_power_offset[i] =
19415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				(u8) roundup(pi->tx_power_offset[i], 8);
19425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
19435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				     (u16)
19445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				     ((pi->tx_power_offset[TXP_FIRST_OFDM]
19455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				       + 7) >> 3));
19465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
19475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
19485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19495b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
19505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
19515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
19525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi))
19545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return pi->nphy_txpwrctrl;
19555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
19565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return pi->hwpwrctrl;
19575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
19585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19595b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
19605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
19615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
19625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	bool suspend;
19635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->hwpwrctrl_capable)
19655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
19665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->hwpwrctrl = hwpwrctrl;
19685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_txpwrctrl = hwpwrctrl;
19695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->txpwrctrl = hwpwrctrl;
19705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
19724b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel		suspend = (0 == (bcma_read32(pi->d11core,
19734b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel					     D11REGOFFS(maccontrol)) &
19744b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel				 MCTL_EN_MAC));
19755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!suspend)
19765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_suspend_mac_and_wait(pi->sh->physhim);
19775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
19795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
19805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_txpwr_fixpower_nphy(pi);
19815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		else
19825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			mod_phy_reg(pi, 0x1e7, (0x7f << 0),
19835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    pi->saved_txpwr_idx);
19845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!suspend)
19865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_enable_mac(pi->sh->physhim);
19875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
19885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
19895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19905b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_txpower_ipa_upd(struct brcms_phy *pi)
19915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
19925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
19935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
19955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
19965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else {
19975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->ipa2g_on = false;
19985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->ipa5g_on = false;
19995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
20005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
20015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20025b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi)
20035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
20045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s16 tx0_status, tx1_status;
20055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 estPower1, estPower2;
20065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
20075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 est_pwr;
20085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	estPower1 = read_phy_reg(pi, 0x118);
20105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	estPower2 = read_phy_reg(pi, 0x119);
20115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((estPower1 & (0x1 << 8)) == (0x1 << 8))
20135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pwr0 = (u8) (estPower1 & (0xff << 0)) >> 0;
20145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
20155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pwr0 = 0x80;
20165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((estPower2 & (0x1 << 8)) == (0x1 << 8))
20185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pwr1 = (u8) (estPower2 & (0xff << 0)) >> 0;
20195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
20205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pwr1 = 0x80;
20215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	tx0_status = read_phy_reg(pi, 0x1ed);
20235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	tx1_status = read_phy_reg(pi, 0x1ee);
20245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((tx0_status & (0x1 << 15)) == (0x1 << 15))
20265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		adj_pwr0 = (u8) (tx0_status & (0xff << 0)) >> 0;
20275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
20285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		adj_pwr0 = 0x80;
20295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((tx1_status & (0x1 << 15)) == (0x1 << 15))
20305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		adj_pwr1 = (u8) (tx1_status & (0xff << 0)) >> 0;
20315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
20325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		adj_pwr1 = 0x80;
20335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	est_pwr = (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) |
20355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			 adj_pwr1);
20365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return est_pwr;
20385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
20395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20405b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
20415b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
20425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			    uint channel)
20435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
20445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
20455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint rate, num_rates;
20465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 min_pwr, max_pwr;
20475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#if WL_TX_POWER_RATES != TXP_NUM_RATES
20495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#error "struct tx_power out of sync with this fn"
20505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#endif
20515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
20535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->rf_cores = 2;
20545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->flags |= (WL_TX_POWER_F_MIMO);
20555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
20565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->flags |=
20575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				(WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
20585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (ISLCNPHY(pi)) {
20595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->rf_cores = 1;
20605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->flags |= (WL_TX_POWER_F_SISO);
20615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
20625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->flags |= WL_TX_POWER_F_ENABLED;
20635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->hwpwrctrl)
20645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->flags |= WL_TX_POWER_F_HW;
20655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
20665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
20685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		     ((ISLCNPHY(pi)) ?
20695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		      (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
20705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (rate = 0; rate < num_rates; rate++) {
20725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->user_limit[rate] = pi->tx_user_target[rate];
20735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
20745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					  rate);
20755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->board_limit[rate] = (u8) max_pwr;
20765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->target[rate] = pi->tx_power_target[rate];
20775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
20785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi)) {
20805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u32 est_pout;
20815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_suspend_mac_and_wait(pi->sh->physhim);
20835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phyreg_enter((struct brcms_phy_pub *) pi);
20845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		est_pout = wlc_phy_txpower_est_power_nphy(pi);
20855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phyreg_exit((struct brcms_phy_pub *) pi);
20865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_enable_mac(pi->sh->physhim);
20875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->est_Pout[0] = (est_pout >> 8) & 0xff;
20895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->est_Pout[1] = est_pout & 0xff;
20905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->est_Pout_act[0] = est_pout >> 24;
20925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
20935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (power->est_Pout[0] == 0x80)
20955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->est_Pout[0] = 0;
20965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (power->est_Pout[1] == 0x80)
20975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->est_Pout[1] = 0;
20985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
20995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (power->est_Pout_act[0] == 0x80)
21005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->est_Pout_act[0] = 0;
21015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (power->est_Pout_act[1] == 0x80)
21025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->est_Pout_act[1] = 0;
21035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->est_Pout_cck = 0;
21055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->tx_power_max[0] = pi->tx_power_max;
21075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->tx_power_max[1] = pi->tx_power_max;
21085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
21105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
21115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (pi->hwpwrctrl && pi->sh->up) {
21125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phyreg_enter(ppi);
21145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (ISLCNPHY(pi)) {
21155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->tx_power_max[0] = pi->tx_power_max;
21175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->tx_power_max[1] = pi->tx_power_max;
21185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->tx_power_max_rate_ind[0] =
21205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->tx_power_max_rate_ind;
21215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			power->tx_power_max_rate_ind[1] =
21225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->tx_power_max_rate_ind;
21235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (wlc_phy_tpc_isenabled_lcnphy(pi))
21255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				power->flags |=
21265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					(WL_TX_POWER_F_HW |
21275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					 WL_TX_POWER_F_ENABLED);
21285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			else
21295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				power->flags &=
21305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					~(WL_TX_POWER_F_HW |
21315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					  WL_TX_POWER_F_ENABLED);
21325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
21345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					    (s8 *) &power->est_Pout_cck);
21355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
21365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phyreg_exit(ppi);
21375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
21385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
21395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21405b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type)
21415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
21425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
21435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->antsel_type = antsel_type;
21455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
21465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21475b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbool wlc_phy_test_ison(struct brcms_phy_pub *ppi)
21485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
21495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
21505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return pi->phytest_on;
21525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
21535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21545b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
21555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
21565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
21575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	bool suspend;
21585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->rx_antdiv = val;
21605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
21625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (val > ANT_RX_DIV_FORCE_1)
21635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
21645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				       MHF1_ANTDIV, BRCM_BAND_ALL);
21655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		else
21665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
21675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				       BRCM_BAND_ALL);
21685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
21695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi))
21715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
21725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->sh->clk)
21745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
21755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21764b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
21774b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			 MCTL_EN_MAC));
21785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!suspend)
21795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_suspend_mac_and_wait(pi->sh->physhim);
21805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
21825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (val > ANT_RX_DIV_FORCE_1) {
21835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
21845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			mod_phy_reg(pi, 0x410,
21855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    (0x1 << 0),
21865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				    ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
21875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
21885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
21895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
21905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
21915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
21925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!suspend)
21945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_enable_mac(pi->sh->physhim);
21955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return;
21975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
21985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
21995b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool
22005b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant)
22015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
22025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s8 cmplx_pwr_dbm[PHY_CORE_MAX];
22035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 i;
22045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
22065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
22075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
22095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (NREV_GE(pi->pubpi.phy_rev, 3))
22105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
22115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		else
22125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
22145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
22155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
22175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
22185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pwr_ant[i] = cmplx_pwr_dbm[i];
22195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
22205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_noise_index =
22215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
22225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return true;
22235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
22245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22255b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm)
22265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
22275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->phynoise_state)
22285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
22295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
22315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->phynoise_chan_watchdog == channel) {
22325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
22335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				noise_dbm;
22345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->sh->phy_noise_index =
22355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
22365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
22375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
22385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
22395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL)
22415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
22425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
22445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22455b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi)
22465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
22475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 cmplx_pwr[PHY_CORE_MAX];
22485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s8 noise_dbm_ant[PHY_CORE_MAX];
22495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 lo, hi;
22505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 cmplx_pwr_tot = 0;
22515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
22525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 idx, core;
22535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
22555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
22565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2,
22585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	     core++) {
22595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
22605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		hi = wlapi_bmac_read_shm(pi->sh->physhim,
22615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					 M_PWRIND_MAP(idx + 1));
22625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		cmplx_pwr[core] = (hi << 16) + lo;
22635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		cmplx_pwr_tot += cmplx_pwr[core];
22645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (cmplx_pwr[core] == 0)
22655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
22665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		else
22675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
22685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
22695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (cmplx_pwr_tot != 0)
22715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
22725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
22745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->nphy_noise_win[core][pi->nphy_noise_index] =
22755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm_ant[core];
22765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (noise_dbm_ant[core] > noise_dbm)
22785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm = noise_dbm_ant[core];
22795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
22805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_noise_index =
22815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
22825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return noise_dbm;
22845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
22865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22875b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
22885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
22895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
22905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u16 jssi_aux;
22915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 channel = 0;
22925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
22935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
22945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
22955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
22965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u16 lo, hi;
22975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		s32 pwr_offset_dB, gain_dB;
22985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u16 status_0, status_1;
22995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
23015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		channel = jssi_aux & D11_CURCHANNEL_MAX;
23025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
23045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
23055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		cmplx_pwr0 = (hi << 16) + lo;
23065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
23085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
23095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		cmplx_pwr1 = (hi << 16) + lo;
23105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
23115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		status_0 = 0x44;
23135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
23145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((cmplx_pwr > 0 && cmplx_pwr < 500)
23155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    && ((status_1 & 0xc000) == 0x4000)) {
23165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
23185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					   pi->pubpi.phy_corenum);
23195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
23205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (pwr_offset_dB > 127)
23215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pwr_offset_dB -= 256;
23225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm += (s8) (pwr_offset_dB - 30);
23245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			gain_dB = (status_0 & 0x1ff);
23265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm -= (s8) (gain_dB);
23275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
23285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
23295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
23305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (ISNPHY(pi)) {
23315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
23335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		channel = jssi_aux & D11_CURCHANNEL_MAX;
23345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		noise_dbm = wlc_phy_noise_read_shmem(pi);
23365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
23375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_noise_cb(pi, channel, noise_dbm);
23395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
23415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23425b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void
23435b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
23445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
23455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
23465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
23475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	bool sampling_in_progress = (pi->phynoise_state != 0);
23485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	bool wait_for_intr = true;
23495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	switch (reason) {
23515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_NOISE_SAMPLE_MON:
23525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phynoise_chan_watchdog = ch;
23535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phynoise_state |= PHY_NOISE_STATE_MON;
23545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
23555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_NOISE_SAMPLE_EXTERNAL:
23575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
23585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
23595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	default:
23615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
23625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
23635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (sampling_in_progress)
23655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
23665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->phynoise_now = pi->sh->now;
23685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->phy_fixed_noise) {
23705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (ISNPHY(pi)) {
23715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
23725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				PHY_NOISE_FIXED_VAL_NPHY;
23735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
23745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				PHY_NOISE_FIXED_VAL_NPHY;
23755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
23765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel							   PHY_NOISE_WINDOW_SZ);
23775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
23785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
23795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm = PHY_NOISE_FIXED_VAL;
23805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
23815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wait_for_intr = false;
23835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		goto done;
23845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
23855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
23875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!pi->phynoise_polling
23885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
23895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
23905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
23915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
23925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
23935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
23945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
23954b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
23964b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel				   MCMD_BG_NOISE);
23975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
23985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_suspend_mac_and_wait(pi->sh->physhim);
23995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_lcnphy_deaf_mode(pi, (bool) 0);
24005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
24015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_lcnphy_deaf_mode(pi, (bool) 1);
24025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_enable_mac(pi->sh->physhim);
24035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wait_for_intr = false;
24045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
24055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (ISNPHY(pi)) {
24065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!pi->phynoise_polling
24075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
24085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
24105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
24115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
24125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
24135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24144b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
24154b006b11ca18995677c5f1cd03cc9c42fbe80693Arend van Spriel				   MCMD_BG_NOISE);
24165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
24175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			struct phy_iq_est est[PHY_CORE_MAX];
24185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			u32 cmplx_pwr[PHY_CORE_MAX];
24195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			s8 noise_dbm_ant[PHY_CORE_MAX];
24205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			u16 log_num_samps, num_samps, classif_state = 0;
24215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			u8 wait_time = 32;
24225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			u8 wait_crs = 0;
24235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			u8 i;
24245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			memset((u8 *) est, 0, sizeof(est));
24265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
24275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
24285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
24305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			num_samps = 1 << log_num_samps;
24315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_suspend_mac_and_wait(pi->sh->physhim);
24335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
24345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_classifier_nphy(pi, 3, 0);
24355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
24365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					       wait_crs);
24375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
24385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlapi_enable_mac(pi->sh->physhim);
24395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (i = 0; i < pi->pubpi.phy_corenum; i++)
24415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				cmplx_pwr[i] = (est[i].i_pwr + est[i].q_pwr) >>
24425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					       log_num_samps;
24435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
24455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			for (i = 0; i < pi->pubpi.phy_corenum; i++) {
24475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->nphy_noise_win[i][pi->nphy_noise_index] =
24485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					noise_dbm_ant[i];
24495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				if (noise_dbm_ant[i] > noise_dbm)
24515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					noise_dbm = noise_dbm_ant[i];
24525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
24535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
24545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel							   PHY_NOISE_WINDOW_SZ);
24555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wait_for_intr = false;
24575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
24585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
24595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24605b435de0d786869c95d1962121af0d7df2542009Arend van Sprieldone:
24615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!wait_for_intr)
24635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_noise_cb(pi, ch, noise_dbm);
24645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
24665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24675b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih)
24685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
24695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 channel;
24705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
24725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
24745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
24755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
24765b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
24775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	9,
24855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	10,
24865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	8,
24885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	7,
24895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	7,
24905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	1,
24915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
24995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	2,
25095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	1,
25105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	1,
25115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	0,
25125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	0,
25135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	0,
25145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	0
25155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel};
25165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25175b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
25185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
25195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 msb, secondmsb, i;
25205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u32 tmp;
25215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < core; i++) {
25235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		secondmsb = 0;
25245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		tmp = cmplx_pwr[i];
25255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		msb = fls(tmp);
25265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (msb)
25275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
25285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
25295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
25305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
25315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25325b435de0d786869c95d1962121af0d7df2542009Arend van Sprielint wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
25335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			 struct d11rxhdr *rxh)
25345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
25355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK;
25365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint radioid = pih->radioid;
25375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
25385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((pi->sh->corerev >= 11)
25405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) {
25415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		rssi = BRCMS_RSSI_INVALID;
25425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		goto end;
25435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
25445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
25465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		u8 gidx = (rxh->PhyRxStatus_2 & 0xFC00) >> 10;
25475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
25485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (rssi > 127)
25505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			rssi -= 256;
25515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
25535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((rssi > -46) && (gidx > 18))
25545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			rssi = rssi + 7;
25555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
25575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		rssi = rssi + 2;
25595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
25615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
25635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (rssi > 127)
25645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			rssi -= 256;
25655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	} else if (radioid == BCM2055_ID || radioid == BCM2056_ID
25665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		   || radioid == BCM2057_ID) {
25675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		rssi = wlc_phy_rssi_compute_nphy(pi, rxh);
25685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
25695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25705b435de0d786869c95d1962121af0d7df2542009Arend van Sprielend:
25715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return rssi;
25725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
25735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25745b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_freqtrack_start(struct brcms_phy_pub *pih)
25755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
25765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return;
25775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
25785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25795b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_freqtrack_end(struct brcms_phy_pub *pih)
25805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
25815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return;
25825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
25835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25845b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag)
25855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
25865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi;
25875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi = (struct brcms_phy *) ppi;
25885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi))
25905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_lcnphy_deaf_mode(pi, true);
25915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else if (ISNPHY(pi))
25925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_nphy_deaf_mode(pi, true);
25935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
25945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
25955b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_watchdog(struct brcms_phy_pub *pih)
25965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
25975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
25985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	bool delay_phy_cal = false;
25995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->now++;
26005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->watchdog_override)
26025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
26035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)))
26055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi,
26065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					     PHY_NOISE_SAMPLE_MON,
26075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					     CHSPEC_CHANNEL(pi->
26085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel							    radio_chanspec));
26095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5)
26115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->phynoise_state = 0;
26125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((!pi->phycal_txpower) ||
26145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
26155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi))
26175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->phycal_txpower = pi->sh->now;
26185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
26195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
26215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	     || ASSOC_INPROG_PHY(pi)))
26225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
26235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
26255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
26275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
26285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    ((pi->sh->now - pi->nphy_perical_last) >=
26295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		     pi->sh->glacial_timer))
26305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
26315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					    PHY_PERICAL_WATCHDOG);
26325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_txpwr_papd_cal_nphy(pi);
26345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
26355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
26375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->phy_forcecal ||
26385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    ((pi->sh->now - pi->phy_lastcal) >=
26395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		     pi->sh->glacial_timer)) {
26405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
26415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				wlc_lcnphy_calib_modes(
26425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					pi,
26435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
26445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (!
26455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			    (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
26465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     || ASSOC_INPROG_PHY(pi)
26475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     || pi->carrier_suppr_disable
26485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     || pi->disable_percal))
26495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				wlc_lcnphy_calib_modes(pi,
26505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						       PHY_PERICAL_WATCHDOG);
26515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
26525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
26535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
26545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26555b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi)
26565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
26575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
26585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint i;
26595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	uint k;
26605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < MA_WINDOW_SZ; i++)
26625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
26635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISLCNPHY(pi)) {
26645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (i = 0; i < MA_WINDOW_SZ; i++)
26655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->sh->phy_noise_window[i] =
26665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				PHY_NOISE_FIXED_VAL_LCNPHY;
26675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
26685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->phy_noise_index = 0;
26695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
26715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
26725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
26735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
26745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->nphy_noise_index = 0;
26755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
26765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26775b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
26785b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
26795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
26805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*eps_imag = (epsilon >> 13);
26815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (*eps_imag > 0xfff)
26825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		*eps_imag -= 0x2000;
26835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*eps_real = (epsilon & 0x1fff);
26855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (*eps_real > 0xfff)
26865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		*eps_real -= 0x2000;
26875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
26885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26895b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi)
26905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
2691be69c4ef462a476523f89c74e7db29f6ad207a1aRoland Vossen	wlapi_del_timer(pi->phycal_timer);
26925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->cal_type_override = PHY_PERICAL_AUTO;
26945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
26955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->mphase_txcal_cmdidx = 0;
26965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
26975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
26985b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void
26995b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay)
27005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
27015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
27035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (pi->nphy_perical != PHY_PERICAL_MANUAL))
27045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
27055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
2706be69c4ef462a476523f89c74e7db29f6ad207a1aRoland Vossen	wlapi_del_timer(pi->phycal_timer);
27075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
2709be69c4ef462a476523f89c74e7db29f6ad207a1aRoland Vossen	wlapi_add_timer(pi->phycal_timer, delay, 0);
27105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
27115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27125b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
27135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
27145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s16 nphy_currtemp = 0;
27155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s16 delta_temp = 0;
27165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	bool do_periodic_cal = true;
27175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
27185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!ISNPHY(pi))
27205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
27215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
27235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (pi->nphy_perical == PHY_PERICAL_MANUAL))
27245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return;
27255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	switch (reason) {
27275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_PERICAL_DRIVERUP:
27285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
27295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_PERICAL_PHYINIT:
27315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
27325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (PHY_PERICAL_MPHASE_PENDING(pi))
27335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				wlc_phy_cal_perical_mphase_reset(pi);
27345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_cal_perical_mphase_schedule(
27365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi,
27375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				PHY_PERICAL_INIT_DELAY);
27385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
27395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
27405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_PERICAL_JOIN_BSS:
27425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_PERICAL_START_IBSS:
27435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_PERICAL_UP_BSS:
27445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
27455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		    PHY_PERICAL_MPHASE_PENDING(pi))
27465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			wlc_phy_cal_perical_mphase_reset(pi);
27475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->first_cal_after_assoc = true;
27495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		pi->cal_type_override = PHY_PERICAL_FULL;
27515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->phycal_tempdelta)
27535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
27545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
27565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
27575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	case PHY_PERICAL_WATCHDOG:
27595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (pi->phycal_tempdelta) {
27605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			nphy_currtemp = wlc_phy_tempsense_nphy(pi);
27615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			delta_temp =
27625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				(nphy_currtemp > pi->nphy_lastcal_temp) ?
27635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				nphy_currtemp - pi->nphy_lastcal_temp :
27645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->nphy_lastcal_temp - nphy_currtemp;
27655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if ((delta_temp < (s16) pi->phycal_tempdelta) &&
27675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			    (pi->nphy_txiqlocal_chanspec ==
27685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			     pi->radio_chanspec))
27695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				do_periodic_cal = false;
27705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			else
27715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->nphy_lastcal_temp = nphy_currtemp;
27725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
27735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (do_periodic_cal) {
27755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
27765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				if (!PHY_PERICAL_MPHASE_PENDING(pi))
27775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel					wlc_phy_cal_perical_mphase_schedule(
27785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						pi,
27795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel						PHY_PERICAL_WDOG_DELAY);
27805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			} else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
27815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				wlc_phy_cal_perical_nphy_run(pi,
27825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel							     PHY_PERICAL_AUTO);
27835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
27845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
27855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	default:
27865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		break;
27875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
27885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
27895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27905b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi)
27915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
27925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
27935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->mphase_txcal_cmdidx = 0;
27945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
27955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
27965b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu8 wlc_phy_nbits(s32 value)
27975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
27985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s32 abs_val;
27995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 nbits = 0;
28005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	abs_val = abs(value);
28025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	while ((abs_val >> nbits) > 0)
28035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		nbits++;
28045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return nbits;
28065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
28075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28085b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
28095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
28105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
28115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->hw_phytxchain = txchain;
28135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->hw_phyrxchain = rxchain;
28145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->phytxchain = txchain;
28155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->phyrxchain = rxchain;
28165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
28175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
28185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28195b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
28205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
28215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
28225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->sh->phytxchain = txchain;
28245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi))
28265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlc_phy_rxcore_setstate_nphy(pih, rxchain);
28275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
28295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
28305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28315b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain)
28325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
28335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
28345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*txchain = pi->sh->phytxchain;
28365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*rxchain = pi->sh->phyrxchain;
28375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
28385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28395b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
28405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
28415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	s16 nphy_currtemp;
28425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 active_bitmap;
28435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
28445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
28465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (!pi->watchdog_override)
28485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return active_bitmap;
28495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
28515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_suspend_mac_and_wait(pi->sh->physhim);
28525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		nphy_currtemp = wlc_phy_tempsense_nphy(pi);
28535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		wlapi_enable_mac(pi->sh->physhim);
28545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (!pi->phy_txcore_heatedup) {
28565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
28575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				active_bitmap &= 0xFD;
28585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->phy_txcore_heatedup = true;
28595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
28605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
28615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
28625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				active_bitmap |= 0x2;
28635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				pi->phy_txcore_heatedup = false;
28645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
28655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
28665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
28675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return active_bitmap;
28695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
28705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28715b435de0d786869c95d1962121af0d7df2542009Arend van Spriels8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec)
28725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
28735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) pih;
28745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	u8 siso_mcs_id, cdd_mcs_id;
28755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	siso_mcs_id =
28775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
28785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		TXP_FIRST_MCS_20_SISO;
28795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	cdd_mcs_id =
28805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
28815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		TXP_FIRST_MCS_20_CDD;
28825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (pi->tx_power_target[siso_mcs_id] >
28845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (pi->tx_power_target[cdd_mcs_id] + 12))
28855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return PHY_TXC1_MODE_SISO;
28865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
28875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return PHY_TXC1_MODE_CDD;
28885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
28895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28905b435de0d786869c95d1962121af0d7df2542009Arend van Sprielconst u8 *wlc_phy_get_ofdm_rate_lookup(void)
28915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
28925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return ofdm_rate_lookup;
28935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
28945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
28955b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
28965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
28975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if ((pi->sh->chip == BCM4313_CHIP_ID) &&
28985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	    (pi->sh->boardflags & BFL_FEM)) {
28995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		if (mode) {
29005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			u16 txant = 0;
29015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			txant = wlapi_bmac_get_txant(pi->sh->physhim);
29025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			if (txant == 1) {
29035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
29045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel				mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
29065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			}
29087d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel			ai_cc_reg(pi->sh->sih,
29097d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  offsetof(struct chipcregs, gpiocontrol),
29107d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  ~0x0, 0x0);
29117d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel			ai_cc_reg(pi->sh->sih,
29127d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  offsetof(struct chipcregs, gpioout),
29137d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  0x40, 0x40);
29147d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel			ai_cc_reg(pi->sh->sih,
29157d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  offsetof(struct chipcregs, gpioouten),
29167d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  0x40, 0x40);
29175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		} else {
29185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
29195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel			mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
29215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29227d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel			ai_cc_reg(pi->sh->sih,
29237d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  offsetof(struct chipcregs, gpioout),
29247d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  0x40, 0x00);
29257d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel			ai_cc_reg(pi->sh->sih,
29267d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  offsetof(struct chipcregs, gpioouten),
29277d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  0x40, 0x0);
29287d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel			ai_cc_reg(pi->sh->sih,
29297d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  offsetof(struct chipcregs, gpiocontrol),
29307d8e18e456466c2247abe0658e4add598f85c98eArend van Spriel				  ~0x0, 0x40);
29315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		}
29325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	}
29335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
29345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29355b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc)
29365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
29375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return;
29385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
29395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29405b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid
29415b435de0d786869c95d1962121af0d7df2542009Arend van Sprielwlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset)
29425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
29435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*cckoffset = 0;
29445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	*ofdmoffset = 0;
29455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
29465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29475b435de0d786869c95d1962121af0d7df2542009Arend van Spriels8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec)
29485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
29495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	return rssi;
29515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
29525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29535b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi)
29545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{
29555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	struct brcms_phy *pi = (struct brcms_phy *) ppi;
29565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel
29575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	if (ISNPHY(pi))
29585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return wlc_phy_n_txpower_ipa_ison(pi);
29595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel	else
29605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel		return 0;
29615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}
2962