diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-01-24 13:38:38 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:32 -0500 |
commit | 8318d78a44d49ac1edf2bdec7299de3617c4232e (patch) | |
tree | d434634418edd7399737801615d247be06616fdd /drivers/net/wireless/b43 | |
parent | 10b6b80145cc93887dd8aab99bfffa375e9add31 (diff) |
cfg80211 API for channels/bitrates, mac80211 and driver conversion
This patch creates new cfg80211 wiphy API for channel and bitrate
registration and converts mac80211 and drivers to the new API. The
old mac80211 API is completely ripped out. All drivers (except ath5k)
are updated to the new API, in many cases I expect that optimisations
can be done.
Along with the regulatory code I've also ripped out the
IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag, I believe it to be
unnecessary if the hardware simply gives us whatever channels it wants
to support and we then enable/disable them as required, which is pretty
much required for travelling.
Additionally, the patch adds proper "basic" rate handling for STA
mode interface, AP mode interface will have to have new API added
to allow userspace to set the basic rate set, currently it'll be
empty... However, the basic rate handling will need to be moved to
the BSS conf stuff.
I do expect there to be bugs in this, especially wrt. transmit
power handling where I'm basically clueless about how it should work.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r-- | drivers/net/wireless/b43/b43.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 119 | ||||
-rw-r--r-- | drivers/net/wireless/b43/sysfs.c | 89 | ||||
-rw-r--r-- | drivers/net/wireless/b43/xmit.c | 81 |
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 | */ | ||
105 | static struct ieee80211_rate __b43_ratetable[] = { | 109 | static 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 | } |
138 | static struct ieee80211_channel b43_2ghz_chantable[] = { | 136 | static 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 |
157 | static struct ieee80211_channel b43_5ghz_chantable[] = { | 154 | static 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 | |
170 | static 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 | ||
178 | static 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 | |||
175 | static void b43_wireless_core_exit(struct b43_wldev *dev); | 185 | static void b43_wireless_core_exit(struct b43_wldev *dev); |
176 | static int b43_wireless_core_init(struct b43_wldev *dev); | 186 | static int b43_wireless_core_init(struct b43_wldev *dev); |
177 | static void b43_wireless_core_stop(struct b43_wldev *dev); | 187 | static 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 | ||
1224 | static void b43_write_probe_resp_plcp(struct b43_wldev *dev, | 1234 | static 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 | */ |
1249 | static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, | 1260 | static 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 | ||
1301 | static void b43_write_probe_resp_template(struct b43_wldev *dev, | 1313 | static 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 | ||
50 | static 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 | |||
73 | static ssize_t b43_attr_interfmode_show(struct device *dev, | 50 | static 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, | |||
155 | static DEVICE_ATTR(interference, 0644, | 132 | static DEVICE_ATTR(interference, 0644, |
156 | b43_attr_interfmode_show, b43_attr_interfmode_store); | 133 | b43_attr_interfmode_show, b43_attr_interfmode_store); |
157 | 134 | ||
158 | static 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 | |||
181 | static 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 | |||
206 | static DEVICE_ATTR(shortpreamble, 0644, | ||
207 | b43_attr_preamble_show, b43_attr_preamble_store); | ||
208 | |||
209 | int b43_sysfs_register(struct b43_wldev *wldev) | 135 | int 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 | ||
230 | void b43_sysfs_unregister(struct b43_wldev *wldev) | 144 | void 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. */ |
36 | static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) | 36 | static 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. */ |
53 | static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) | 53 | static 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 | ||
77 | u8 b43_plcp_get_ratecode_cck(const u8 bitrate) | 79 | u8 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); |