diff options
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); |