3 Broadcom B43 wireless driver
4 IEEE 802.11g LP-PHY driver
6 Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.de>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
21 Boston, MA 02110-1301, USA.
28 #include "phy_common.h"
29 #include "tables_lpphy.h"
32 static int b43_lpphy_op_allocate(struct b43_wldev
*dev
)
34 struct b43_phy_lp
*lpphy
;
36 lpphy
= kzalloc(sizeof(*lpphy
), GFP_KERNEL
);
44 static void b43_lpphy_op_prepare_structs(struct b43_wldev
*dev
)
46 struct b43_phy
*phy
= &dev
->phy
;
47 struct b43_phy_lp
*lpphy
= phy
->lp
;
49 memset(lpphy
, 0, sizeof(*lpphy
));
54 static void b43_lpphy_op_free(struct b43_wldev
*dev
)
56 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
62 static void lpphy_table_init(struct b43_wldev
*dev
)
67 static void lpphy_baseband_rev0_1_init(struct b43_wldev
*dev
)
69 B43_WARN_ON(1);//TODO rev < 2 not supported, yet.
72 static void lpphy_baseband_rev2plus_init(struct b43_wldev
*dev
)
74 struct ssb_bus
*bus
= dev
->dev
->bus
;
75 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
77 b43_phy_write(dev
, B43_LPPHY_AFE_DAC_CTL
, 0x50);
78 b43_phy_write(dev
, B43_LPPHY_AFE_CTL
, 0x8800);
79 b43_phy_write(dev
, B43_LPPHY_AFE_CTL_OVR
, 0);
80 b43_phy_write(dev
, B43_LPPHY_AFE_CTL_OVRVAL
, 0);
81 b43_phy_write(dev
, B43_LPPHY_RF_OVERRIDE_0
, 0);
82 b43_phy_write(dev
, B43_LPPHY_RF_OVERRIDE_2
, 0);
83 b43_phy_write(dev
, B43_PHY_OFDM(0xF9), 0);
84 b43_phy_write(dev
, B43_LPPHY_TR_LOOKUP_1
, 0);
85 b43_phy_set(dev
, B43_LPPHY_ADC_COMPENSATION_CTL
, 0x10);
86 b43_phy_maskset(dev
, B43_LPPHY_OFDMSYNCTHRESH0
, 0xFF00, 0x78);
87 b43_phy_maskset(dev
, B43_LPPHY_DCOFFSETTRANSIENT
, 0xF8FF, 0x200);
88 b43_phy_maskset(dev
, B43_LPPHY_DCOFFSETTRANSIENT
, 0xFF00, 0x7F);
89 b43_phy_maskset(dev
, B43_LPPHY_GAINDIRECTMISMATCH
, 0xFF0F, 0x40);
90 b43_phy_maskset(dev
, B43_LPPHY_PREAMBLECONFIRMTO
, 0xFF00, 0x2);
91 b43_phy_mask(dev
, B43_LPPHY_CRSGAIN_CTL
, ~0x4000);
92 b43_phy_mask(dev
, B43_LPPHY_CRSGAIN_CTL
, ~0x2000);
93 b43_phy_set(dev
, B43_PHY_OFDM(0x10A), 0x1);
94 b43_phy_maskset(dev
, B43_PHY_OFDM(0x10A), 0xFF01, 0x10);
95 b43_phy_maskset(dev
, B43_PHY_OFDM(0xDF), 0xFF00, 0xF4);
96 b43_phy_maskset(dev
, B43_PHY_OFDM(0xDF), 0x00FF, 0xF100);
97 b43_phy_write(dev
, B43_LPPHY_CLIPTHRESH
, 0x48);
98 b43_phy_maskset(dev
, B43_LPPHY_HIGAINDB
, 0xFF00, 0x46);
99 b43_phy_maskset(dev
, B43_PHY_OFDM(0xE4), 0xFF00, 0x10);
100 b43_phy_maskset(dev
, B43_LPPHY_PWR_THRESH1
, 0xFFF0, 0x9);
101 b43_phy_mask(dev
, B43_LPPHY_GAINDIRECTMISMATCH
, ~0xF);
102 b43_phy_maskset(dev
, B43_LPPHY_VERYLOWGAINDB
, 0x00FF, 0x5500);
103 b43_phy_maskset(dev
, B43_LPPHY_CLIPCTRTHRESH
, 0xF81F, 0xA0);
104 b43_phy_maskset(dev
, B43_LPPHY_GAINDIRECTMISMATCH
, 0xE0FF, 0x300);
105 b43_phy_maskset(dev
, B43_LPPHY_HIGAINDB
, 0x00FF, 0x2A00);
106 if ((bus
->chip_id
== 0x4325) && (bus
->chip_rev
== 0)) {
107 b43_phy_maskset(dev
, B43_LPPHY_LOWGAINDB
, 0x00FF, 0x2100);
108 b43_phy_maskset(dev
, B43_LPPHY_VERYLOWGAINDB
, 0xFF00, 0xA);
110 b43_phy_maskset(dev
, B43_LPPHY_LOWGAINDB
, 0x00FF, 0x1E00);
111 b43_phy_maskset(dev
, B43_LPPHY_VERYLOWGAINDB
, 0xFF00, 0xD);
113 b43_phy_maskset(dev
, B43_PHY_OFDM(0xFE), 0xFFE0, 0x1F);
114 b43_phy_maskset(dev
, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
115 b43_phy_maskset(dev
, B43_PHY_OFDM(0x100), 0xFF00, 0x19);
116 b43_phy_maskset(dev
, B43_PHY_OFDM(0xFF), 0x03FF, 0x3C00);
117 b43_phy_maskset(dev
, B43_PHY_OFDM(0xFE), 0xFC1F, 0x3E0);
118 b43_phy_maskset(dev
, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
119 b43_phy_maskset(dev
, B43_PHY_OFDM(0x100), 0x00FF, 0x1900);
120 b43_phy_maskset(dev
, B43_LPPHY_CLIPCTRTHRESH
, 0x83FF, 0x5800);
121 b43_phy_maskset(dev
, B43_LPPHY_CLIPCTRTHRESH
, 0xFFE0, 0x12);
122 b43_phy_maskset(dev
, B43_LPPHY_GAINMISMATCH
, 0x0FFF, 0x9000);
124 b43_lptab_write(dev
, B43_LPTAB16(0x08, 0x14), 0);
125 b43_lptab_write(dev
, B43_LPTAB16(0x08, 0x12), 0x40);
127 if (b43_current_band(dev
->wl
) == IEEE80211_BAND_2GHZ
) {
128 b43_phy_set(dev
, B43_LPPHY_CRSGAIN_CTL
, 0x40);
129 b43_phy_maskset(dev
, B43_LPPHY_CRSGAIN_CTL
, 0xF0FF, 0xB00);
130 b43_phy_maskset(dev
, B43_LPPHY_SYNCPEAKCNT
, 0xFFF8, 0x6);
131 b43_phy_maskset(dev
, B43_LPPHY_MINPWR_LEVEL
, 0x00FF, 0x9D00);
132 b43_phy_maskset(dev
, B43_LPPHY_MINPWR_LEVEL
, 0xFF00, 0xA1);
134 b43_phy_mask(dev
, B43_LPPHY_CRSGAIN_CTL
, ~0x40);
136 b43_phy_maskset(dev
, B43_LPPHY_CRS_ED_THRESH
, 0xFF00, 0xB3);
137 b43_phy_maskset(dev
, B43_LPPHY_CRS_ED_THRESH
, 0x00FF, 0xAD00);
138 b43_phy_maskset(dev
, B43_LPPHY_INPUT_PWRDB
, 0xFF00, lpphy
->rx_pwr_offset
);
139 b43_phy_set(dev
, B43_LPPHY_RESET_CTL
, 0x44);
140 b43_phy_write(dev
, B43_LPPHY_RESET_CTL
, 0x80);
141 b43_phy_write(dev
, B43_LPPHY_AFE_RSSI_CTL_0
, 0xA954);
142 b43_phy_write(dev
, B43_LPPHY_AFE_RSSI_CTL_1
,
143 0x2000 | ((u16
)lpphy
->rssi_gs
<< 10) |
144 ((u16
)lpphy
->rssi_vc
<< 4) | lpphy
->rssi_vf
);
147 static void lpphy_baseband_init(struct b43_wldev
*dev
)
149 lpphy_table_init(dev
);
150 if (dev
->phy
.rev
>= 2)
151 lpphy_baseband_rev2plus_init(dev
);
153 lpphy_baseband_rev0_1_init(dev
);
156 struct b2062_freqdata
{
161 /* Initialize the 2062 radio. */
162 static void lpphy_2062_init(struct b43_wldev
*dev
)
164 struct ssb_bus
*bus
= dev
->dev
->bus
;
165 u32 crystalfreq
, pdiv
, tmp
, ref
;
167 const struct b2062_freqdata
*fd
= NULL
;
169 static const struct b2062_freqdata freqdata_tab
[] = {
170 { .freq
= 12000, .data
[0] = 6, .data
[1] = 6, .data
[2] = 6,
171 .data
[3] = 6, .data
[4] = 10, .data
[5] = 6, },
172 { .freq
= 13000, .data
[0] = 4, .data
[1] = 4, .data
[2] = 4,
173 .data
[3] = 4, .data
[4] = 11, .data
[5] = 7, },
174 { .freq
= 14400, .data
[0] = 3, .data
[1] = 3, .data
[2] = 3,
175 .data
[3] = 3, .data
[4] = 12, .data
[5] = 7, },
176 { .freq
= 16200, .data
[0] = 3, .data
[1] = 3, .data
[2] = 3,
177 .data
[3] = 3, .data
[4] = 13, .data
[5] = 8, },
178 { .freq
= 18000, .data
[0] = 2, .data
[1] = 2, .data
[2] = 2,
179 .data
[3] = 2, .data
[4] = 14, .data
[5] = 8, },
180 { .freq
= 19200, .data
[0] = 1, .data
[1] = 1, .data
[2] = 1,
181 .data
[3] = 1, .data
[4] = 14, .data
[5] = 9, },
184 b2062_upload_init_table(dev
);
186 b43_radio_write(dev
, B2062_N_TX_CTL3
, 0);
187 b43_radio_write(dev
, B2062_N_TX_CTL4
, 0);
188 b43_radio_write(dev
, B2062_N_TX_CTL5
, 0);
189 b43_radio_write(dev
, B2062_N_PDN_CTL0
, 0x40);
190 b43_radio_write(dev
, B2062_N_PDN_CTL0
, 0);
191 b43_radio_write(dev
, B2062_N_CALIB_TS
, 0x10);
192 b43_radio_write(dev
, B2062_N_CALIB_TS
, 0);
193 if (b43_current_band(dev
->wl
) == IEEE80211_BAND_2GHZ
)
194 b43_radio_set(dev
, B2062_N_TSSI_CTL0
, 0x1);
196 b43_radio_mask(dev
, B2062_N_TSSI_CTL0
, ~0x1);
198 /* Get the crystal freq, in Hz. */
199 crystalfreq
= bus
->chipco
.pmu
.crystalfreq
* 1000;
201 B43_WARN_ON(!(bus
->chipco
.capabilities
& SSB_CHIPCO_CAP_PMU
));
202 B43_WARN_ON(crystalfreq
== 0);
204 if (crystalfreq
>= 30000000) {
206 b43_radio_mask(dev
, B2062_S_RFPLL_CTL1
, 0xFFFB);
209 b43_radio_set(dev
, B2062_S_RFPLL_CTL1
, 0x4);
212 tmp
= (800000000 * pdiv
+ crystalfreq
) / (32000000 * pdiv
);
213 tmp
= (tmp
- 1) & 0xFF;
214 b43_radio_write(dev
, B2062_S_RFPLL_CTL18
, tmp
);
216 tmp
= (2 * crystalfreq
+ 1000000 * pdiv
) / (2000000 * pdiv
);
217 tmp
= ((tmp
& 0xFF) - 1) & 0xFFFF;
218 b43_radio_write(dev
, B2062_S_RFPLL_CTL19
, tmp
);
220 ref
= (1000 * pdiv
+ 2 * crystalfreq
) / (2000 * pdiv
);
222 for (i
= 0; i
< ARRAY_SIZE(freqdata_tab
); i
++) {
223 if (ref
< freqdata_tab
[i
].freq
) {
224 fd
= &freqdata_tab
[i
];
229 fd
= &freqdata_tab
[ARRAY_SIZE(freqdata_tab
) - 1];
230 b43dbg(dev
->wl
, "b2062: Using crystal tab entry %u kHz.\n",
231 fd
->freq
); /* FIXME: Keep this printk until the code is fully debugged. */
233 b43_radio_write(dev
, B2062_S_RFPLL_CTL8
,
234 ((u16
)(fd
->data
[1]) << 4) | fd
->data
[0]);
235 b43_radio_write(dev
, B2062_S_RFPLL_CTL9
,
236 ((u16
)(fd
->data
[3]) << 4) | fd
->data
[2]);
237 b43_radio_write(dev
, B2062_S_RFPLL_CTL10
, fd
->data
[4]);
238 b43_radio_write(dev
, B2062_S_RFPLL_CTL11
, fd
->data
[5]);
241 /* Initialize the 2063 radio. */
242 static void lpphy_2063_init(struct b43_wldev
*dev
)
247 static void lpphy_sync_stx(struct b43_wldev
*dev
)
252 static void lpphy_radio_init(struct b43_wldev
*dev
)
254 /* The radio is attached through the 4wire bus. */
255 b43_phy_set(dev
, B43_LPPHY_FOURWIRE_CTL
, 0x2);
257 b43_phy_mask(dev
, B43_LPPHY_FOURWIRE_CTL
, 0xFFFD);
260 if (dev
->phy
.rev
< 2) {
261 lpphy_2062_init(dev
);
263 lpphy_2063_init(dev
);
265 b43_phy_write(dev
, B43_PHY_OFDM(0xF0), 0x5F80);
266 b43_phy_write(dev
, B43_PHY_OFDM(0xF1), 0);
267 //TODO Do something on the backplane
271 /* Read the TX power control mode from hardware. */
272 static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev
*dev
)
274 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
277 ctl
= b43_phy_read(dev
, B43_LPPHY_TX_PWR_CTL_CMD
);
278 switch (ctl
& B43_LPPHY_TX_PWR_CTL_CMD_MODE
) {
279 case B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF
:
280 lpphy
->txpctl_mode
= B43_LPPHY_TXPCTL_OFF
;
282 case B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW
:
283 lpphy
->txpctl_mode
= B43_LPPHY_TXPCTL_SW
;
285 case B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW
:
286 lpphy
->txpctl_mode
= B43_LPPHY_TXPCTL_HW
;
289 lpphy
->txpctl_mode
= B43_LPPHY_TXPCTL_UNKNOWN
;
295 /* Set the TX power control mode in hardware. */
296 static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev
*dev
)
298 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
301 switch (lpphy
->txpctl_mode
) {
302 case B43_LPPHY_TXPCTL_OFF
:
303 ctl
= B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF
;
305 case B43_LPPHY_TXPCTL_HW
:
306 ctl
= B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW
;
308 case B43_LPPHY_TXPCTL_SW
:
309 ctl
= B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW
;
315 b43_phy_maskset(dev
, B43_LPPHY_TX_PWR_CTL_CMD
,
316 (u16
)~B43_LPPHY_TX_PWR_CTL_CMD_MODE
, ctl
);
319 static void lpphy_set_tx_power_control(struct b43_wldev
*dev
,
320 enum b43_lpphy_txpctl_mode mode
)
322 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
323 enum b43_lpphy_txpctl_mode oldmode
;
325 oldmode
= lpphy
->txpctl_mode
;
326 lpphy_read_tx_pctl_mode_from_hardware(dev
);
327 if (lpphy
->txpctl_mode
== mode
)
329 lpphy
->txpctl_mode
= mode
;
331 if (oldmode
== B43_LPPHY_TXPCTL_HW
) {
332 //TODO Update TX Power NPT
333 //TODO Clear all TX Power offsets
335 if (mode
== B43_LPPHY_TXPCTL_HW
) {
336 //TODO Recalculate target TX power
337 b43_phy_maskset(dev
, B43_LPPHY_TX_PWR_CTL_CMD
,
338 0xFF80, lpphy
->tssi_idx
);
339 b43_phy_maskset(dev
, B43_LPPHY_TX_PWR_CTL_NNUM
,
340 0x8FFF, ((u16
)lpphy
->tssi_npt
<< 16));
341 //TODO Set "TSSI Transmit Count" variable to total transmitted frame count
342 //TODO Disable TX gain override
343 lpphy
->tx_pwr_idx_over
= -1;
346 if (dev
->phy
.rev
>= 2) {
347 if (mode
== B43_LPPHY_TXPCTL_HW
)
348 b43_phy_maskset(dev
, B43_PHY_OFDM(0xD0), 0xFD, 0x2);
350 b43_phy_maskset(dev
, B43_PHY_OFDM(0xD0), 0xFD, 0);
352 lpphy_write_tx_pctl_mode_to_hardware(dev
);
355 static void lpphy_set_tx_power_by_index(struct b43_wldev
*dev
, u8 index
)
357 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
359 lpphy
->tx_pwr_idx_over
= index
;
360 if (lpphy
->txpctl_mode
!= B43_LPPHY_TXPCTL_OFF
)
361 lpphy_set_tx_power_control(dev
, B43_LPPHY_TXPCTL_SW
);
366 static void lpphy_btcoex_override(struct b43_wldev
*dev
)
368 b43_write16(dev
, B43_MMIO_BTCOEX_CTL
, 0x3);
369 b43_write16(dev
, B43_MMIO_BTCOEX_TXCTL
, 0xFF);
372 static void lpphy_pr41573_workaround(struct b43_wldev
*dev
)
374 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
376 const unsigned int saved_tab_size
= 256;
377 enum b43_lpphy_txpctl_mode txpctl_mode
;
379 u16 tssi_npt
, tssi_idx
;
381 saved_tab
= kcalloc(saved_tab_size
, sizeof(saved_tab
[0]), GFP_KERNEL
);
383 b43err(dev
->wl
, "PR41573 failed. Out of memory!\n");
387 lpphy_read_tx_pctl_mode_from_hardware(dev
);
388 txpctl_mode
= lpphy
->txpctl_mode
;
389 tx_pwr_idx_over
= lpphy
->tx_pwr_idx_over
;
390 tssi_npt
= lpphy
->tssi_npt
;
391 tssi_idx
= lpphy
->tssi_idx
;
393 if (dev
->phy
.rev
< 2) {
394 b43_lptab_read_bulk(dev
, B43_LPTAB32(10, 0x140),
395 saved_tab_size
, saved_tab
);
397 b43_lptab_read_bulk(dev
, B43_LPTAB32(7, 0x140),
398 saved_tab_size
, saved_tab
);
405 static void lpphy_calibration(struct b43_wldev
*dev
)
407 struct b43_phy_lp
*lpphy
= dev
->phy
.lp
;
408 enum b43_lpphy_txpctl_mode saved_pctl_mode
;
410 b43_mac_suspend(dev
);
412 lpphy_btcoex_override(dev
);
413 lpphy_read_tx_pctl_mode_from_hardware(dev
);
414 saved_pctl_mode
= lpphy
->txpctl_mode
;
415 lpphy_set_tx_power_control(dev
, B43_LPPHY_TXPCTL_OFF
);
416 //TODO Perform transmit power table I/Q LO calibration
417 if ((dev
->phy
.rev
== 0) && (saved_pctl_mode
!= B43_LPPHY_TXPCTL_OFF
))
418 lpphy_pr41573_workaround(dev
);
419 //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration
420 lpphy_set_tx_power_control(dev
, saved_pctl_mode
);
421 //TODO Perform I/Q calibration with a single control value set
426 /* Initialize TX power control */
427 static void lpphy_tx_pctl_init(struct b43_wldev
*dev
)
429 if (0/*FIXME HWPCTL capable */) {
431 } else { /* This device is only software TX power control capable. */
432 if (b43_current_band(dev
->wl
) == IEEE80211_BAND_2GHZ
) {
437 //TODO set BB multiplier to 0x0096
441 static int b43_lpphy_op_init(struct b43_wldev
*dev
)
443 /* TODO: band SPROM */
444 lpphy_baseband_init(dev
);
445 lpphy_radio_init(dev
);
448 lpphy_tx_pctl_init(dev
);
454 static u16
b43_lpphy_op_read(struct b43_wldev
*dev
, u16 reg
)
456 b43_write16(dev
, B43_MMIO_PHY_CONTROL
, reg
);
457 return b43_read16(dev
, B43_MMIO_PHY_DATA
);
460 static void b43_lpphy_op_write(struct b43_wldev
*dev
, u16 reg
, u16 value
)
462 b43_write16(dev
, B43_MMIO_PHY_CONTROL
, reg
);
463 b43_write16(dev
, B43_MMIO_PHY_DATA
, value
);
466 static u16
b43_lpphy_op_radio_read(struct b43_wldev
*dev
, u16 reg
)
468 /* Register 1 is a 32-bit register. */
469 B43_WARN_ON(reg
== 1);
470 /* LP-PHY needs a special bit set for read access */
471 if (dev
->phy
.rev
< 2) {
477 b43_write16(dev
, B43_MMIO_RADIO_CONTROL
, reg
);
478 return b43_read16(dev
, B43_MMIO_RADIO_DATA_LOW
);
481 static void b43_lpphy_op_radio_write(struct b43_wldev
*dev
, u16 reg
, u16 value
)
483 /* Register 1 is a 32-bit register. */
484 B43_WARN_ON(reg
== 1);
486 b43_write16(dev
, B43_MMIO_RADIO_CONTROL
, reg
);
487 b43_write16(dev
, B43_MMIO_RADIO_DATA_LOW
, value
);
490 static void b43_lpphy_op_software_rfkill(struct b43_wldev
*dev
,
496 static int b43_lpphy_op_switch_channel(struct b43_wldev
*dev
,
497 unsigned int new_channel
)
503 static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev
*dev
)
505 if (b43_current_band(dev
->wl
) == IEEE80211_BAND_2GHZ
)
510 static void b43_lpphy_op_set_rx_antenna(struct b43_wldev
*dev
, int antenna
)
515 static void b43_lpphy_op_adjust_txpower(struct b43_wldev
*dev
)
520 static enum b43_txpwr_result
b43_lpphy_op_recalc_txpower(struct b43_wldev
*dev
,
524 return B43_TXPWR_RES_DONE
;
528 const struct b43_phy_operations b43_phyops_lp
= {
529 .allocate
= b43_lpphy_op_allocate
,
530 .free
= b43_lpphy_op_free
,
531 .prepare_structs
= b43_lpphy_op_prepare_structs
,
532 .init
= b43_lpphy_op_init
,
533 .phy_read
= b43_lpphy_op_read
,
534 .phy_write
= b43_lpphy_op_write
,
535 .radio_read
= b43_lpphy_op_radio_read
,
536 .radio_write
= b43_lpphy_op_radio_write
,
537 .software_rfkill
= b43_lpphy_op_software_rfkill
,
538 .switch_analog
= b43_phyop_switch_analog_generic
,
539 .switch_channel
= b43_lpphy_op_switch_channel
,
540 .get_default_chan
= b43_lpphy_op_get_default_chan
,
541 .set_rx_antenna
= b43_lpphy_op_set_rx_antenna
,
542 .recalc_txpower
= b43_lpphy_op_recalc_txpower
,
543 .adjust_txpower
= b43_lpphy_op_adjust_txpower
,