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/b43legacy/main.c | |
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/b43legacy/main.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 159 |
1 files changed, 70 insertions, 89 deletions
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c39de422e220..d2a72a2cd178 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -95,28 +95,29 @@ MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl); | |||
95 | * data in there. This data is the same for all devices, so we don't | 95 | * data in there. This data is the same for all devices, so we don't |
96 | * get concurrency issues */ | 96 | * get concurrency issues */ |
97 | #define RATETAB_ENT(_rateid, _flags) \ | 97 | #define RATETAB_ENT(_rateid, _flags) \ |
98 | { \ | 98 | { \ |
99 | .rate = B43legacy_RATE_TO_100KBPS(_rateid), \ | 99 | .bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \ |
100 | .val = (_rateid), \ | 100 | .hw_value = (_rateid), \ |
101 | .val2 = (_rateid), \ | 101 | .flags = (_flags), \ |
102 | .flags = (_flags), \ | ||
103 | } | 102 | } |
103 | /* | ||
104 | * NOTE: When changing this, sync with xmit.c's | ||
105 | * b43legacy_plcp_get_bitrate_idx_* functions! | ||
106 | */ | ||
104 | static struct ieee80211_rate __b43legacy_ratetable[] = { | 107 | static struct ieee80211_rate __b43legacy_ratetable[] = { |
105 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, IEEE80211_RATE_CCK), | 108 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0), |
106 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), | 109 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE), |
107 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), | 110 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE), |
108 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), | 111 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE), |
109 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), | 112 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0), |
110 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), | 113 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0), |
111 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), | 114 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0), |
112 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), | 115 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0), |
113 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), | 116 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0), |
114 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), | 117 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0), |
115 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), | 118 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0), |
116 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), | 119 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0), |
117 | }; | 120 | }; |
118 | #define b43legacy_a_ratetable (__b43legacy_ratetable + 4) | ||
119 | #define b43legacy_a_ratetable_size 8 | ||
120 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) | 121 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) |
121 | #define b43legacy_b_ratetable_size 4 | 122 | #define b43legacy_b_ratetable_size 4 |
122 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) | 123 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) |
@@ -124,14 +125,8 @@ static struct ieee80211_rate __b43legacy_ratetable[] = { | |||
124 | 125 | ||
125 | #define CHANTAB_ENT(_chanid, _freq) \ | 126 | #define CHANTAB_ENT(_chanid, _freq) \ |
126 | { \ | 127 | { \ |
127 | .chan = (_chanid), \ | 128 | .center_freq = (_freq), \ |
128 | .freq = (_freq), \ | 129 | .hw_value = (_chanid), \ |
129 | .val = (_chanid), \ | ||
130 | .flag = IEEE80211_CHAN_W_SCAN | \ | ||
131 | IEEE80211_CHAN_W_ACTIVE_SCAN | \ | ||
132 | IEEE80211_CHAN_W_IBSS, \ | ||
133 | .power_level = 0x0A, \ | ||
134 | .antenna_max = 0xFF, \ | ||
135 | } | 130 | } |
136 | static struct ieee80211_channel b43legacy_bg_chantable[] = { | 131 | static struct ieee80211_channel b43legacy_bg_chantable[] = { |
137 | CHANTAB_ENT(1, 2412), | 132 | CHANTAB_ENT(1, 2412), |
@@ -149,7 +144,20 @@ static struct ieee80211_channel b43legacy_bg_chantable[] = { | |||
149 | CHANTAB_ENT(13, 2472), | 144 | CHANTAB_ENT(13, 2472), |
150 | CHANTAB_ENT(14, 2484), | 145 | CHANTAB_ENT(14, 2484), |
151 | }; | 146 | }; |
152 | #define b43legacy_bg_chantable_size ARRAY_SIZE(b43legacy_bg_chantable) | 147 | |
148 | static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = { | ||
149 | .channels = b43legacy_bg_chantable, | ||
150 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
151 | .bitrates = b43legacy_b_ratetable, | ||
152 | .n_bitrates = b43legacy_b_ratetable_size, | ||
153 | }; | ||
154 | |||
155 | static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = { | ||
156 | .channels = b43legacy_bg_chantable, | ||
157 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
158 | .bitrates = b43legacy_g_ratetable, | ||
159 | .n_bitrates = b43legacy_g_ratetable_size, | ||
160 | }; | ||
153 | 161 | ||
154 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); | 162 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); |
155 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); | 163 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); |
@@ -969,18 +977,18 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, | |||
969 | 977 | ||
970 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | 978 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, |
971 | u16 shm_offset, u16 size, | 979 | u16 shm_offset, u16 size, |
972 | u8 rate) | 980 | struct ieee80211_rate *rate) |
973 | { | 981 | { |
974 | struct b43legacy_plcp_hdr4 plcp; | 982 | struct b43legacy_plcp_hdr4 plcp; |
975 | u32 tmp; | 983 | u32 tmp; |
976 | __le16 dur; | 984 | __le16 dur; |
977 | 985 | ||
978 | plcp.data = 0; | 986 | plcp.data = 0; |
979 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); | 987 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate); |
980 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 988 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
981 | dev->wl->vif, | 989 | dev->wl->vif, |
982 | size, | 990 | size, |
983 | B43legacy_RATE_TO_100KBPS(rate)); | 991 | rate); |
984 | /* Write PLCP in two parts and timing for packet transfer */ | 992 | /* Write PLCP in two parts and timing for packet transfer */ |
985 | tmp = le32_to_cpu(plcp.data); | 993 | tmp = le32_to_cpu(plcp.data); |
986 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, | 994 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, |
@@ -998,7 +1006,8 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | |||
998 | * 3) Stripping TIM | 1006 | * 3) Stripping TIM |
999 | */ | 1007 | */ |
1000 | static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | 1008 | static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, |
1001 | u16 *dest_size, u8 rate) | 1009 | u16 *dest_size, |
1010 | struct ieee80211_rate *rate) | ||
1002 | { | 1011 | { |
1003 | const u8 *src_data; | 1012 | const u8 *src_data; |
1004 | u8 *dest_data; | 1013 | u8 *dest_data; |
@@ -1046,7 +1055,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1046 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1055 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1047 | dev->wl->vif, | 1056 | dev->wl->vif, |
1048 | *dest_size, | 1057 | *dest_size, |
1049 | B43legacy_RATE_TO_100KBPS(rate)); | 1058 | rate); |
1050 | hdr->duration_id = dur; | 1059 | hdr->duration_id = dur; |
1051 | 1060 | ||
1052 | return dest_data; | 1061 | return dest_data; |
@@ -1054,7 +1063,8 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1054 | 1063 | ||
1055 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | 1064 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, |
1056 | u16 ram_offset, | 1065 | u16 ram_offset, |
1057 | u16 shm_size_offset, u8 rate) | 1066 | u16 shm_size_offset, |
1067 | struct ieee80211_rate *rate) | ||
1058 | { | 1068 | { |
1059 | u8 *probe_resp_data; | 1069 | u8 *probe_resp_data; |
1060 | u16 size; | 1070 | u16 size; |
@@ -1069,19 +1079,19 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | |||
1069 | * all possible basic rates | 1079 | * all possible basic rates |
1070 | */ | 1080 | */ |
1071 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, | 1081 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, |
1072 | B43legacy_CCK_RATE_1MB); | 1082 | &b43legacy_b_ratetable[0]); |
1073 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, | 1083 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, |
1074 | B43legacy_CCK_RATE_2MB); | 1084 | &b43legacy_b_ratetable[1]); |
1075 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, | 1085 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, |
1076 | B43legacy_CCK_RATE_5MB); | 1086 | &b43legacy_b_ratetable[2]); |
1077 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, | 1087 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, |
1078 | B43legacy_CCK_RATE_11MB); | 1088 | &b43legacy_b_ratetable[3]); |
1079 | 1089 | ||
1080 | size = min((size_t)size, | 1090 | size = min((size_t)size, |
1081 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); | 1091 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); |
1082 | b43legacy_write_template_common(dev, probe_resp_data, | 1092 | b43legacy_write_template_common(dev, probe_resp_data, |
1083 | size, ram_offset, | 1093 | size, ram_offset, |
1084 | shm_size_offset, rate); | 1094 | shm_size_offset, rate->bitrate); |
1085 | kfree(probe_resp_data); | 1095 | kfree(probe_resp_data); |
1086 | } | 1096 | } |
1087 | 1097 | ||
@@ -1106,7 +1116,7 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev) | |||
1106 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, | 1116 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, |
1107 | B43legacy_CCK_RATE_1MB); | 1117 | B43legacy_CCK_RATE_1MB); |
1108 | b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, | 1118 | b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, |
1109 | B43legacy_CCK_RATE_11MB); | 1119 | &b43legacy_b_ratetable[0]); |
1110 | 1120 | ||
1111 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | 1121 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); |
1112 | status |= 0x03; | 1122 | status |= 0x03; |
@@ -2550,14 +2560,16 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2550 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); | 2560 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); |
2551 | 2561 | ||
2552 | mutex_lock(&wl->mutex); | 2562 | mutex_lock(&wl->mutex); |
2563 | dev = wl->current_dev; | ||
2564 | phy = &dev->phy; | ||
2553 | 2565 | ||
2554 | /* Switch the PHY mode (if necessary). */ | 2566 | /* Switch the PHY mode (if necessary). */ |
2555 | switch (conf->phymode) { | 2567 | switch (conf->channel->band) { |
2556 | case MODE_IEEE80211B: | 2568 | case IEEE80211_BAND_2GHZ: |
2557 | new_phymode = B43legacy_PHYMODE_B; | 2569 | if (phy->type == B43legacy_PHYTYPE_B) |
2558 | break; | 2570 | new_phymode = B43legacy_PHYMODE_B; |
2559 | case MODE_IEEE80211G: | 2571 | else |
2560 | new_phymode = B43legacy_PHYMODE_G; | 2572 | new_phymode = B43legacy_PHYMODE_G; |
2561 | break; | 2573 | break; |
2562 | default: | 2574 | default: |
2563 | B43legacy_WARN_ON(1); | 2575 | B43legacy_WARN_ON(1); |
@@ -2565,8 +2577,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2565 | err = b43legacy_switch_phymode(wl, new_phymode); | 2577 | err = b43legacy_switch_phymode(wl, new_phymode); |
2566 | if (err) | 2578 | if (err) |
2567 | goto out_unlock_mutex; | 2579 | goto out_unlock_mutex; |
2568 | dev = wl->current_dev; | ||
2569 | phy = &dev->phy; | ||
2570 | 2580 | ||
2571 | /* Disable IRQs while reconfiguring the device. | 2581 | /* Disable IRQs while reconfiguring the device. |
2572 | * This makes it possible to drop the spinlock throughout | 2582 | * This makes it possible to drop the spinlock throughout |
@@ -2582,8 +2592,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2582 | 2592 | ||
2583 | /* Switch to the requested channel. | 2593 | /* Switch to the requested channel. |
2584 | * The firmware takes care of races with the TX handler. */ | 2594 | * The firmware takes care of races with the TX handler. */ |
2585 | if (conf->channel_val != phy->channel) | 2595 | if (conf->channel->hw_value != phy->channel) |
2586 | b43legacy_radio_selectchannel(dev, conf->channel_val, 0); | 2596 | b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); |
2587 | 2597 | ||
2588 | /* Enable/Disable ShortSlot timing. */ | 2598 | /* Enable/Disable ShortSlot timing. */ |
2589 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) | 2599 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) |
@@ -3398,48 +3408,19 @@ static int b43legacy_setup_modes(struct b43legacy_wldev *dev, | |||
3398 | int have_gphy) | 3408 | int have_gphy) |
3399 | { | 3409 | { |
3400 | struct ieee80211_hw *hw = dev->wl->hw; | 3410 | struct ieee80211_hw *hw = dev->wl->hw; |
3401 | struct ieee80211_hw_mode *mode; | ||
3402 | struct b43legacy_phy *phy = &dev->phy; | 3411 | struct b43legacy_phy *phy = &dev->phy; |
3403 | int cnt = 0; | ||
3404 | int err; | ||
3405 | 3412 | ||
3406 | phy->possible_phymodes = 0; | 3413 | phy->possible_phymodes = 0; |
3407 | for (; 1; cnt++) { | 3414 | if (have_bphy) { |
3408 | if (have_bphy) { | 3415 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3409 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | 3416 | &b43legacy_band_2GHz_BPHY; |
3410 | mode = &phy->hwmodes[cnt]; | 3417 | phy->possible_phymodes |= B43legacy_PHYMODE_B; |
3411 | 3418 | } | |
3412 | mode->mode = MODE_IEEE80211B; | 3419 | |
3413 | mode->num_channels = b43legacy_bg_chantable_size; | 3420 | if (have_gphy) { |
3414 | mode->channels = b43legacy_bg_chantable; | 3421 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3415 | mode->num_rates = b43legacy_b_ratetable_size; | 3422 | &b43legacy_band_2GHz_GPHY; |
3416 | mode->rates = b43legacy_b_ratetable; | 3423 | phy->possible_phymodes |= B43legacy_PHYMODE_G; |
3417 | err = ieee80211_register_hwmode(hw, mode); | ||
3418 | if (err) | ||
3419 | return err; | ||
3420 | |||
3421 | phy->possible_phymodes |= B43legacy_PHYMODE_B; | ||
3422 | have_bphy = 0; | ||
3423 | continue; | ||
3424 | } | ||
3425 | if (have_gphy) { | ||
3426 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | ||
3427 | mode = &phy->hwmodes[cnt]; | ||
3428 | |||
3429 | mode->mode = MODE_IEEE80211G; | ||
3430 | mode->num_channels = b43legacy_bg_chantable_size; | ||
3431 | mode->channels = b43legacy_bg_chantable; | ||
3432 | mode->num_rates = b43legacy_g_ratetable_size; | ||
3433 | mode->rates = b43legacy_g_ratetable; | ||
3434 | err = ieee80211_register_hwmode(hw, mode); | ||
3435 | if (err) | ||
3436 | return err; | ||
3437 | |||
3438 | phy->possible_phymodes |= B43legacy_PHYMODE_G; | ||
3439 | have_gphy = 0; | ||
3440 | continue; | ||
3441 | } | ||
3442 | break; | ||
3443 | } | 3424 | } |
3444 | 3425 | ||
3445 | return 0; | 3426 | return 0; |