Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

b43: N-PHY: support setting custom TX power

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Rafał Miłecki and committed by
John W. Linville
8615eb28 ec76643b

+77 -12
+1
drivers/net/wireless/b43/b43.h
··· 457 457 #define B43_MACCTL_RADIOLOCK 0x00080000 /* Radio lock */ 458 458 #define B43_MACCTL_BEACPROMISC 0x00100000 /* Beacon Promiscuous */ 459 459 #define B43_MACCTL_KEEP_BADPLCP 0x00200000 /* Keep frames with bad PLCP */ 460 + #define B43_MACCTL_PHY_LOCK 0x00200000 460 461 #define B43_MACCTL_KEEP_CTL 0x00400000 /* Keep control frames */ 461 462 #define B43_MACCTL_KEEP_BAD 0x00800000 /* Keep bad frames (FCS) */ 462 463 #define B43_MACCTL_PROMISC 0x01000000 /* Promiscuous mode */
+72 -12
drivers/net/wireless/b43/phy_n.c
··· 34 34 #include "radio_2056.h" 35 35 #include "radio_2057.h" 36 36 #include "main.h" 37 + #include "ppr.h" 37 38 38 39 struct nphy_txgains { 39 40 u16 tx_lpf[2]; ··· 3607 3606 * Tx and Rx 3608 3607 **************************************************/ 3609 3608 3610 - static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev) 3611 - {//TODO 3612 - } 3613 - 3614 - static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev, 3615 - bool ignore_tssi) 3616 - {//TODO 3617 - return B43_TXPWR_RES_DONE; 3618 - } 3619 - 3620 3609 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */ 3621 3610 static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) 3622 3611 { ··· 4060 4069 4061 4070 s16 a1[2], b0[2], b1[2]; 4062 4071 u8 idle[2]; 4072 + u8 ppr_max; 4063 4073 s8 target[2]; 4064 4074 s32 num, den, pwr; 4065 4075 u32 regval[64]; ··· 4139 4147 b1[0] = b1[1] = -1393; 4140 4148 } 4141 4149 } 4142 - /* target[0] = target[1] = nphy->tx_power_max; */ 4150 + 4151 + ppr_max = b43_ppr_get_max(dev, &nphy->tx_pwr_max_ppr); 4152 + if (ppr_max) { 4153 + target[0] = ppr_max; 4154 + target[1] = ppr_max; 4155 + } 4143 4156 4144 4157 if (dev->phy.rev >= 3) { 4145 4158 if (sprom->fem.ghz2.tssipos) ··· 5886 5889 b43_mac_enable(dev); 5887 5890 } 5888 5891 5892 + static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev, 5893 + bool ignore_tssi) 5894 + { 5895 + struct b43_phy *phy = &dev->phy; 5896 + struct b43_phy_n *nphy = dev->phy.n; 5897 + struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; 5898 + struct b43_ppr *ppr = &nphy->tx_pwr_max_ppr; 5899 + u8 max; /* qdBm */ 5900 + bool tx_pwr_state; 5901 + 5902 + if (nphy->tx_pwr_last_recalc_freq == channel->center_freq && 5903 + nphy->tx_pwr_last_recalc_limit == phy->desired_txpower) 5904 + return B43_TXPWR_RES_DONE; 5905 + 5906 + /* Make sure we have a clean PPR */ 5907 + b43_ppr_clear(dev, ppr); 5908 + 5909 + /* HW limitations */ 5910 + b43_ppr_load_max_from_sprom(dev, ppr, B43_BAND_2G); 5911 + 5912 + /* Regulatory & user settings */ 5913 + max = INT_TO_Q52(phy->chandef->chan->max_power); 5914 + if (phy->desired_txpower) 5915 + max = min_t(u8, max, INT_TO_Q52(phy->desired_txpower)); 5916 + b43_ppr_apply_max(dev, ppr, max); 5917 + if (b43_debug(dev, B43_DBG_XMITPOWER)) 5918 + b43dbg(dev->wl, "Calculated TX power: " Q52_FMT "\n", 5919 + Q52_ARG(b43_ppr_get_max(dev, ppr))); 5920 + 5921 + /* TODO: Enable this once we get gains working */ 5922 + #if 0 5923 + /* Some extra gains */ 5924 + hw_gain = 6; /* N-PHY specific */ 5925 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 5926 + hw_gain += sprom->antenna_gain.a0; 5927 + else 5928 + hw_gain += sprom->antenna_gain.a1; 5929 + b43_ppr_add(dev, ppr, -hw_gain); 5930 + #endif 5931 + 5932 + /* Make sure we didn't go too low */ 5933 + b43_ppr_apply_min(dev, ppr, INT_TO_Q52(8)); 5934 + 5935 + /* Apply */ 5936 + tx_pwr_state = nphy->txpwrctrl; 5937 + b43_mac_suspend(dev); 5938 + b43_nphy_tx_power_ctl_setup(dev); 5939 + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { 5940 + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_PHY_LOCK); 5941 + b43_read32(dev, B43_MMIO_MACCTL); 5942 + udelay(1); 5943 + } 5944 + b43_nphy_tx_power_ctrl(dev, nphy->txpwrctrl); 5945 + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) 5946 + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PHY_LOCK, 0); 5947 + b43_mac_enable(dev); 5948 + 5949 + nphy->tx_pwr_last_recalc_freq = channel->center_freq; 5950 + nphy->tx_pwr_last_recalc_limit = phy->desired_txpower; 5951 + 5952 + return B43_TXPWR_RES_DONE; 5953 + } 5954 + 5889 5955 /************************************************** 5890 5956 * N-PHY init 5891 5957 **************************************************/ ··· 6482 6422 nphy = kzalloc(sizeof(*nphy), GFP_KERNEL); 6483 6423 if (!nphy) 6484 6424 return -ENOMEM; 6425 + 6485 6426 dev->phy.n = nphy; 6486 6427 6487 6428 return 0; ··· 6723 6662 .switch_channel = b43_nphy_op_switch_channel, 6724 6663 .get_default_chan = b43_nphy_op_get_default_chan, 6725 6664 .recalc_txpower = b43_nphy_op_recalc_txpower, 6726 - .adjust_txpower = b43_nphy_op_adjust_txpower, 6727 6665 };
+4
drivers/net/wireless/b43/phy_n.h
··· 2 2 #define B43_NPHY_H_ 3 3 4 4 #include "phy_common.h" 5 + #include "ppr.h" 5 6 6 7 7 8 /* N-PHY registers. */ ··· 968 967 struct b43_phy_n_txpwrindex txpwrindex[2]; 969 968 struct b43_phy_n_pwr_ctl_info pwr_ctl_info[2]; 970 969 struct b43_chanspec txiqlocal_chanspec; 970 + struct b43_ppr tx_pwr_max_ppr; 971 + u16 tx_pwr_last_recalc_freq; 972 + int tx_pwr_last_recalc_limit; 971 973 972 974 u8 txrx_chain; 973 975 u16 tx_rx_cal_phy_saveregs[11];