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

b43: N-PHY: implement very basic TX power control management

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
161d540c 40277cab

+153 -8
+152 -7
drivers/net/wireless/b43/phy_n.c
··· 67 67 B43_RFSEQ_UPDATE_GAINU, 68 68 }; 69 69 70 + static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, 71 + bool enable); 70 72 static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, 71 73 u8 *events, u8 *delays, u8 length); 72 74 static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, ··· 147 145 b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6); 148 146 } 149 147 148 + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */ 149 + static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) 150 + { 151 + struct b43_phy_n *nphy = dev->phy.n; 152 + u8 i; 153 + u16 tmp; 154 + 155 + if (nphy->hang_avoid) 156 + b43_nphy_stay_in_carrier_search(dev, 1); 157 + 158 + nphy->txpwrctrl = enable; 159 + if (!enable) { 160 + if (dev->phy.rev >= 3) 161 + ; /* TODO */ 162 + 163 + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840); 164 + for (i = 0; i < 84; i++) 165 + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0); 166 + 167 + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6C40); 168 + for (i = 0; i < 84; i++) 169 + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0); 170 + 171 + tmp = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN; 172 + if (dev->phy.rev >= 3) 173 + tmp |= B43_NPHY_TXPCTL_CMD_PCTLEN; 174 + b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, ~tmp); 175 + 176 + if (dev->phy.rev >= 3) { 177 + b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100); 178 + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100); 179 + } else { 180 + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000); 181 + } 182 + 183 + if (dev->phy.rev == 2) 184 + b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, 185 + ~B43_NPHY_BPHY_CTL3_SCALE, 0x53); 186 + else if (dev->phy.rev < 2) 187 + b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, 188 + ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A); 189 + 190 + if (dev->phy.rev < 2 && 0) 191 + ; /* TODO */ 192 + } else { 193 + b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n"); 194 + } 195 + 196 + if (nphy->hang_avoid) 197 + b43_nphy_stay_in_carrier_search(dev, 0); 198 + } 199 + 200 + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */ 150 201 static void b43_nphy_tx_power_fix(struct b43_wldev *dev) 151 202 { 152 - //TODO 203 + struct b43_phy_n *nphy = dev->phy.n; 204 + struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 205 + 206 + u8 txpi[2], bbmult, i; 207 + u16 tmp, radio_gain, dac_gain; 208 + u16 freq = dev->phy.channel_freq; 209 + u32 txgain; 210 + /* u32 gaintbl; rev3+ */ 211 + 212 + if (nphy->hang_avoid) 213 + b43_nphy_stay_in_carrier_search(dev, 1); 214 + 215 + if (dev->phy.rev >= 3) { 216 + txpi[0] = 40; 217 + txpi[1] = 40; 218 + } else if (sprom->revision < 4) { 219 + txpi[0] = 72; 220 + txpi[1] = 72; 221 + } else { 222 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 223 + txpi[0] = sprom->txpid2g[0]; 224 + txpi[1] = sprom->txpid2g[1]; 225 + } else if (freq >= 4900 && freq < 5100) { 226 + txpi[0] = sprom->txpid5gl[0]; 227 + txpi[1] = sprom->txpid5gl[1]; 228 + } else if (freq >= 5100 && freq < 5500) { 229 + txpi[0] = sprom->txpid5g[0]; 230 + txpi[1] = sprom->txpid5g[1]; 231 + } else if (freq >= 5500) { 232 + txpi[0] = sprom->txpid5gh[0]; 233 + txpi[1] = sprom->txpid5gh[1]; 234 + } else { 235 + txpi[0] = 91; 236 + txpi[1] = 91; 237 + } 238 + } 239 + 240 + /* 241 + for (i = 0; i < 2; i++) { 242 + nphy->txpwrindex[i].index_internal = txpi[i]; 243 + nphy->txpwrindex[i].index_internal_save = txpi[i]; 244 + } 245 + */ 246 + 247 + for (i = 0; i < 2; i++) { 248 + if (dev->phy.rev >= 3) { 249 + /* TODO */ 250 + radio_gain = (txgain >> 16) & 0x1FFFF; 251 + } else { 252 + txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]]; 253 + radio_gain = (txgain >> 16) & 0x1FFF; 254 + } 255 + 256 + dac_gain = (txgain >> 8) & 0x3F; 257 + bbmult = txgain & 0xFF; 258 + 259 + if (dev->phy.rev >= 3) { 260 + if (i == 0) 261 + b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100); 262 + else 263 + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100); 264 + } else { 265 + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000); 266 + } 267 + 268 + if (i == 0) 269 + b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN1, dac_gain); 270 + else 271 + b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain); 272 + 273 + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i); 274 + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain); 275 + 276 + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57); 277 + tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); 278 + 279 + if (i == 0) 280 + tmp = (tmp & 0x00FF) | (bbmult << 8); 281 + else 282 + tmp = (tmp & 0xFF00) | bbmult; 283 + 284 + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57); 285 + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp); 286 + 287 + if (0) 288 + ; /* TODO */ 289 + } 290 + 291 + b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT); 292 + 293 + if (nphy->hang_avoid) 294 + b43_nphy_stay_in_carrier_search(dev, 0); 153 295 } 154 296 155 297 ··· 2497 2351 struct nphy_txgains target; 2498 2352 const u32 *table = NULL; 2499 2353 2500 - if (nphy->txpwrctrl == 0) { 2354 + if (!nphy->txpwrctrl) { 2501 2355 int i; 2502 2356 2503 2357 if (nphy->hang_avoid) ··· 3406 3260 b43_nphy_bphy_init(dev); 3407 3261 3408 3262 tx_pwr_state = nphy->txpwrctrl; 3409 - /* TODO N PHY TX power control with argument 0 3410 - (turning off power control) */ 3411 - /* TODO Fix the TX Power Settings */ 3263 + b43_nphy_tx_power_ctrl(dev, false); 3264 + b43_nphy_tx_power_fix(dev); 3412 3265 /* TODO N PHY TX Power Control Idle TSSI */ 3413 3266 /* TODO N PHY TX Power Control Setup */ 3414 3267 ··· 3478 3333 } 3479 3334 3480 3335 b43_nphy_tx_pwr_ctrl_coef_setup(dev); 3481 - /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */ 3336 + b43_nphy_tx_power_ctrl(dev, tx_pwr_state); 3482 3337 b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015); 3483 3338 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320); 3484 3339 if (phy->rev >= 3 && phy->rev <= 6) ··· 3529 3384 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840); 3530 3385 } 3531 3386 3532 - if (nphy->txpwrctrl) 3387 + if (!nphy->txpwrctrl) 3533 3388 b43_nphy_tx_power_fix(dev); 3534 3389 3535 3390 if (dev->phy.rev < 3)
+1 -1
drivers/net/wireless/b43/phy_n.h
··· 782 782 u16 mphase_txcal_numcmds; 783 783 u16 mphase_txcal_bestcoeffs[11]; 784 784 785 - u8 txpwrctrl; 785 + bool txpwrctrl; 786 786 u16 txcal_bbmult; 787 787 u16 txiqlocal_bestc[11]; 788 788 bool txiqlocal_coeffsvalid;