aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/main.c26
-rw-r--r--drivers/net/wireless/b43/phy_n.c479
-rw-r--r--drivers/net/wireless/b43/phy_n.h21
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c22
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h37
-rw-r--r--drivers/net/wireless/b43/xmit.c1
7 files changed, 452 insertions, 135 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index b8807fb12c92..3a003e6803a5 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -104,6 +104,7 @@
104#define B43_MMIO_MACFILTER_CONTROL 0x420 104#define B43_MMIO_MACFILTER_CONTROL 0x420
105#define B43_MMIO_MACFILTER_DATA 0x422 105#define B43_MMIO_MACFILTER_DATA 0x422
106#define B43_MMIO_RCMTA_COUNT 0x43C 106#define B43_MMIO_RCMTA_COUNT 0x43C
107#define B43_MMIO_PSM_PHY_HDR 0x492
107#define B43_MMIO_RADIO_HWENABLED_LO 0x49A 108#define B43_MMIO_RADIO_HWENABLED_LO 0x49A
108#define B43_MMIO_GPIO_CONTROL 0x49C 109#define B43_MMIO_GPIO_CONTROL 0x49C
109#define B43_MMIO_GPIO_MASK 0x49E 110#define B43_MMIO_GPIO_MASK 0x49E
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9a374ef83a22..7965b70efbab 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4349,11 +4349,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4349 b43_set_phytxctl_defaults(dev); 4349 b43_set_phytxctl_defaults(dev);
4350 4350
4351 /* Minimum Contention Window */ 4351 /* Minimum Contention Window */
4352 if (phy->type == B43_PHYTYPE_B) { 4352 if (phy->type == B43_PHYTYPE_B)
4353 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F); 4353 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F);
4354 } else { 4354 else
4355 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF); 4355 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF);
4356 }
4357 /* Maximum Contention Window */ 4356 /* Maximum Contention Window */
4358 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4357 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4359 4358
@@ -4572,6 +4571,23 @@ static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
4572 mutex_unlock(&wl->mutex); 4571 mutex_unlock(&wl->mutex);
4573} 4572}
4574 4573
4574static int b43_op_get_survey(struct ieee80211_hw *hw, int idx,
4575 struct survey_info *survey)
4576{
4577 struct b43_wl *wl = hw_to_b43_wl(hw);
4578 struct b43_wldev *dev = wl->current_dev;
4579 struct ieee80211_conf *conf = &hw->conf;
4580
4581 if (idx != 0)
4582 return -ENOENT;
4583
4584 survey->channel = conf->channel;
4585 survey->filled = SURVEY_INFO_NOISE_DBM;
4586 survey->noise = dev->stats.link_noise;
4587
4588 return 0;
4589}
4590
4575static const struct ieee80211_ops b43_hw_ops = { 4591static const struct ieee80211_ops b43_hw_ops = {
4576 .tx = b43_op_tx, 4592 .tx = b43_op_tx,
4577 .conf_tx = b43_op_conf_tx, 4593 .conf_tx = b43_op_conf_tx,
@@ -4591,6 +4607,7 @@ static const struct ieee80211_ops b43_hw_ops = {
4591 .sta_notify = b43_op_sta_notify, 4607 .sta_notify = b43_op_sta_notify,
4592 .sw_scan_start = b43_op_sw_scan_start_notifier, 4608 .sw_scan_start = b43_op_sw_scan_start_notifier,
4593 .sw_scan_complete = b43_op_sw_scan_complete_notifier, 4609 .sw_scan_complete = b43_op_sw_scan_complete_notifier,
4610 .get_survey = b43_op_get_survey,
4594 .rfkill_poll = b43_rfkill_poll, 4611 .rfkill_poll = b43_rfkill_poll,
4595}; 4612};
4596 4613
@@ -4906,8 +4923,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4906 4923
4907 /* fill hw info */ 4924 /* fill hw info */
4908 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 4925 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
4909 IEEE80211_HW_SIGNAL_DBM | 4926 IEEE80211_HW_SIGNAL_DBM;
4910 IEEE80211_HW_NOISE_DBM;
4911 4927
4912 hw->wiphy->interface_modes = 4928 hw->wiphy->interface_modes =
4913 BIT(NL80211_IFTYPE_AP) | 4929 BIT(NL80211_IFTYPE_AP) |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 9c7cd282e46c..3d6b33775964 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -73,6 +73,22 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
73 u16 value, u8 core, bool off); 73 u16 value, u8 core, bool off);
74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, 74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
75 u16 value, u8 core); 75 u16 value, u8 core);
76static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel);
77
78static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
79{
80 return !chanspec->channel && !chanspec->sideband &&
81 !chanspec->b_width && !chanspec->b_freq;
82}
83
84static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
85 struct b43_chanspec *chanspec2)
86{
87 return (chanspec1->channel == chanspec2->channel &&
88 chanspec1->sideband == chanspec2->sideband &&
89 chanspec1->b_width == chanspec2->b_width &&
90 chanspec1->b_freq == chanspec2->b_freq);
91}
76 92
77void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 93void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
78{//TODO 94{//TODO
@@ -89,34 +105,44 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
89} 105}
90 106
91static void b43_chantab_radio_upload(struct b43_wldev *dev, 107static void b43_chantab_radio_upload(struct b43_wldev *dev,
92 const struct b43_nphy_channeltab_entry *e) 108 const struct b43_nphy_channeltab_entry_rev2 *e)
93{ 109{
94 b43_radio_write16(dev, B2055_PLL_REF, e->radio_pll_ref); 110 b43_radio_write(dev, B2055_PLL_REF, e->radio_pll_ref);
95 b43_radio_write16(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0); 111 b43_radio_write(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0);
96 b43_radio_write16(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1); 112 b43_radio_write(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1);
97 b43_radio_write16(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail); 113 b43_radio_write(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail);
98 b43_radio_write16(dev, B2055_VCO_CAL1, e->radio_vco_cal1); 114 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
99 b43_radio_write16(dev, B2055_VCO_CAL2, e->radio_vco_cal2); 115
100 b43_radio_write16(dev, B2055_PLL_LFC1, e->radio_pll_lfc1); 116 b43_radio_write(dev, B2055_VCO_CAL1, e->radio_vco_cal1);
101 b43_radio_write16(dev, B2055_PLL_LFR1, e->radio_pll_lfr1); 117 b43_radio_write(dev, B2055_VCO_CAL2, e->radio_vco_cal2);
102 b43_radio_write16(dev, B2055_PLL_LFC2, e->radio_pll_lfc2); 118 b43_radio_write(dev, B2055_PLL_LFC1, e->radio_pll_lfc1);
103 b43_radio_write16(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf); 119 b43_radio_write(dev, B2055_PLL_LFR1, e->radio_pll_lfr1);
104 b43_radio_write16(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1); 120 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
105 b43_radio_write16(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2); 121
106 b43_radio_write16(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune); 122 b43_radio_write(dev, B2055_PLL_LFC2, e->radio_pll_lfc2);
107 b43_radio_write16(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune); 123 b43_radio_write(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf);
108 b43_radio_write16(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1); 124 b43_radio_write(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1);
109 b43_radio_write16(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn); 125 b43_radio_write(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2);
110 b43_radio_write16(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim); 126 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
111 b43_radio_write16(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune); 127
112 b43_radio_write16(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune); 128 b43_radio_write(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune);
113 b43_radio_write16(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1); 129 b43_radio_write(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune);
114 b43_radio_write16(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn); 130 b43_radio_write(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1);
115 b43_radio_write16(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); 131 b43_radio_write(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn);
132 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
133
134 b43_radio_write(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim);
135 b43_radio_write(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune);
136 b43_radio_write(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune);
137 b43_radio_write(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1);
138 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
139
140 b43_radio_write(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn);
141 b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
116} 142}
117 143
118static void b43_chantab_phy_upload(struct b43_wldev *dev, 144static void b43_chantab_phy_upload(struct b43_wldev *dev,
119 const struct b43_nphy_channeltab_entry *e) 145 const struct b43_phy_n_sfo_cfg *e)
120{ 146{
121 b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a); 147 b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a);
122 b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2); 148 b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2);
@@ -131,34 +157,20 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
131 //TODO 157 //TODO
132} 158}
133 159
134/* Tune the hardware to a new channel. */
135static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
136{
137 const struct b43_nphy_channeltab_entry *tabent;
138 160
139 tabent = b43_nphy_get_chantabent(dev, channel); 161/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */
140 if (!tabent) 162static void b43_radio_2055_setup(struct b43_wldev *dev,
141 return -ESRCH; 163 const struct b43_nphy_channeltab_entry_rev2 *e)
164{
165 B43_WARN_ON(dev->phy.rev >= 3);
142 166
143 //FIXME enable/disable band select upper20 in RXCTL 167 b43_chantab_radio_upload(dev, e);
144 if (0 /*FIXME 5Ghz*/)
145 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x20);
146 else
147 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x50);
148 b43_chantab_radio_upload(dev, tabent);
149 udelay(50); 168 udelay(50);
150 b43_radio_write16(dev, B2055_VCO_CAL10, 5); 169 b43_radio_write(dev, B2055_VCO_CAL10, 0x05);
151 b43_radio_write16(dev, B2055_VCO_CAL10, 45); 170 b43_radio_write(dev, B2055_VCO_CAL10, 0x45);
152 b43_radio_write16(dev, B2055_VCO_CAL10, 65); 171 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
172 b43_radio_write(dev, B2055_VCO_CAL10, 0x65);
153 udelay(300); 173 udelay(300);
154 if (0 /*FIXME 5Ghz*/)
155 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
156 else
157 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
158 b43_chantab_phy_upload(dev, tabent);
159 b43_nphy_tx_power_fix(dev);
160
161 return 0;
162} 174}
163 175
164static void b43_radio_init2055_pre(struct b43_wldev *dev) 176static void b43_radio_init2055_pre(struct b43_wldev *dev)
@@ -174,52 +186,64 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev)
174 186
175static void b43_radio_init2055_post(struct b43_wldev *dev) 187static void b43_radio_init2055_post(struct b43_wldev *dev)
176{ 188{
189 struct b43_phy_n *nphy = dev->phy.n;
177 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 190 struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
178 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); 191 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo);
179 int i; 192 int i;
180 u16 val; 193 u16 val;
194 bool workaround = false;
195
196 if (sprom->revision < 4)
197 workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM ||
198 binfo->type != 0x46D ||
199 binfo->rev < 0x41);
200 else
201 workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0);
181 202
182 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); 203 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
183 msleep(1); 204 if (workaround) {
184 if ((sprom->revision != 4) || 205 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
185 !(sprom->boardflags_hi & B43_BFH_RSSIINV)) { 206 b43_radio_mask(dev, B2055_C2_RX_BB_REG, 0x7F);
186 if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) ||
187 (binfo->type != 0x46D) ||
188 (binfo->rev < 0x41)) {
189 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
190 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
191 msleep(1);
192 }
193 } 207 }
194 b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0x3F, 0x2C); 208 b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C);
195 msleep(1); 209 b43_radio_write(dev, B2055_CAL_MISC, 0x3C);
196 b43_radio_write16(dev, B2055_CAL_MISC, 0x3C);
197 msleep(1);
198 b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); 210 b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE);
199 msleep(1);
200 b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); 211 b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80);
201 msleep(1);
202 b43_radio_set(dev, B2055_CAL_MISC, 0x1); 212 b43_radio_set(dev, B2055_CAL_MISC, 0x1);
203 msleep(1); 213 msleep(1);
204 b43_radio_set(dev, B2055_CAL_MISC, 0x40); 214 b43_radio_set(dev, B2055_CAL_MISC, 0x40);
205 msleep(1); 215 for (i = 0; i < 200; i++) {
206 for (i = 0; i < 100; i++) { 216 val = b43_radio_read(dev, B2055_CAL_COUT2);
207 val = b43_radio_read16(dev, B2055_CAL_COUT2); 217 if (val & 0x80) {
208 if (val & 0x80) 218 i = 0;
209 break; 219 break;
220 }
210 udelay(10); 221 udelay(10);
211 } 222 }
212 msleep(1); 223 if (i)
224 b43err(dev->wl, "radio post init timeout\n");
213 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); 225 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
214 msleep(1);
215 nphy_channel_switch(dev, dev->phy.channel); 226 nphy_channel_switch(dev, dev->phy.channel);
216 b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9); 227 b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
217 b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9); 228 b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
218 b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83); 229 b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
219 b43_radio_write16(dev, B2055_C2_RX_BB_MIDACHP, 0x83); 230 b43_radio_write(dev, B2055_C2_RX_BB_MIDACHP, 0x83);
231 b43_radio_maskset(dev, B2055_C1_LNA_GAINBST, 0xFFF8, 0x6);
232 b43_radio_maskset(dev, B2055_C2_LNA_GAINBST, 0xFFF8, 0x6);
233 if (!nphy->gain_boost) {
234 b43_radio_set(dev, B2055_C1_RX_RFSPC1, 0x2);
235 b43_radio_set(dev, B2055_C2_RX_RFSPC1, 0x2);
236 } else {
237 b43_radio_mask(dev, B2055_C1_RX_RFSPC1, 0xFFFD);
238 b43_radio_mask(dev, B2055_C2_RX_RFSPC1, 0xFFFD);
239 }
240 udelay(2);
220} 241}
221 242
222/* Initialize a Broadcom 2055 N-radio */ 243/*
244 * Initialize a Broadcom 2055 N-radio
245 * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init
246 */
223static void b43_radio_init2055(struct b43_wldev *dev) 247static void b43_radio_init2055(struct b43_wldev *dev)
224{ 248{
225 b43_radio_init2055_pre(dev); 249 b43_radio_init2055_pre(dev);
@@ -230,16 +254,15 @@ static void b43_radio_init2055(struct b43_wldev *dev)
230 b43_radio_init2055_post(dev); 254 b43_radio_init2055_post(dev);
231} 255}
232 256
233void b43_nphy_radio_turn_on(struct b43_wldev *dev) 257/*
258 * Initialize a Broadcom 2056 N-radio
259 * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
260 */
261static void b43_radio_init2056(struct b43_wldev *dev)
234{ 262{
235 b43_radio_init2055(dev); 263 /* TODO */
236} 264}
237 265
238void b43_nphy_radio_turn_off(struct b43_wldev *dev)
239{
240 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
241 ~B43_NPHY_RFCTL_CMD_EN);
242}
243 266
244/* 267/*
245 * Upload the N-PHY tables. 268 * Upload the N-PHY tables.
@@ -647,6 +670,41 @@ static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
647 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); 670 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
648} 671}
649 672
673/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
674static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
675{
676 if (dev->phy.rev >= 3) {
677 if (!init)
678 return;
679 if (0 /* FIXME */) {
680 b43_ntab_write(dev, B43_NTAB16(9, 2), 0x211);
681 b43_ntab_write(dev, B43_NTAB16(9, 3), 0x222);
682 b43_ntab_write(dev, B43_NTAB16(9, 8), 0x144);
683 b43_ntab_write(dev, B43_NTAB16(9, 12), 0x188);
684 }
685 } else {
686 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
687 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
688
689 ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00,
690 0xFC00);
691 b43_write32(dev, B43_MMIO_MACCTL,
692 b43_read32(dev, B43_MMIO_MACCTL) &
693 ~B43_MACCTL_GPOUTSMSK);
694 b43_write16(dev, B43_MMIO_GPIO_MASK,
695 b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00);
696 b43_write16(dev, B43_MMIO_GPIO_CONTROL,
697 b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00);
698
699 if (init) {
700 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
701 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
702 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
703 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
704 }
705 }
706}
707
650/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ 708/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
651static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) 709static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
652{ 710{
@@ -723,7 +781,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
723{ 781{
724 struct b43_phy_n *nphy = dev->phy.n; 782 struct b43_phy_n *nphy = dev->phy.n;
725 783
726 unsigned int channel; 784 u8 channel = nphy->radio_chanspec.channel;
727 int tone[2] = { 57, 58 }; 785 int tone[2] = { 57, 58 };
728 u32 noise[2] = { 0x3FF, 0x3FF }; 786 u32 noise[2] = { 0x3FF, 0x3FF };
729 787
@@ -732,8 +790,6 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
732 if (nphy->hang_avoid) 790 if (nphy->hang_avoid)
733 b43_nphy_stay_in_carrier_search(dev, 1); 791 b43_nphy_stay_in_carrier_search(dev, 1);
734 792
735 /* FIXME: channel = radio_chanspec */
736
737 if (nphy->gband_spurwar_en) { 793 if (nphy->gband_spurwar_en) {
738 /* TODO: N PHY Adjust Analog Pfbw (7) */ 794 /* TODO: N PHY Adjust Analog Pfbw (7) */
739 if (channel == 11 && dev->phy.is_40mhz) 795 if (channel == 11 && dev->phy.is_40mhz)
@@ -779,6 +835,62 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
779 b43_nphy_stay_in_carrier_search(dev, 0); 835 b43_nphy_stay_in_carrier_search(dev, 0);
780} 836}
781 837
838/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
839static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
840{
841 struct b43_phy_n *nphy = dev->phy.n;
842
843 u8 i;
844 s16 tmp;
845 u16 data[4];
846 s16 gain[2];
847 u16 minmax[2];
848 u16 lna_gain[4] = { -2, 10, 19, 25 };
849
850 if (nphy->hang_avoid)
851 b43_nphy_stay_in_carrier_search(dev, 1);
852
853 if (nphy->gain_boost) {
854 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
855 gain[0] = 6;
856 gain[1] = 6;
857 } else {
858 tmp = 40370 - 315 * nphy->radio_chanspec.channel;
859 gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
860 tmp = 23242 - 224 * nphy->radio_chanspec.channel;
861 gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
862 }
863 } else {
864 gain[0] = 0;
865 gain[1] = 0;
866 }
867
868 for (i = 0; i < 2; i++) {
869 if (nphy->elna_gain_config) {
870 data[0] = 19 + gain[i];
871 data[1] = 25 + gain[i];
872 data[2] = 25 + gain[i];
873 data[3] = 25 + gain[i];
874 } else {
875 data[0] = lna_gain[0] + gain[i];
876 data[1] = lna_gain[1] + gain[i];
877 data[2] = lna_gain[2] + gain[i];
878 data[3] = lna_gain[3] + gain[i];
879 }
880 b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data);
881
882 minmax[i] = 23 + gain[i];
883 }
884
885 b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN,
886 minmax[0] << B43_NPHY_C1_MINGAIN_SHIFT);
887 b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN,
888 minmax[1] << B43_NPHY_C2_MINGAIN_SHIFT);
889
890 if (nphy->hang_avoid)
891 b43_nphy_stay_in_carrier_search(dev, 0);
892}
893
782/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ 894/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
783static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) 895static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
784{ 896{
@@ -863,7 +975,7 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
863 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 975 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
864 (code << 8 | 0x7C)); 976 (code << 8 | 0x7C));
865 977
866 /* TODO: b43_nphy_adjust_lna_gain_table(dev); */ 978 b43_nphy_adjust_lna_gain_table(dev);
867 979
868 if (nphy->elna_gain_config) { 980 if (nphy->elna_gain_config) {
869 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); 981 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
@@ -1970,12 +2082,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
1970 u16 *rssical_phy_regs = NULL; 2082 u16 *rssical_phy_regs = NULL;
1971 2083
1972 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2084 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1973 if (!nphy->rssical_chanspec_2G) 2085 if (b43_empty_chanspec(&nphy->rssical_chanspec_2G))
1974 return; 2086 return;
1975 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; 2087 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
1976 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; 2088 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
1977 } else { 2089 } else {
1978 if (!nphy->rssical_chanspec_5G) 2090 if (b43_empty_chanspec(&nphy->rssical_chanspec_5G))
1979 return; 2091 return;
1980 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; 2092 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
1981 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; 2093 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2395,7 +2507,7 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
2395 2507
2396 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 2508 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2397 u16 *txcal_radio_regs = NULL; 2509 u16 *txcal_radio_regs = NULL;
2398 u8 *iqcal_chanspec; 2510 struct b43_chanspec *iqcal_chanspec;
2399 u16 *table = NULL; 2511 u16 *table = NULL;
2400 2512
2401 if (nphy->hang_avoid) 2513 if (nphy->hang_avoid)
@@ -2451,12 +2563,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
2451 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 2563 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2452 2564
2453 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2565 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2454 if (nphy->iqcal_chanspec_2G == 0) 2566 if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G))
2455 return; 2567 return;
2456 table = nphy->cal_cache.txcal_coeffs_2G; 2568 table = nphy->cal_cache.txcal_coeffs_2G;
2457 loft = &nphy->cal_cache.txcal_coeffs_2G[5]; 2569 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
2458 } else { 2570 } else {
2459 if (nphy->iqcal_chanspec_5G == 0) 2571 if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G))
2460 return; 2572 return;
2461 table = nphy->cal_cache.txcal_coeffs_5G; 2573 table = nphy->cal_cache.txcal_coeffs_5G;
2462 loft = &nphy->cal_cache.txcal_coeffs_5G[5]; 2574 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2689,7 +2801,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2689 } 2801 }
2690 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, 2802 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
2691 buffer); 2803 buffer);
2692 b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2, 2804 b43_ntab_read_bulk(dev, B43_NTAB16(15, 101), 2,
2693 buffer); 2805 buffer);
2694 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, 2806 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
2695 buffer); 2807 buffer);
@@ -2701,8 +2813,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2701 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, 2813 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2702 nphy->txiqlocal_bestc); 2814 nphy->txiqlocal_bestc);
2703 nphy->txiqlocal_coeffsvalid = true; 2815 nphy->txiqlocal_coeffsvalid = true;
2704 /* TODO: Set nphy->txiqlocal_chanspec to 2816 nphy->txiqlocal_chanspec = nphy->radio_chanspec;
2705 the current channel */
2706 } else { 2817 } else {
2707 length = 11; 2818 length = 11;
2708 if (dev->phy.rev < 3) 2819 if (dev->phy.rev < 3)
@@ -2737,7 +2848,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2737 u16 buffer[7]; 2848 u16 buffer[7];
2738 bool equal = true; 2849 bool equal = true;
2739 2850
2740 if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */) 2851 if (!nphy->txiqlocal_coeffsvalid ||
2852 b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec))
2741 return; 2853 return;
2742 2854
2743 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); 2855 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -3092,9 +3204,11 @@ int b43_phy_initn(struct b43_wldev *dev)
3092 do_rssi_cal = false; 3204 do_rssi_cal = false;
3093 if (phy->rev >= 3) { 3205 if (phy->rev >= 3) {
3094 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3206 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3095 do_rssi_cal = (nphy->rssical_chanspec_2G == 0); 3207 do_rssi_cal =
3208 b43_empty_chanspec(&nphy->rssical_chanspec_2G);
3096 else 3209 else
3097 do_rssi_cal = (nphy->rssical_chanspec_5G == 0); 3210 do_rssi_cal =
3211 b43_empty_chanspec(&nphy->rssical_chanspec_5G);
3098 3212
3099 if (do_rssi_cal) 3213 if (do_rssi_cal)
3100 b43_nphy_rssi_cal(dev); 3214 b43_nphy_rssi_cal(dev);
@@ -3106,9 +3220,9 @@ int b43_phy_initn(struct b43_wldev *dev)
3106 3220
3107 if (!((nphy->measure_hold & 0x6) != 0)) { 3221 if (!((nphy->measure_hold & 0x6) != 0)) {
3108 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3222 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3109 do_cal = (nphy->iqcal_chanspec_2G == 0); 3223 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G);
3110 else 3224 else
3111 do_cal = (nphy->iqcal_chanspec_5G == 0); 3225 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G);
3112 3226
3113 if (nphy->mute) 3227 if (nphy->mute)
3114 do_cal = false; 3228 do_cal = false;
@@ -3117,7 +3231,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3117 target = b43_nphy_get_tx_gains(dev); 3231 target = b43_nphy_get_tx_gains(dev);
3118 3232
3119 if (nphy->antsel_type == 2) 3233 if (nphy->antsel_type == 2)
3120 ;/*TODO NPHY Superswitch Init with argument 1*/ 3234 b43_nphy_superswitch_init(dev, true);
3121 if (nphy->perical != 2) { 3235 if (nphy->perical != 2) {
3122 b43_nphy_rssi_cal(dev); 3236 b43_nphy_rssi_cal(dev);
3123 if (phy->rev >= 3) { 3237 if (phy->rev >= 3) {
@@ -3155,6 +3269,133 @@ int b43_phy_initn(struct b43_wldev *dev)
3155 return 0; 3269 return 0;
3156} 3270}
3157 3271
3272/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
3273static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3274 const struct b43_phy_n_sfo_cfg *e,
3275 struct b43_chanspec chanspec)
3276{
3277 struct b43_phy *phy = &dev->phy;
3278 struct b43_phy_n *nphy = dev->phy.n;
3279
3280 u16 tmp;
3281 u32 tmp32;
3282
3283 tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
3284 if (chanspec.b_freq == 1 && tmp == 0) {
3285 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3286 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3287 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
3288 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3289 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
3290 } else if (chanspec.b_freq == 1) {
3291 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
3292 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3293 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3294 b43_phy_mask(dev, B43_PHY_B_BBCFG, (u16)~0xC000);
3295 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3296 }
3297
3298 b43_chantab_phy_upload(dev, e);
3299
3300 tmp = chanspec.channel;
3301 if (chanspec.b_freq == 1)
3302 tmp |= 0x0100;
3303 if (chanspec.b_width == 3)
3304 tmp |= 0x0200;
3305 b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp);
3306
3307 if (nphy->radio_chanspec.channel == 14) {
3308 b43_nphy_classifier(dev, 2, 0);
3309 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
3310 } else {
3311 b43_nphy_classifier(dev, 2, 2);
3312 if (chanspec.b_freq == 2)
3313 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
3314 }
3315
3316 if (nphy->txpwrctrl)
3317 b43_nphy_tx_power_fix(dev);
3318
3319 if (dev->phy.rev < 3)
3320 b43_nphy_adjust_lna_gain_table(dev);
3321
3322 b43_nphy_tx_lp_fbw(dev);
3323
3324 if (dev->phy.rev >= 3 && 0) {
3325 /* TODO */
3326 }
3327
3328 b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830);
3329
3330 if (phy->rev >= 3)
3331 b43_nphy_spur_workaround(dev);
3332}
3333
3334/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
3335static int b43_nphy_set_chanspec(struct b43_wldev *dev,
3336 struct b43_chanspec chanspec)
3337{
3338 struct b43_phy_n *nphy = dev->phy.n;
3339
3340 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
3341 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
3342
3343 u8 tmp;
3344 u8 channel = chanspec.channel;
3345
3346 if (dev->phy.rev >= 3) {
3347 /* TODO */
3348 tabent_r3 = NULL;
3349 if (!tabent_r3)
3350 return -ESRCH;
3351 } else {
3352 tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel);
3353 if (!tabent_r2)
3354 return -ESRCH;
3355 }
3356
3357 nphy->radio_chanspec = chanspec;
3358
3359 if (chanspec.b_width != nphy->b_width)
3360 ; /* TODO: BMAC BW Set (chanspec.b_width) */
3361
3362 /* TODO: use defines */
3363 if (chanspec.b_width == 3) {
3364 if (chanspec.sideband == 2)
3365 b43_phy_set(dev, B43_NPHY_RXCTL,
3366 B43_NPHY_RXCTL_BSELU20);
3367 else
3368 b43_phy_mask(dev, B43_NPHY_RXCTL,
3369 ~B43_NPHY_RXCTL_BSELU20);
3370 }
3371
3372 if (dev->phy.rev >= 3) {
3373 tmp = (chanspec.b_freq == 1) ? 4 : 0;
3374 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
3375 /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
3376 b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec);
3377 } else {
3378 tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050;
3379 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
3380 b43_radio_2055_setup(dev, tabent_r2);
3381 b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec);
3382 }
3383
3384 return 0;
3385}
3386
3387/* Tune the hardware to a new channel */
3388static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
3389{
3390 struct b43_phy_n *nphy = dev->phy.n;
3391
3392 struct b43_chanspec chanspec;
3393 chanspec = nphy->radio_chanspec;
3394 chanspec.channel = channel;
3395
3396 return b43_nphy_set_chanspec(dev, chanspec);
3397}
3398
3158static int b43_nphy_op_allocate(struct b43_wldev *dev) 3399static int b43_nphy_op_allocate(struct b43_wldev *dev)
3159{ 3400{
3160 struct b43_phy_n *nphy; 3401 struct b43_phy_n *nphy;
@@ -3243,9 +3484,43 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
3243 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); 3484 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
3244} 3485}
3245 3486
3487/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
3246static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, 3488static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3247 bool blocked) 3489 bool blocked)
3248{//TODO 3490{
3491 struct b43_phy_n *nphy = dev->phy.n;
3492
3493 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
3494 b43err(dev->wl, "MAC not suspended\n");
3495
3496 if (blocked) {
3497 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3498 ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3499 if (dev->phy.rev >= 3) {
3500 b43_radio_mask(dev, 0x09, ~0x2);
3501
3502 b43_radio_write(dev, 0x204D, 0);
3503 b43_radio_write(dev, 0x2053, 0);
3504 b43_radio_write(dev, 0x2058, 0);
3505 b43_radio_write(dev, 0x205E, 0);
3506 b43_radio_mask(dev, 0x2062, ~0xF0);
3507 b43_radio_write(dev, 0x2064, 0);
3508
3509 b43_radio_write(dev, 0x304D, 0);
3510 b43_radio_write(dev, 0x3053, 0);
3511 b43_radio_write(dev, 0x3058, 0);
3512 b43_radio_write(dev, 0x305E, 0);
3513 b43_radio_mask(dev, 0x3062, ~0xF0);
3514 b43_radio_write(dev, 0x3064, 0);
3515 }
3516 } else {
3517 if (dev->phy.rev >= 3) {
3518 b43_radio_init2056(dev);
3519 b43_nphy_set_chanspec(dev, nphy->radio_chanspec);
3520 } else {
3521 b43_radio_init2055(dev);
3522 }
3523 }
3249} 3524}
3250 3525
3251static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) 3526static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 403aad3f894f..8b6d570dd0aa 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -711,6 +711,8 @@
711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ 711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */
712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ 712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */
713 713
714#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
715#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
714 716
715 717
716/* Broadcom 2055 radio registers */ 718/* Broadcom 2055 radio registers */
@@ -924,6 +926,13 @@
924 926
925struct b43_wldev; 927struct b43_wldev;
926 928
929struct b43_chanspec {
930 u8 channel;
931 u8 sideband;
932 u8 b_width;
933 u8 b_freq;
934};
935
927struct b43_phy_n_iq_comp { 936struct b43_phy_n_iq_comp {
928 s16 a0; 937 s16 a0;
929 s16 b0; 938 s16 b0;
@@ -975,7 +984,8 @@ struct b43_phy_n {
975 u16 papd_epsilon_offset[2]; 984 u16 papd_epsilon_offset[2];
976 s32 preamble_override; 985 s32 preamble_override;
977 u32 bb_mult_save; 986 u32 bb_mult_save;
978 u16 radio_chanspec; 987 u8 b_width;
988 struct b43_chanspec radio_chanspec;
979 989
980 bool gain_boost; 990 bool gain_boost;
981 bool elna_gain_config; 991 bool elna_gain_config;
@@ -991,6 +1001,7 @@ struct b43_phy_n {
991 u16 txiqlocal_bestc[11]; 1001 u16 txiqlocal_bestc[11];
992 bool txiqlocal_coeffsvalid; 1002 bool txiqlocal_coeffsvalid;
993 struct b43_phy_n_txpwrindex txpwrindex[2]; 1003 struct b43_phy_n_txpwrindex txpwrindex[2];
1004 struct b43_chanspec txiqlocal_chanspec;
994 1005
995 u8 txrx_chain; 1006 u8 txrx_chain;
996 u16 tx_rx_cal_phy_saveregs[11]; 1007 u16 tx_rx_cal_phy_saveregs[11];
@@ -1006,12 +1017,12 @@ struct b43_phy_n {
1006 bool gband_spurwar_en; 1017 bool gband_spurwar_en;
1007 1018
1008 bool ipa2g_on; 1019 bool ipa2g_on;
1009 u8 iqcal_chanspec_2G; 1020 struct b43_chanspec iqcal_chanspec_2G;
1010 u8 rssical_chanspec_2G; 1021 struct b43_chanspec rssical_chanspec_2G;
1011 1022
1012 bool ipa5g_on; 1023 bool ipa5g_on;
1013 u8 iqcal_chanspec_5G; 1024 struct b43_chanspec iqcal_chanspec_5G;
1014 u8 rssical_chanspec_5G; 1025 struct b43_chanspec rssical_chanspec_5G;
1015 1026
1016 struct b43_phy_n_rssical_cache rssical_cache; 1027 struct b43_phy_n_rssical_cache rssical_cache;
1017 struct b43_phy_n_cal_cache cal_cache; 1028 struct b43_phy_n_cal_cache cal_cache;
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index a00d509150f7..d96e870ab8fe 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -318,14 +318,14 @@ void b2055_upload_inittab(struct b43_wldev *dev,
318 .radio_c2_tx_mxbgtrim = r21 318 .radio_c2_tx_mxbgtrim = r21
319 319
320#define PHYREGS(r0, r1, r2, r3, r4, r5) \ 320#define PHYREGS(r0, r1, r2, r3, r4, r5) \
321 .phy_bw1a = r0, \ 321 .phy_regs.phy_bw1a = r0, \
322 .phy_bw2 = r1, \ 322 .phy_regs.phy_bw2 = r1, \
323 .phy_bw3 = r2, \ 323 .phy_regs.phy_bw3 = r2, \
324 .phy_bw4 = r3, \ 324 .phy_regs.phy_bw4 = r3, \
325 .phy_bw5 = r4, \ 325 .phy_regs.phy_bw5 = r4, \
326 .phy_bw6 = r5 326 .phy_regs.phy_bw6 = r5
327 327
328static const struct b43_nphy_channeltab_entry b43_nphy_channeltab[] = { 328static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = {
329 { .channel = 184, 329 { .channel = 184,
330 .freq = 4920, /* MHz */ 330 .freq = 4920, /* MHz */
331 .unk2 = 3280, 331 .unk2 = 3280,
@@ -1320,10 +1320,10 @@ static const struct b43_nphy_channeltab_entry b43_nphy_channeltab[] = {
1320 }, 1320 },
1321}; 1321};
1322 1322
1323const struct b43_nphy_channeltab_entry * 1323const struct b43_nphy_channeltab_entry_rev2 *
1324b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel) 1324b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
1325{ 1325{
1326 const struct b43_nphy_channeltab_entry *e; 1326 const struct b43_nphy_channeltab_entry_rev2 *e;
1327 unsigned int i; 1327 unsigned int i;
1328 1328
1329 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) { 1329 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 9c1c6ecd3672..8fc1da9f8fe5 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -4,9 +4,22 @@
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6 6
7struct b43_nphy_channeltab_entry { 7struct b43_phy_n_sfo_cfg {
8 u16 phy_bw1a;
9 u16 phy_bw2;
10 u16 phy_bw3;
11 u16 phy_bw4;
12 u16 phy_bw5;
13 u16 phy_bw6;
14};
15
16struct b43_nphy_channeltab_entry_rev2 {
8 /* The channel number */ 17 /* The channel number */
9 u8 channel; 18 u8 channel;
19 /* The channel frequency in MHz */
20 u16 freq;
21 /* An unknown value */
22 u16 unk2;
10 /* Radio register values on channelswitch */ 23 /* Radio register values on channelswitch */
11 u8 radio_pll_ref; 24 u8 radio_pll_ref;
12 u8 radio_rf_pllmod0; 25 u8 radio_rf_pllmod0;
@@ -31,16 +44,18 @@ struct b43_nphy_channeltab_entry {
31 u8 radio_c2_tx_pgapadtn; 44 u8 radio_c2_tx_pgapadtn;
32 u8 radio_c2_tx_mxbgtrim; 45 u8 radio_c2_tx_mxbgtrim;
33 /* PHY register values on channelswitch */ 46 /* PHY register values on channelswitch */
34 u16 phy_bw1a; 47 struct b43_phy_n_sfo_cfg phy_regs;
35 u16 phy_bw2; 48};
36 u16 phy_bw3; 49
37 u16 phy_bw4; 50struct b43_nphy_channeltab_entry_rev3 {
38 u16 phy_bw5; 51 /* The channel number */
39 u16 phy_bw6; 52 u8 channel;
40 /* The channel frequency in MHz */ 53 /* The channel frequency in MHz */
41 u16 freq; 54 u16 freq;
42 /* An unknown value */ 55 /* Radio register values on channelswitch */
43 u16 unk2; 56 /* TODO */
57 /* PHY register values on channelswitch */
58 struct b43_phy_n_sfo_cfg phy_regs;
44}; 59};
45 60
46 61
@@ -77,8 +92,8 @@ void b2055_upload_inittab(struct b43_wldev *dev,
77 92
78/* Get the NPHY Channel Switch Table entry for a channel number. 93/* Get the NPHY Channel Switch Table entry for a channel number.
79 * Returns NULL on failure to find an entry. */ 94 * Returns NULL on failure to find an entry. */
80const struct b43_nphy_channeltab_entry * 95const struct b43_nphy_channeltab_entry_rev2 *
81b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); 96b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
82 97
83 98
84/* The N-PHY tables. */ 99/* The N-PHY tables. */
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index eda06529ef5f..e6b0528f3b52 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -610,7 +610,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
610 } 610 }
611 611
612 /* Link quality statistics */ 612 /* Link quality statistics */
613 status.noise = dev->stats.link_noise;
614 if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) { 613 if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
615// s8 rssi = max(rxhdr->power0, rxhdr->power1); 614// s8 rssi = max(rxhdr->power0, rxhdr->power1);
616 //TODO: Find out what the rssi value is (dBm or percentage?) 615 //TODO: Find out what the rssi value is (dBm or percentage?)