Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2aa8eec authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'wireless'



John W. Linville says:

====================
Please excuse this larger-than-I-would-like pull request intended
for the 3.9 stream.  There are a number of late-breaking fixes,
including a revert...

Regarding the mac80211 bits, Johannes says:

"I have two tracing fixes (one from Vladimir), two fixes for P2P device
crashes, a fix for a BSS memory leak/lost update problem and a fix from
Ben for a scanning issue in mac80211. It's a little on the large side
because one of the P2P device problems required a bit much locking work,
but I've run through all the different scenarios (wext/nl80211,
p2p-device/station interface, ifdown/rfkill) to verify locking with
lockdep."

As for the iwlwifi bits, Johannes says:

"I have three little fixes to the driver from Emmanuel. One addresses a
small bug Ben Hutchings found during the stable review process and two
address some warnings in the driver when RF-Kill is asserted."

Along with those...

Avinash Patil fixes an mwifiex bug cause by failing to process a sleep
command due to bad SKB manipulation when going into power saving mode.

Colin Ian King avoids a null pointer dereference in iwl4965.

Dan Williams officially announces that he has dropped maintainership
of the libertas driver.

Iestyn C. Elfick adds a work-around to avoid b43 DMA transmision
sequence error that would lead to a device reset.

Luis R. Rodriguez avoids an ath9k warning by not queueing a work item
while going to suspend mode.

Rafał Miłecki provides a pair of b43 N-PHY fixes related to RSSI
calibration.

Finally, I revert "brcmsmac: support 4313iPA" because it has been
reported in many places to cause problems with the already supported
4313ePA devices.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 91c57464 630a216d
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -5059,9 +5059,8 @@ S: Maintained
F:	drivers/net/ethernet/marvell/sk*
F:	drivers/net/ethernet/marvell/sk*


MARVELL LIBERTAS WIRELESS DRIVER
MARVELL LIBERTAS WIRELESS DRIVER
M:	Dan Williams <dcbw@redhat.com>
L:	libertas-dev@lists.infradead.org
L:	libertas-dev@lists.infradead.org
S:	Maintained
S:	Orphan
F:	drivers/net/wireless/libertas/
F:	drivers/net/wireless/libertas/


MARVELL MV643XX ETHERNET DRIVER
MARVELL MV643XX ETHERNET DRIVER
+2 −1
Original line number Original line Diff line number Diff line
@@ -170,6 +170,7 @@ void ath_rx_poll(unsigned long data)
{
{
	struct ath_softc *sc = (struct ath_softc *)data;
	struct ath_softc *sc = (struct ath_softc *)data;


	if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
		ieee80211_queue_work(sc->hw, &sc->hw_check_work);
		ieee80211_queue_work(sc->hw, &sc->hw_check_work);
}
}


+53 −12
Original line number Original line Diff line number Diff line
@@ -1487,8 +1487,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
	const struct b43_dma_ops *ops;
	const struct b43_dma_ops *ops;
	struct b43_dmaring *ring;
	struct b43_dmaring *ring;
	struct b43_dmadesc_meta *meta;
	struct b43_dmadesc_meta *meta;
	static const struct b43_txstatus fake; /* filled with 0 */
	const struct b43_txstatus *txstat;
	int slot, firstused;
	int slot, firstused;
	bool frame_succeed;
	bool frame_succeed;
	int skip;
	static u8 err_out1, err_out2;


	ring = parse_cookie(dev, status->cookie, &slot);
	ring = parse_cookie(dev, status->cookie, &slot);
	if (unlikely(!ring))
	if (unlikely(!ring))
@@ -1501,14 +1505,37 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
	firstused = ring->current_slot - ring->used_slots + 1;
	firstused = ring->current_slot - ring->used_slots + 1;
	if (firstused < 0)
	if (firstused < 0)
		firstused = ring->nr_slots + firstused;
		firstused = ring->nr_slots + firstused;

	skip = 0;
	if (unlikely(slot != firstused)) {
	if (unlikely(slot != firstused)) {
		/* This possibly is a firmware bug and will result in
		/* This possibly is a firmware bug and will result in
		 * malfunction, memory leaks and/or stall of DMA functionality. */
		 * malfunction, memory leaks and/or stall of DMA functionality.
		b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. "
		 */
		       "Expected %d, but got %d\n",
		if (slot == next_slot(ring, next_slot(ring, firstused))) {
			/* If a single header/data pair was missed, skip over
			 * the first two slots in an attempt to recover.
			 */
			slot = firstused;
			skip = 2;
			if (!err_out1) {
				/* Report the error once. */
				b43dbg(dev->wl,
				       "Skip on DMA ring %d slot %d.\n",
				       ring->index, slot);
				err_out1 = 1;
			}
		} else {
			/* More than a single header/data pair were missed.
			 * Report this error once.
			 */
			if (!err_out2)
				b43dbg(dev->wl,
				       "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n",
				       ring->index, firstused, slot);
				       ring->index, firstused, slot);
			err_out2 = 1;
			return;
			return;
		}
		}
	}


	ops = ring->ops;
	ops = ring->ops;
	while (1) {
	while (1) {
@@ -1522,11 +1549,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
			       slot, firstused, ring->index);
			       slot, firstused, ring->index);
			break;
			break;
		}
		}

		if (meta->skb) {
		if (meta->skb) {
			struct b43_private_tx_info *priv_info =
			struct b43_private_tx_info *priv_info =
			     b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
			     b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));


			unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
			unmap_descbuffer(ring, meta->dmaaddr,
					 meta->skb->len, 1);
			kfree(priv_info->bouncebuffer);
			kfree(priv_info->bouncebuffer);
			priv_info->bouncebuffer = NULL;
			priv_info->bouncebuffer = NULL;
		} else {
		} else {
@@ -1538,8 +1567,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
			struct ieee80211_tx_info *info;
			struct ieee80211_tx_info *info;


			if (unlikely(!meta->skb)) {
			if (unlikely(!meta->skb)) {
				/* This is a scatter-gather fragment of a frame, so
				/* This is a scatter-gather fragment of a frame,
				 * the skb pointer must not be NULL. */
				 * so the skb pointer must not be NULL.
				 */
				b43dbg(dev->wl, "TX status unexpected NULL skb "
				b43dbg(dev->wl, "TX status unexpected NULL skb "
				       "at slot %d (first=%d) on ring %d\n",
				       "at slot %d (first=%d) on ring %d\n",
				       slot, firstused, ring->index);
				       slot, firstused, ring->index);
@@ -1550,9 +1580,18 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,


			/*
			/*
			 * Call back to inform the ieee80211 subsystem about
			 * Call back to inform the ieee80211 subsystem about
			 * the status of the transmission.
			 * the status of the transmission. When skipping over
			 * a missed TX status report, use a status structure
			 * filled with zeros to indicate that the frame was not
			 * sent (frame_count 0) and not acknowledged
			 */
			 */
			frame_succeed = b43_fill_txstatus_report(dev, info, status);
			if (unlikely(skip))
				txstat = &fake;
			else
				txstat = status;

			frame_succeed = b43_fill_txstatus_report(dev, info,
								 txstat);
#ifdef CONFIG_B43_DEBUG
#ifdef CONFIG_B43_DEBUG
			if (frame_succeed)
			if (frame_succeed)
				ring->nr_succeed_tx_packets++;
				ring->nr_succeed_tx_packets++;
@@ -1580,12 +1619,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
		/* Everything unmapped and free'd. So it's not used anymore. */
		/* Everything unmapped and free'd. So it's not used anymore. */
		ring->used_slots--;
		ring->used_slots--;


		if (meta->is_last_fragment) {
		if (meta->is_last_fragment && !skip) {
			/* This is the last scatter-gather
			/* This is the last scatter-gather
			 * fragment of the frame. We are done. */
			 * fragment of the frame. We are done. */
			break;
			break;
		}
		}
		slot = next_slot(ring, slot);
		slot = next_slot(ring, slot);
		if (skip > 0)
			--skip;
	}
	}
	if (ring->stopped) {
	if (ring->stopped) {
		B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
		B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
+4 −4
Original line number Original line Diff line number Diff line
@@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
	u16 clip_off[2] = { 0xFFFF, 0xFFFF };
	u16 clip_off[2] = { 0xFFFF, 0xFFFF };


	u8 vcm_final = 0;
	u8 vcm_final = 0;
	s8 offset[4];
	s32 offset[4];
	s32 results[8][4] = { };
	s32 results[8][4] = { };
	s32 results_min[4] = { };
	s32 results_min[4] = { };
	s32 poll_results[4] = { };
	s32 poll_results[4] = { };
@@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
		}
		}
		for (i = 0; i < 4; i += 2) {
		for (i = 0; i < 4; i += 2) {
			s32 curr;
			s32 curr;
			s32 mind = 40;
			s32 mind = 0x100000;
			s32 minpoll = 249;
			s32 minpoll = 249;
			u8 minvcm = 0;
			u8 minvcm = 0;
			if (2 * core != i)
			if (2 * core != i)
@@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
	u8 regs_save_radio[2];
	u8 regs_save_radio[2];
	u16 regs_save_phy[2];
	u16 regs_save_phy[2];


	s8 offset[4];
	s32 offset[4];
	u8 core;
	u8 core;
	u8 rail;
	u8 rail;


@@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
	}
	}


	for (i = 0; i < 4; i++) {
	for (i = 0; i < 4; i++) {
		s32 mind = 40;
		s32 mind = 0x100000;
		u8 minvcm = 0;
		u8 minvcm = 0;
		s32 minpoll = 249;
		s32 minpoll = 249;
		s32 curr;
		s32 curr;
+130 −239
Original line number Original line Diff line number Diff line
@@ -1137,9 +1137,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
	gain0_15 = ((biq1 & 0xf) << 12) |
	gain0_15 = ((biq1 & 0xf) << 12) |
		   ((tia & 0xf) << 8) |
		   ((tia & 0xf) << 8) |
		   ((lna2 & 0x3) << 6) |
		   ((lna2 & 0x3) << 6) |
		   ((lna2 & 0x3) << 4) |
		   ((lna2 &
		   ((lna1 & 0x3) << 2) |
		     0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
		   ((lna1 & 0x3) << 0);


	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1157,8 +1156,6 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
	}
	}


	mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
	mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
	mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
	mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);


}
}


@@ -1331,43 +1328,6 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
}
}


static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
				      u16 tia_gain, u16 lna2_gain)
{
	u32 i_thresh_l, q_thresh_l;
	u32 i_thresh_h, q_thresh_h;
	struct lcnphy_iq_est iq_est_h, iq_est_l;

	wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
					       lna2_gain, 0);

	wlc_lcnphy_rx_gain_override_enable(pi, true);
	wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
	udelay(500);
	write_radio_reg(pi, RADIO_2064_REG112, 0);
	if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
		return false;

	wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
	udelay(500);
	write_radio_reg(pi, RADIO_2064_REG112, 0);
	if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
		return false;

	i_thresh_l = (iq_est_l.i_pwr << 1);
	i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;

	q_thresh_l = (iq_est_l.q_pwr << 1);
	q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
	if ((iq_est_h.i_pwr > i_thresh_l) &&
	    (iq_est_h.i_pwr < i_thresh_h) &&
	    (iq_est_h.q_pwr > q_thresh_l) &&
	    (iq_est_h.q_pwr < q_thresh_h))
		return true;

	return false;
}

static bool
static bool
wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
		     const struct lcnphy_rx_iqcomp *iqcomp,
		     const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1382,8 +1342,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
	int tia_gain, lna2_gain, biq1_gain;
	int tia_gain;
	bool set_gain;
	u32 received_power, rx_pwr_threshold;
	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
	u16 values_to_save[11];
	u16 values_to_save[11];
	s16 *ptr;
	s16 *ptr;
@@ -1408,7 +1368,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
		goto cal_done;
		goto cal_done;
	}
	}


	WARN_ON(module != 1);
	if (module == 1) {

		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);


@@ -1471,38 +1432,28 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);


		wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
		write_phy_reg(pi, 0x6da, 0xffff);
		write_phy_reg(pi, 0x6da, 0xffff);
		or_phy_reg(pi, 0x6db, 0x3);
		or_phy_reg(pi, 0x6db, 0x3);

		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
	set_gain = false;
		wlc_lcnphy_rx_gain_override_enable(pi, true);

	lna2_gain = 3;
	while ((lna2_gain >= 0) && !set_gain) {
		tia_gain = 4;

		while ((tia_gain >= 0) && !set_gain) {
			biq1_gain = 6;


			while ((biq1_gain >= 0) && !set_gain) {
		tia_gain = 8;
				set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
		rx_pwr_threshold = 950;
								     (u16)
		while (tia_gain > 0) {
								     biq1_gain,
								     (u16)
								     tia_gain,
								     (u16)
								     lna2_gain);
				biq1_gain -= 1;
			}
			tia_gain -= 1;
			tia_gain -= 1;
		}
			wlc_lcnphy_set_rx_gain_by_distribution(pi,
		lna2_gain -= 1;
							       0, 0, 2, 2,
	}
							       (u16)
							       tia_gain, 1, 0);
			udelay(500);


	if (set_gain)
			received_power =
		result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
				wlc_lcnphy_measure_digital_power(pi, 2000);
	else
			if (received_power < rx_pwr_threshold)
		result = false;
				break;
		}
		result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);


		wlc_lcnphy_stop_tx_tone(pi);
		wlc_lcnphy_stop_tx_tone(pi);


@@ -1536,6 +1487,7 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,


		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
		wlc_lcnphy_rx_gain_override_enable(pi, false);
		wlc_lcnphy_rx_gain_override_enable(pi, false);
	}


cal_done:
cal_done:
	kfree(ptr);
	kfree(ptr);
@@ -1829,17 +1781,6 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
		write_radio_reg(pi, RADIO_2064_REG038, 3);
		write_radio_reg(pi, RADIO_2064_REG038, 3);
		write_radio_reg(pi, RADIO_2064_REG091, 7);
		write_radio_reg(pi, RADIO_2064_REG091, 7);
	}
	}

	if (!(pi->sh->boardflags & BFL_FEM)) {
		u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
			0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};

		write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
		write_radio_reg(pi, RADIO_2064_REG091, 0x3);
		write_radio_reg(pi, RADIO_2064_REG038, 0x3);

		write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
	}
}
}


static int
static int
@@ -2034,16 +1975,6 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
		} else {
		} else {
			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
			mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
			mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
			mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
			mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
			mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
			mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
			mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
			mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
			mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
		}
		}
	} else {
	} else {
		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2130,14 +2061,12 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));


	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
	mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
}
}


static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
{
{
	struct phytbl_info tab;
	struct phytbl_info tab;
	u32 rfseq, ind;
	u32 rfseq, ind;
	u8 tssi_sel;


	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
	tab.tbl_width = 32;
	tab.tbl_width = 32;
@@ -2159,13 +2088,7 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)


	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);


	if (pi->sh->boardflags & BFL_FEM) {
		tssi_sel = 0x1;
	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
	} else {
		tssi_sel = 0xe;
		wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
	}
	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);


	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2201,10 +2124,9 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);


	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
	} else {
	} else {
		mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
	}
	}
@@ -2251,10 +2173,6 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)


	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);


	mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
	mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
	mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);

	wlc_lcnphy_pwrctrl_rssiparams(pi);
	wlc_lcnphy_pwrctrl_rssiparams(pi);
}
}


@@ -2873,8 +2791,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
		read_radio_reg(pi, RADIO_2064_REG007) & 1;
		read_radio_reg(pi, RADIO_2064_REG007) & 1;
	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
	u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);

	idleTssi = read_phy_reg(pi, 0x4ab);
	idleTssi = read_phy_reg(pi, 0x4ab);
	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
			 MCTL_EN_MAC));
			 MCTL_EN_MAC));
@@ -2892,12 +2808,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
	wlc_lcnphy_tssi_setup(pi);
	wlc_lcnphy_tssi_setup(pi);

	mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
	mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));

	wlc_lcnphy_set_bbmult(pi, 0x0);

	wlc_phy_do_dummy_tx(pi, true, OFF);
	wlc_phy_do_dummy_tx(pi, true, OFF);
	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
		    >> 0);
		    >> 0);
@@ -2919,7 +2829,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)


	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);


	wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
	wlc_lcnphy_set_tx_gain(pi, &old_gains);
	wlc_lcnphy_set_tx_gain(pi, &old_gains);
	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3133,11 +3042,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
			wlc_lcnphy_write_table(pi, &tab);
			wlc_lcnphy_write_table(pi, &tab);
			tab.tbl_offset++;
			tab.tbl_offset++;
		}
		}
		mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
		mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
		mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
		mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
		mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);


		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);


@@ -3939,6 +3843,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
	target_gains.pad_gain = 21;
	target_gains.pad_gain = 21;
	target_gains.dac_gain = 0;
	target_gains.dac_gain = 0;
	wlc_lcnphy_set_tx_gain(pi, &target_gains);
	wlc_lcnphy_set_tx_gain(pi, &target_gains);
	wlc_lcnphy_set_tx_pwr_by_index(pi, 16);


	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {


@@ -3949,7 +3854,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
					lcnphy_recal ? LCNPHY_CAL_RECAL :
					lcnphy_recal ? LCNPHY_CAL_RECAL :
					LCNPHY_CAL_FULL), false);
					LCNPHY_CAL_FULL), false);
	} else {
	} else {
		wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
	}
	}


@@ -4374,22 +4278,17 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
	if (CHSPEC_IS5G(pi->radio_chanspec))
	if (CHSPEC_IS5G(pi->radio_chanspec))
		pa_gain = 0x70;
		pa_gain = 0x70;
	else
	else
		pa_gain = 0x60;
		pa_gain = 0x70;


	if (pi->sh->boardflags & BFL_FEM)
	if (pi->sh->boardflags & BFL_FEM)
		pa_gain = 0x10;
		pa_gain = 0x10;

	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
	tab.tbl_width = 32;
	tab.tbl_width = 32;
	tab.tbl_len = 1;
	tab.tbl_len = 1;
	tab.tbl_ptr = &val;
	tab.tbl_ptr = &val;


	for (j = 0; j < 128; j++) {
	for (j = 0; j < 128; j++) {
		if (pi->sh->boardflags & BFL_FEM)
		gm_gain = gain_table[j].gm;
		gm_gain = gain_table[j].gm;
		else
			gm_gain = 15;

		val = (((u32) pa_gain << 24) |
		val = (((u32) pa_gain << 24) |
		       (gain_table[j].pad << 16) |
		       (gain_table[j].pad << 16) |
		       (gain_table[j].pga << 8) | gm_gain);
		       (gain_table[j].pga << 8) | gm_gain);
@@ -4600,10 +4499,7 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)


	write_phy_reg(pi, 0x4ea, 0x4688);
	write_phy_reg(pi, 0x4ea, 0x4688);


	if (pi->sh->boardflags & BFL_FEM)
	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
	else
		mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);


	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);


@@ -4614,13 +4510,6 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
	wlc_lcnphy_rcal(pi);
	wlc_lcnphy_rcal(pi);


	wlc_lcnphy_rc_cal(pi);
	wlc_lcnphy_rc_cal(pi);

	if (!(pi->sh->boardflags & BFL_FEM)) {
		write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
		write_radio_reg(pi, RADIO_2064_REG033, 0x19);
		write_radio_reg(pi, RADIO_2064_REG039, 0xe);
	}

}
}


static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4650,20 +4539,22 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
		wlc_lcnphy_write_table(pi, &tab);
		wlc_lcnphy_write_table(pi, &tab);
	}
	}


	if (!(pi->sh->boardflags & BFL_FEM)) {
	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
	tab.tbl_width = 16;
	tab.tbl_width = 16;
	tab.tbl_ptr = &val;
	tab.tbl_ptr = &val;
	tab.tbl_len = 1;
	tab.tbl_len = 1;


		val = 150;
	val = 114;
	tab.tbl_offset = 0;
	tab.tbl_offset = 0;
	wlc_lcnphy_write_table(pi, &tab);
	wlc_lcnphy_write_table(pi, &tab);


		val = 220;
	val = 130;
	tab.tbl_offset = 1;
	tab.tbl_offset = 1;
	wlc_lcnphy_write_table(pi, &tab);
	wlc_lcnphy_write_table(pi, &tab);
	}

	val = 6;
	tab.tbl_offset = 8;
	wlc_lcnphy_write_table(pi, &tab);


	if (CHSPEC_IS2G(pi->radio_chanspec)) {
	if (CHSPEC_IS2G(pi->radio_chanspec)) {
		if (pi->sh->boardflags & BFL_FEM)
		if (pi->sh->boardflags & BFL_FEM)
@@ -5055,7 +4946,6 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
		wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
		wlc_lcnphy_load_tx_iir_filter(pi, true, 3);


	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
	wlc_lcnphy_tssi_setup(pi);
}
}


void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
@@ -5094,7 +4984,8 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
		return false;
		return false;


	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
	if ((pi->sh->boardflags & BFL_FEM) &&
	    (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
		if (pi_lcn->lcnphy_tempsense_option == 3) {
		if (pi_lcn->lcnphy_tempsense_option == 3) {
			pi->hwpwrctrl = true;
			pi->hwpwrctrl = true;
			pi->hwpwrctrl_capable = true;
			pi->hwpwrctrl_capable = true;
Loading