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.h5
-rw-r--r--drivers/net/wireless/b43/main.c119
-rw-r--r--drivers/net/wireless/b43/sysfs.c89
-rw-r--r--drivers/net/wireless/b43/xmit.c81
4 files changed, 105 insertions, 189 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index f13346ba9dd2..3e40323cd43f 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -468,10 +468,6 @@ struct b43_phy {
468 u8 possible_phymodes; 468 u8 possible_phymodes;
469 /* GMODE bit enabled? */ 469 /* GMODE bit enabled? */
470 bool gmode; 470 bool gmode;
471 /* Possible ieee80211 subsystem hwmodes for this PHY.
472 * Which mode is selected, depends on thr GMODE enabled bit */
473#define B43_MAX_PHYHWMODES 2
474 struct ieee80211_hw_mode hwmodes[B43_MAX_PHYHWMODES];
475 471
476 /* Analog Type */ 472 /* Analog Type */
477 u8 analog; 473 u8 analog;
@@ -727,7 +723,6 @@ struct b43_wldev {
727 723
728 bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ 724 bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */
729 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ 725 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */
730 bool short_preamble; /* TRUE, if short preamble is enabled. */
731 bool short_slot; /* TRUE, if short slot timing is enabled. */ 726 bool short_slot; /* TRUE, if short slot timing is enabled. */
732 bool radio_hw_enable; /* saved state of radio hardware enabled state */ 727 bool radio_hw_enable; /* saved state of radio hardware enabled state */
733 bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ 728 bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 51dfce16178a..017a041d07d0 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -96,25 +96,29 @@ MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl);
96 * data in there. This data is the same for all devices, so we don't 96 * data in there. This data is the same for all devices, so we don't
97 * get concurrency issues */ 97 * get concurrency issues */
98#define RATETAB_ENT(_rateid, _flags) \ 98#define RATETAB_ENT(_rateid, _flags) \
99 { \ 99 { \
100 .rate = B43_RATE_TO_BASE100KBPS(_rateid), \ 100 .bitrate = B43_RATE_TO_BASE100KBPS(_rateid), \
101 .val = (_rateid), \ 101 .hw_value = (_rateid), \
102 .val2 = (_rateid), \ 102 .flags = (_flags), \
103 .flags = (_flags), \
104 } 103 }
104
105/*
106 * NOTE: When changing this, sync with xmit.c's
107 * b43_plcp_get_bitrate_idx_* functions!
108 */
105static struct ieee80211_rate __b43_ratetable[] = { 109static struct ieee80211_rate __b43_ratetable[] = {
106 RATETAB_ENT(B43_CCK_RATE_1MB, IEEE80211_RATE_CCK), 110 RATETAB_ENT(B43_CCK_RATE_1MB, 0),
107 RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), 111 RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
108 RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), 112 RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
109 RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), 113 RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
110 RATETAB_ENT(B43_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), 114 RATETAB_ENT(B43_OFDM_RATE_6MB, 0),
111 RATETAB_ENT(B43_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), 115 RATETAB_ENT(B43_OFDM_RATE_9MB, 0),
112 RATETAB_ENT(B43_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), 116 RATETAB_ENT(B43_OFDM_RATE_12MB, 0),
113 RATETAB_ENT(B43_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), 117 RATETAB_ENT(B43_OFDM_RATE_18MB, 0),
114 RATETAB_ENT(B43_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), 118 RATETAB_ENT(B43_OFDM_RATE_24MB, 0),
115 RATETAB_ENT(B43_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), 119 RATETAB_ENT(B43_OFDM_RATE_36MB, 0),
116 RATETAB_ENT(B43_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), 120 RATETAB_ENT(B43_OFDM_RATE_48MB, 0),
117 RATETAB_ENT(B43_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), 121 RATETAB_ENT(B43_OFDM_RATE_54MB, 0),
118}; 122};
119 123
120#define b43_a_ratetable (__b43_ratetable + 4) 124#define b43_a_ratetable (__b43_ratetable + 4)
@@ -126,14 +130,8 @@ static struct ieee80211_rate __b43_ratetable[] = {
126 130
127#define CHANTAB_ENT(_chanid, _freq) \ 131#define CHANTAB_ENT(_chanid, _freq) \
128 { \ 132 { \
129 .chan = (_chanid), \ 133 .center_freq = (_freq), \
130 .freq = (_freq), \ 134 .hw_value = (_chanid), \
131 .val = (_chanid), \
132 .flag = IEEE80211_CHAN_W_SCAN | \
133 IEEE80211_CHAN_W_ACTIVE_SCAN | \
134 IEEE80211_CHAN_W_IBSS, \
135 .power_level = 0xFF, \
136 .antenna_max = 0xFF, \
137 } 135 }
138static struct ieee80211_channel b43_2ghz_chantable[] = { 136static struct ieee80211_channel b43_2ghz_chantable[] = {
139 CHANTAB_ENT(1, 2412), 137 CHANTAB_ENT(1, 2412),
@@ -151,9 +149,8 @@ static struct ieee80211_channel b43_2ghz_chantable[] = {
151 CHANTAB_ENT(13, 2472), 149 CHANTAB_ENT(13, 2472),
152 CHANTAB_ENT(14, 2484), 150 CHANTAB_ENT(14, 2484),
153}; 151};
154#define b43_2ghz_chantable_size ARRAY_SIZE(b43_2ghz_chantable)
155 152
156#if 0 153#ifdef NOTYET
157static struct ieee80211_channel b43_5ghz_chantable[] = { 154static struct ieee80211_channel b43_5ghz_chantable[] = {
158 CHANTAB_ENT(36, 5180), 155 CHANTAB_ENT(36, 5180),
159 CHANTAB_ENT(40, 5200), 156 CHANTAB_ENT(40, 5200),
@@ -169,9 +166,22 @@ static struct ieee80211_channel b43_5ghz_chantable[] = {
169 CHANTAB_ENT(161, 5805), 166 CHANTAB_ENT(161, 5805),
170 CHANTAB_ENT(165, 5825), 167 CHANTAB_ENT(165, 5825),
171}; 168};
172#define b43_5ghz_chantable_size ARRAY_SIZE(b43_5ghz_chantable) 169
170static struct ieee80211_supported_band b43_band_5GHz = {
171 .channels = b43_5ghz_chantable,
172 .n_channels = ARRAY_SIZE(b43_5ghz_chantable),
173 .bitrates = b43_a_ratetable,
174 .n_bitrates = b43_a_ratetable_size,
175};
173#endif 176#endif
174 177
178static struct ieee80211_supported_band b43_band_2GHz = {
179 .channels = b43_2ghz_chantable,
180 .n_channels = ARRAY_SIZE(b43_2ghz_chantable),
181 .bitrates = b43_g_ratetable,
182 .n_bitrates = b43_g_ratetable_size,
183};
184
175static void b43_wireless_core_exit(struct b43_wldev *dev); 185static void b43_wireless_core_exit(struct b43_wldev *dev);
176static int b43_wireless_core_init(struct b43_wldev *dev); 186static int b43_wireless_core_init(struct b43_wldev *dev);
177static void b43_wireless_core_stop(struct b43_wldev *dev); 187static void b43_wireless_core_stop(struct b43_wldev *dev);
@@ -1222,17 +1232,18 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
1222} 1232}
1223 1233
1224static void b43_write_probe_resp_plcp(struct b43_wldev *dev, 1234static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
1225 u16 shm_offset, u16 size, u8 rate) 1235 u16 shm_offset, u16 size,
1236 struct ieee80211_rate *rate)
1226{ 1237{
1227 struct b43_plcp_hdr4 plcp; 1238 struct b43_plcp_hdr4 plcp;
1228 u32 tmp; 1239 u32 tmp;
1229 __le16 dur; 1240 __le16 dur;
1230 1241
1231 plcp.data = 0; 1242 plcp.data = 0;
1232 b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); 1243 b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
1233 dur = ieee80211_generic_frame_duration(dev->wl->hw, 1244 dur = ieee80211_generic_frame_duration(dev->wl->hw,
1234 dev->wl->vif, size, 1245 dev->wl->vif, size,
1235 B43_RATE_TO_BASE100KBPS(rate)); 1246 rate);
1236 /* Write PLCP in two parts and timing for packet transfer */ 1247 /* Write PLCP in two parts and timing for packet transfer */
1237 tmp = le32_to_cpu(plcp.data); 1248 tmp = le32_to_cpu(plcp.data);
1238 b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF); 1249 b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF);
@@ -1247,7 +1258,8 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
1247 * 3) Stripping TIM 1258 * 3) Stripping TIM
1248 */ 1259 */
1249static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, 1260static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
1250 u16 *dest_size, u8 rate) 1261 u16 *dest_size,
1262 struct ieee80211_rate *rate)
1251{ 1263{
1252 const u8 *src_data; 1264 const u8 *src_data;
1253 u8 *dest_data; 1265 u8 *dest_data;
@@ -1292,7 +1304,7 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
1292 IEEE80211_STYPE_PROBE_RESP); 1304 IEEE80211_STYPE_PROBE_RESP);
1293 dur = ieee80211_generic_frame_duration(dev->wl->hw, 1305 dur = ieee80211_generic_frame_duration(dev->wl->hw,
1294 dev->wl->vif, *dest_size, 1306 dev->wl->vif, *dest_size,
1295 B43_RATE_TO_BASE100KBPS(rate)); 1307 rate);
1296 hdr->duration_id = dur; 1308 hdr->duration_id = dur;
1297 1309
1298 return dest_data; 1310 return dest_data;
@@ -1300,7 +1312,8 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
1300 1312
1301static void b43_write_probe_resp_template(struct b43_wldev *dev, 1313static void b43_write_probe_resp_template(struct b43_wldev *dev,
1302 u16 ram_offset, 1314 u16 ram_offset,
1303 u16 shm_size_offset, u8 rate) 1315 u16 shm_size_offset,
1316 struct ieee80211_rate *rate)
1304{ 1317{
1305 const u8 *probe_resp_data; 1318 const u8 *probe_resp_data;
1306 u16 size; 1319 u16 size;
@@ -1313,14 +1326,15 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev,
1313 /* Looks like PLCP headers plus packet timings are stored for 1326 /* Looks like PLCP headers plus packet timings are stored for
1314 * all possible basic rates 1327 * all possible basic rates
1315 */ 1328 */
1316 b43_write_probe_resp_plcp(dev, 0x31A, size, B43_CCK_RATE_1MB); 1329 b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]);
1317 b43_write_probe_resp_plcp(dev, 0x32C, size, B43_CCK_RATE_2MB); 1330 b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]);
1318 b43_write_probe_resp_plcp(dev, 0x33E, size, B43_CCK_RATE_5MB); 1331 b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]);
1319 b43_write_probe_resp_plcp(dev, 0x350, size, B43_CCK_RATE_11MB); 1332 b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]);
1320 1333
1321 size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6)); 1334 size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6));
1322 b43_write_template_common(dev, probe_resp_data, 1335 b43_write_template_common(dev, probe_resp_data,
1323 size, ram_offset, shm_size_offset, rate); 1336 size, ram_offset, shm_size_offset,
1337 rate->hw_value);
1324 kfree(probe_resp_data); 1338 kfree(probe_resp_data);
1325} 1339}
1326 1340
@@ -1388,7 +1402,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
1388 b43_write_beacon_template(dev, 0x68, 0x18, 1402 b43_write_beacon_template(dev, 0x68, 0x18,
1389 B43_CCK_RATE_1MB); 1403 B43_CCK_RATE_1MB);
1390 b43_write_probe_resp_template(dev, 0x268, 0x4A, 1404 b43_write_probe_resp_template(dev, 0x268, 0x4A,
1391 B43_CCK_RATE_11MB); 1405 &__b43_ratetable[3]);
1392 wl->beacon0_uploaded = 1; 1406 wl->beacon0_uploaded = 1;
1393 } 1407 }
1394 cmd |= B43_MACCMD_BEACON0_VALID; 1408 cmd |= B43_MACCMD_BEACON0_VALID;
@@ -2830,14 +2844,11 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
2830 mutex_lock(&wl->mutex); 2844 mutex_lock(&wl->mutex);
2831 2845
2832 /* Switch the PHY mode (if necessary). */ 2846 /* Switch the PHY mode (if necessary). */
2833 switch (conf->phymode) { 2847 switch (conf->channel->band) {
2834 case MODE_IEEE80211A: 2848 case IEEE80211_BAND_5GHZ:
2835 new_phymode = B43_PHYMODE_A; 2849 new_phymode = B43_PHYMODE_A;
2836 break; 2850 break;
2837 case MODE_IEEE80211B: 2851 case IEEE80211_BAND_2GHZ:
2838 new_phymode = B43_PHYMODE_B;
2839 break;
2840 case MODE_IEEE80211G:
2841 new_phymode = B43_PHYMODE_G; 2852 new_phymode = B43_PHYMODE_G;
2842 break; 2853 break;
2843 default: 2854 default:
@@ -2863,8 +2874,8 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
2863 2874
2864 /* Switch to the requested channel. 2875 /* Switch to the requested channel.
2865 * The firmware takes care of races with the TX handler. */ 2876 * The firmware takes care of races with the TX handler. */
2866 if (conf->channel_val != phy->channel) 2877 if (conf->channel->hw_value != phy->channel)
2867 b43_radio_selectchannel(dev, conf->channel_val, 0); 2878 b43_radio_selectchannel(dev, conf->channel->hw_value, 0);
2868 2879
2869 /* Enable/Disable ShortSlot timing. */ 2880 /* Enable/Disable ShortSlot timing. */
2870 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != 2881 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
@@ -3810,9 +3821,7 @@ static int b43_setup_modes(struct b43_wldev *dev,
3810 bool have_2ghz_phy, bool have_5ghz_phy) 3821 bool have_2ghz_phy, bool have_5ghz_phy)
3811{ 3822{
3812 struct ieee80211_hw *hw = dev->wl->hw; 3823 struct ieee80211_hw *hw = dev->wl->hw;
3813 struct ieee80211_hw_mode *mode;
3814 struct b43_phy *phy = &dev->phy; 3824 struct b43_phy *phy = &dev->phy;
3815 int err;
3816 3825
3817 /* XXX: This function will go away soon, when mac80211 3826 /* XXX: This function will go away soon, when mac80211
3818 * band stuff is rewritten. So this is just a hack. 3827 * band stuff is rewritten. So this is just a hack.
@@ -3821,15 +3830,7 @@ static int b43_setup_modes(struct b43_wldev *dev,
3821 * This assumption is OK, as any B, N or A PHY will already 3830 * This assumption is OK, as any B, N or A PHY will already
3822 * have died a horrible sanity check death earlier. */ 3831 * have died a horrible sanity check death earlier. */
3823 3832
3824 mode = &phy->hwmodes[0]; 3833 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
3825 mode->mode = MODE_IEEE80211G;
3826 mode->num_channels = b43_2ghz_chantable_size;
3827 mode->channels = b43_2ghz_chantable;
3828 mode->num_rates = b43_g_ratetable_size;
3829 mode->rates = b43_g_ratetable;
3830 err = ieee80211_register_hwmode(hw, mode);
3831 if (err)
3832 return err;
3833 phy->possible_phymodes |= B43_PHYMODE_G; 3834 phy->possible_phymodes |= B43_PHYMODE_G;
3834 3835
3835 return 0; 3836 return 0;
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c
index f4faff6a7d6c..275095b8cbe7 100644
--- a/drivers/net/wireless/b43/sysfs.c
+++ b/drivers/net/wireless/b43/sysfs.c
@@ -47,29 +47,6 @@ static int get_integer(const char *buf, size_t count)
47 return ret; 47 return ret;
48} 48}
49 49
50static int get_boolean(const char *buf, size_t count)
51{
52 if (count != 0) {
53 if (buf[0] == '1')
54 return 1;
55 if (buf[0] == '0')
56 return 0;
57 if (count >= 4 && memcmp(buf, "true", 4) == 0)
58 return 1;
59 if (count >= 5 && memcmp(buf, "false", 5) == 0)
60 return 0;
61 if (count >= 3 && memcmp(buf, "yes", 3) == 0)
62 return 1;
63 if (count >= 2 && memcmp(buf, "no", 2) == 0)
64 return 0;
65 if (count >= 2 && memcmp(buf, "on", 2) == 0)
66 return 1;
67 if (count >= 3 && memcmp(buf, "off", 3) == 0)
68 return 0;
69 }
70 return -EINVAL;
71}
72
73static ssize_t b43_attr_interfmode_show(struct device *dev, 50static ssize_t b43_attr_interfmode_show(struct device *dev,
74 struct device_attribute *attr, 51 struct device_attribute *attr,
75 char *buf) 52 char *buf)
@@ -155,82 +132,18 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
155static DEVICE_ATTR(interference, 0644, 132static DEVICE_ATTR(interference, 0644,
156 b43_attr_interfmode_show, b43_attr_interfmode_store); 133 b43_attr_interfmode_show, b43_attr_interfmode_store);
157 134
158static ssize_t b43_attr_preamble_show(struct device *dev,
159 struct device_attribute *attr, char *buf)
160{
161 struct b43_wldev *wldev = dev_to_b43_wldev(dev);
162 ssize_t count;
163
164 if (!capable(CAP_NET_ADMIN))
165 return -EPERM;
166
167 mutex_lock(&wldev->wl->mutex);
168
169 if (wldev->short_preamble)
170 count =
171 snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
172 else
173 count =
174 snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
175
176 mutex_unlock(&wldev->wl->mutex);
177
178 return count;
179}
180
181static ssize_t b43_attr_preamble_store(struct device *dev,
182 struct device_attribute *attr,
183 const char *buf, size_t count)
184{
185 struct b43_wldev *wldev = dev_to_b43_wldev(dev);
186 unsigned long flags;
187 int value;
188
189 if (!capable(CAP_NET_ADMIN))
190 return -EPERM;
191
192 value = get_boolean(buf, count);
193 if (value < 0)
194 return value;
195 mutex_lock(&wldev->wl->mutex);
196 spin_lock_irqsave(&wldev->wl->irq_lock, flags);
197
198 wldev->short_preamble = !!value;
199
200 spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
201 mutex_unlock(&wldev->wl->mutex);
202
203 return count;
204}
205
206static DEVICE_ATTR(shortpreamble, 0644,
207 b43_attr_preamble_show, b43_attr_preamble_store);
208
209int b43_sysfs_register(struct b43_wldev *wldev) 135int b43_sysfs_register(struct b43_wldev *wldev)
210{ 136{
211 struct device *dev = wldev->dev->dev; 137 struct device *dev = wldev->dev->dev;
212 int err;
213 138
214 B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); 139 B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
215 140
216 err = device_create_file(dev, &dev_attr_interference); 141 return device_create_file(dev, &dev_attr_interference);
217 if (err)
218 goto out;
219 err = device_create_file(dev, &dev_attr_shortpreamble);
220 if (err)
221 goto err_remove_interfmode;
222
223 out:
224 return err;
225 err_remove_interfmode:
226 device_remove_file(dev, &dev_attr_interference);
227 goto out;
228} 142}
229 143
230void b43_sysfs_unregister(struct b43_wldev *wldev) 144void b43_sysfs_unregister(struct b43_wldev *wldev)
231{ 145{
232 struct device *dev = wldev->dev->dev; 146 struct device *dev = wldev->dev->dev;
233 147
234 device_remove_file(dev, &dev_attr_shortpreamble);
235 device_remove_file(dev, &dev_attr_interference); 148 device_remove_file(dev, &dev_attr_interference);
236} 149}
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 7caa26eb4105..4014b6c8272b 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -32,46 +32,48 @@
32#include "dma.h" 32#include "dma.h"
33 33
34 34
35/* Extract the bitrate out of a CCK PLCP header. */ 35/* Extract the bitrate index out of a CCK PLCP header. */
36static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) 36static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
37{ 37{
38 switch (plcp->raw[0]) { 38 switch (plcp->raw[0]) {
39 case 0x0A: 39 case 0x0A:
40 return B43_CCK_RATE_1MB; 40 return 0;
41 case 0x14: 41 case 0x14:
42 return B43_CCK_RATE_2MB; 42 return 1;
43 case 0x37: 43 case 0x37:
44 return B43_CCK_RATE_5MB; 44 return 2;
45 case 0x6E: 45 case 0x6E:
46 return B43_CCK_RATE_11MB; 46 return 3;
47 } 47 }
48 B43_WARN_ON(1); 48 B43_WARN_ON(1);
49 return 0; 49 return -1;
50} 50}
51 51
52/* Extract the bitrate out of an OFDM PLCP header. */ 52/* Extract the bitrate index out of an OFDM PLCP header. */
53static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) 53static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
54{ 54{
55 int base = aphy ? 0 : 4;
56
55 switch (plcp->raw[0] & 0xF) { 57 switch (plcp->raw[0] & 0xF) {
56 case 0xB: 58 case 0xB:
57 return B43_OFDM_RATE_6MB; 59 return base + 0;
58 case 0xF: 60 case 0xF:
59 return B43_OFDM_RATE_9MB; 61 return base + 1;
60 case 0xA: 62 case 0xA:
61 return B43_OFDM_RATE_12MB; 63 return base + 2;
62 case 0xE: 64 case 0xE:
63 return B43_OFDM_RATE_18MB; 65 return base + 3;
64 case 0x9: 66 case 0x9:
65 return B43_OFDM_RATE_24MB; 67 return base + 4;
66 case 0xD: 68 case 0xD:
67 return B43_OFDM_RATE_36MB; 69 return base + 5;
68 case 0x8: 70 case 0x8:
69 return B43_OFDM_RATE_48MB; 71 return base + 6;
70 case 0xC: 72 case 0xC:
71 return B43_OFDM_RATE_54MB; 73 return base + 7;
72 } 74 }
73 B43_WARN_ON(1); 75 B43_WARN_ON(1);
74 return 0; 76 return -1;
75} 77}
76 78
77u8 b43_plcp_get_ratecode_cck(const u8 bitrate) 79u8 b43_plcp_get_ratecode_cck(const u8 bitrate)
@@ -191,6 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
191 (const struct ieee80211_hdr *)fragment_data; 193 (const struct ieee80211_hdr *)fragment_data;
192 int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); 194 int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
193 u16 fctl = le16_to_cpu(wlhdr->frame_control); 195 u16 fctl = le16_to_cpu(wlhdr->frame_control);
196 struct ieee80211_rate *fbrate;
194 u8 rate, rate_fb; 197 u8 rate, rate_fb;
195 int rate_ofdm, rate_fb_ofdm; 198 int rate_ofdm, rate_fb_ofdm;
196 unsigned int plcp_fragment_len; 199 unsigned int plcp_fragment_len;
@@ -200,9 +203,11 @@ int b43_generate_txhdr(struct b43_wldev *dev,
200 203
201 memset(txhdr, 0, sizeof(*txhdr)); 204 memset(txhdr, 0, sizeof(*txhdr));
202 205
203 rate = txctl->tx_rate; 206 WARN_ON(!txctl->tx_rate);
207 rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB;
204 rate_ofdm = b43_is_ofdm_rate(rate); 208 rate_ofdm = b43_is_ofdm_rate(rate);
205 rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; 209 fbrate = txctl->alt_retry_rate ? : txctl->tx_rate;
210 rate_fb = fbrate->hw_value;
206 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); 211 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
207 212
208 if (rate_ofdm) 213 if (rate_ofdm)
@@ -221,11 +226,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
221 * use the original dur_id field. */ 226 * use the original dur_id field. */
222 txhdr->dur_fb = wlhdr->duration_id; 227 txhdr->dur_fb = wlhdr->duration_id;
223 } else { 228 } else {
224 int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb);
225 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, 229 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
226 txctl->vif, 230 txctl->vif,
227 fragment_len, 231 fragment_len,
228 fbrate_base100kbps); 232 fbrate);
229 } 233 }
230 234
231 plcp_fragment_len = fragment_len + FCS_LEN; 235 plcp_fragment_len = fragment_len + FCS_LEN;
@@ -287,7 +291,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
287 phy_ctl |= B43_TXH_PHY_ENC_OFDM; 291 phy_ctl |= B43_TXH_PHY_ENC_OFDM;
288 else 292 else
289 phy_ctl |= B43_TXH_PHY_ENC_CCK; 293 phy_ctl |= B43_TXH_PHY_ENC_CCK;
290 if (dev->short_preamble) 294 if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
291 phy_ctl |= B43_TXH_PHY_SHORTPRMBL; 295 phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
292 296
293 switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { 297 switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
@@ -332,7 +336,8 @@ int b43_generate_txhdr(struct b43_wldev *dev,
332 int rts_rate_ofdm, rts_rate_fb_ofdm; 336 int rts_rate_ofdm, rts_rate_fb_ofdm;
333 struct b43_plcp_hdr6 *plcp; 337 struct b43_plcp_hdr6 *plcp;
334 338
335 rts_rate = txctl->rts_cts_rate; 339 WARN_ON(!txctl->rts_cts_rate);
340 rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
336 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); 341 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
337 rts_rate_fb = b43_calc_fallback_rate(rts_rate); 342 rts_rate_fb = b43_calc_fallback_rate(rts_rate);
338 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); 343 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
@@ -506,6 +511,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
506 u16 phystat0, phystat3, chanstat, mactime; 511 u16 phystat0, phystat3, chanstat, mactime;
507 u32 macstat; 512 u32 macstat;
508 u16 chanid; 513 u16 chanid;
514 u16 phytype;
509 u8 jssi; 515 u8 jssi;
510 int padding; 516 int padding;
511 517
@@ -518,6 +524,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
518 macstat = le32_to_cpu(rxhdr->mac_status); 524 macstat = le32_to_cpu(rxhdr->mac_status);
519 mactime = le16_to_cpu(rxhdr->mac_time); 525 mactime = le16_to_cpu(rxhdr->mac_time);
520 chanstat = le16_to_cpu(rxhdr->channel); 526 chanstat = le16_to_cpu(rxhdr->channel);
527 phytype = chanstat & B43_RX_CHAN_PHYTYPE;
521 528
522 if (macstat & B43_RX_MAC_FCSERR) 529 if (macstat & B43_RX_MAC_FCSERR)
523 dev->wl->ieee_stats.dot11FCSErrorCount++; 530 dev->wl->ieee_stats.dot11FCSErrorCount++;
@@ -575,9 +582,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
575 /* the next line looks wrong, but is what mac80211 wants */ 582 /* the next line looks wrong, but is what mac80211 wants */
576 status.signal = (jssi * 100) / B43_RX_MAX_SSI; 583 status.signal = (jssi * 100) / B43_RX_MAX_SSI;
577 if (phystat0 & B43_RX_PHYST0_OFDM) 584 if (phystat0 & B43_RX_PHYST0_OFDM)
578 status.rate = b43_plcp_get_bitrate_ofdm(plcp); 585 status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
586 phytype == B43_PHYTYPE_A);
579 else 587 else
580 status.rate = b43_plcp_get_bitrate_cck(plcp); 588 status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
581 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); 589 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
582 590
583 /* 591 /*
@@ -601,29 +609,28 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
601 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; 609 chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
602 switch (chanstat & B43_RX_CHAN_PHYTYPE) { 610 switch (chanstat & B43_RX_CHAN_PHYTYPE) {
603 case B43_PHYTYPE_A: 611 case B43_PHYTYPE_A:
604 status.phymode = MODE_IEEE80211A; 612 status.band = IEEE80211_BAND_5GHZ;
605 B43_WARN_ON(1); 613 B43_WARN_ON(1);
606 /* FIXME: We don't really know which value the "chanid" contains. 614 /* FIXME: We don't really know which value the "chanid" contains.
607 * So the following assignment might be wrong. */ 615 * So the following assignment might be wrong. */
608 status.channel = chanid; 616 status.freq = b43_channel_to_freq_5ghz(chanid);
609 status.freq = b43_channel_to_freq_5ghz(status.channel);
610 break; 617 break;
611 case B43_PHYTYPE_G: 618 case B43_PHYTYPE_G:
612 status.phymode = MODE_IEEE80211G; 619 status.band = IEEE80211_BAND_2GHZ;
613 /* chanid is the radio channel cookie value as used 620 /* chanid is the radio channel cookie value as used
614 * to tune the radio. */ 621 * to tune the radio. */
615 status.freq = chanid + 2400; 622 status.freq = chanid + 2400;
616 status.channel = b43_freq_to_channel_2ghz(status.freq);
617 break; 623 break;
618 case B43_PHYTYPE_N: 624 case B43_PHYTYPE_N:
619 status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/;
620 /* chanid is the SHM channel cookie. Which is the plain 625 /* chanid is the SHM channel cookie. Which is the plain
621 * channel number in b43. */ 626 * channel number in b43. */
622 status.channel = chanid; 627 if (chanstat & B43_RX_CHAN_5GHZ) {
623 if (chanstat & B43_RX_CHAN_5GHZ) 628 status.band = IEEE80211_BAND_5GHZ;
624 status.freq = b43_freq_to_channel_5ghz(status.freq); 629 status.freq = b43_freq_to_channel_5ghz(chanid);
625 else 630 } else {
626 status.freq = b43_freq_to_channel_2ghz(status.freq); 631 status.band = IEEE80211_BAND_2GHZ;
632 status.freq = b43_freq_to_channel_2ghz(chanid);
633 }
627 break; 634 break;
628 default: 635 default:
629 B43_WARN_ON(1); 636 B43_WARN_ON(1);