diff options
author | Chaoming_Li <chaoming_li@realsil.com.cn> | 2011-04-25 13:52:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-26 16:13:31 -0400 |
commit | acd48572c396364bb480175d7de83944eefa2563 (patch) | |
tree | c58de4c21341f7c2002b9cab79390401a938940a /drivers | |
parent | 3dad618b7b929010f05b179bbc4d56e3d5956083 (diff) |
rtlwifi: Change base routines for addition of rtl8192se and rtl8192de
Change base routines for addition of RTL8192SE and RTL8192DE code.
Additional files are modified to allow compilation.
Signed-off-by: Chaoming_Li <chaoming_li@realsil.com.cn>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/rtlwifi/base.c | 726 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/base.h | 60 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/ps.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/ps.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/usb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/usb.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/wifi.h | 5 |
10 files changed, 675 insertions, 141 deletions
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 9477785f1168..7b3eadfdaf8c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -50,8 +50,9 @@ | |||
50 | *3) functions called by core.c | 50 | *3) functions called by core.c |
51 | *4) wq & timer callback functions | 51 | *4) wq & timer callback functions |
52 | *5) frame process functions | 52 | *5) frame process functions |
53 | *6) sysfs functions | 53 | *6) IOT functions |
54 | *7) ... | 54 | *7) sysfs functions |
55 | *8) ... | ||
55 | */ | 56 | */ |
56 | 57 | ||
57 | /********************************************************* | 58 | /********************************************************* |
@@ -59,7 +60,7 @@ | |||
59 | * mac80211 init functions | 60 | * mac80211 init functions |
60 | * | 61 | * |
61 | *********************************************************/ | 62 | *********************************************************/ |
62 | static struct ieee80211_channel rtl_channeltable[] = { | 63 | static struct ieee80211_channel rtl_channeltable_2g[] = { |
63 | {.center_freq = 2412, .hw_value = 1,}, | 64 | {.center_freq = 2412, .hw_value = 1,}, |
64 | {.center_freq = 2417, .hw_value = 2,}, | 65 | {.center_freq = 2417, .hw_value = 2,}, |
65 | {.center_freq = 2422, .hw_value = 3,}, | 66 | {.center_freq = 2422, .hw_value = 3,}, |
@@ -76,7 +77,34 @@ static struct ieee80211_channel rtl_channeltable[] = { | |||
76 | {.center_freq = 2484, .hw_value = 14,}, | 77 | {.center_freq = 2484, .hw_value = 14,}, |
77 | }; | 78 | }; |
78 | 79 | ||
79 | static struct ieee80211_rate rtl_ratetable[] = { | 80 | static struct ieee80211_channel rtl_channeltable_5g[] = { |
81 | {.center_freq = 5180, .hw_value = 36,}, | ||
82 | {.center_freq = 5200, .hw_value = 40,}, | ||
83 | {.center_freq = 5220, .hw_value = 44,}, | ||
84 | {.center_freq = 5240, .hw_value = 48,}, | ||
85 | {.center_freq = 5260, .hw_value = 52,}, | ||
86 | {.center_freq = 5280, .hw_value = 56,}, | ||
87 | {.center_freq = 5300, .hw_value = 60,}, | ||
88 | {.center_freq = 5320, .hw_value = 64,}, | ||
89 | {.center_freq = 5500, .hw_value = 100,}, | ||
90 | {.center_freq = 5520, .hw_value = 104,}, | ||
91 | {.center_freq = 5540, .hw_value = 108,}, | ||
92 | {.center_freq = 5560, .hw_value = 112,}, | ||
93 | {.center_freq = 5580, .hw_value = 116,}, | ||
94 | {.center_freq = 5600, .hw_value = 120,}, | ||
95 | {.center_freq = 5620, .hw_value = 124,}, | ||
96 | {.center_freq = 5640, .hw_value = 128,}, | ||
97 | {.center_freq = 5660, .hw_value = 132,}, | ||
98 | {.center_freq = 5680, .hw_value = 136,}, | ||
99 | {.center_freq = 5700, .hw_value = 140,}, | ||
100 | {.center_freq = 5745, .hw_value = 149,}, | ||
101 | {.center_freq = 5765, .hw_value = 153,}, | ||
102 | {.center_freq = 5785, .hw_value = 157,}, | ||
103 | {.center_freq = 5805, .hw_value = 161,}, | ||
104 | {.center_freq = 5825, .hw_value = 165,}, | ||
105 | }; | ||
106 | |||
107 | static struct ieee80211_rate rtl_ratetable_2g[] = { | ||
80 | {.bitrate = 10, .hw_value = 0x00,}, | 108 | {.bitrate = 10, .hw_value = 0x00,}, |
81 | {.bitrate = 20, .hw_value = 0x01,}, | 109 | {.bitrate = 20, .hw_value = 0x01,}, |
82 | {.bitrate = 55, .hw_value = 0x02,}, | 110 | {.bitrate = 55, .hw_value = 0x02,}, |
@@ -91,18 +119,57 @@ static struct ieee80211_rate rtl_ratetable[] = { | |||
91 | {.bitrate = 540, .hw_value = 0x0b,}, | 119 | {.bitrate = 540, .hw_value = 0x0b,}, |
92 | }; | 120 | }; |
93 | 121 | ||
122 | static struct ieee80211_rate rtl_ratetable_5g[] = { | ||
123 | {.bitrate = 60, .hw_value = 0x04,}, | ||
124 | {.bitrate = 90, .hw_value = 0x05,}, | ||
125 | {.bitrate = 120, .hw_value = 0x06,}, | ||
126 | {.bitrate = 180, .hw_value = 0x07,}, | ||
127 | {.bitrate = 240, .hw_value = 0x08,}, | ||
128 | {.bitrate = 360, .hw_value = 0x09,}, | ||
129 | {.bitrate = 480, .hw_value = 0x0a,}, | ||
130 | {.bitrate = 540, .hw_value = 0x0b,}, | ||
131 | }; | ||
132 | |||
94 | static const struct ieee80211_supported_band rtl_band_2ghz = { | 133 | static const struct ieee80211_supported_band rtl_band_2ghz = { |
95 | .band = IEEE80211_BAND_2GHZ, | 134 | .band = IEEE80211_BAND_2GHZ, |
96 | 135 | ||
97 | .channels = rtl_channeltable, | 136 | .channels = rtl_channeltable_2g, |
98 | .n_channels = ARRAY_SIZE(rtl_channeltable), | 137 | .n_channels = ARRAY_SIZE(rtl_channeltable_2g), |
99 | 138 | ||
100 | .bitrates = rtl_ratetable, | 139 | .bitrates = rtl_ratetable_2g, |
101 | .n_bitrates = ARRAY_SIZE(rtl_ratetable), | 140 | .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g), |
102 | 141 | ||
103 | .ht_cap = {0}, | 142 | .ht_cap = {0}, |
104 | }; | 143 | }; |
105 | 144 | ||
145 | static struct ieee80211_supported_band rtl_band_5ghz = { | ||
146 | .band = IEEE80211_BAND_5GHZ, | ||
147 | |||
148 | .channels = rtl_channeltable_5g, | ||
149 | .n_channels = ARRAY_SIZE(rtl_channeltable_5g), | ||
150 | |||
151 | .bitrates = rtl_ratetable_5g, | ||
152 | .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g), | ||
153 | |||
154 | .ht_cap = {0}, | ||
155 | }; | ||
156 | |||
157 | static const u8 tid_to_ac[] = { | ||
158 | 2, /* IEEE80211_AC_BE */ | ||
159 | 3, /* IEEE80211_AC_BK */ | ||
160 | 3, /* IEEE80211_AC_BK */ | ||
161 | 2, /* IEEE80211_AC_BE */ | ||
162 | 1, /* IEEE80211_AC_VI */ | ||
163 | 1, /* IEEE80211_AC_VI */ | ||
164 | 0, /* IEEE80211_AC_VO */ | ||
165 | 0, /* IEEE80211_AC_VO */ | ||
166 | }; | ||
167 | |||
168 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid) | ||
169 | { | ||
170 | return tid_to_ac[tid]; | ||
171 | } | ||
172 | |||
106 | static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | 173 | static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, |
107 | struct ieee80211_sta_ht_cap *ht_cap) | 174 | struct ieee80211_sta_ht_cap *ht_cap) |
108 | { | 175 | { |
@@ -115,6 +182,9 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | |||
115 | IEEE80211_HT_CAP_SGI_20 | | 182 | IEEE80211_HT_CAP_SGI_20 | |
116 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; | 183 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; |
117 | 184 | ||
185 | if (rtlpriv->rtlhal.disable_amsdu_8k) | ||
186 | ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; | ||
187 | |||
118 | /* | 188 | /* |
119 | *Maximum length of AMPDU that the STA can receive. | 189 | *Maximum length of AMPDU that the STA can receive. |
120 | *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) | 190 | *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) |
@@ -159,37 +229,99 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | |||
159 | 229 | ||
160 | static void _rtl_init_mac80211(struct ieee80211_hw *hw) | 230 | static void _rtl_init_mac80211(struct ieee80211_hw *hw) |
161 | { | 231 | { |
232 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
233 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
162 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); | 234 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); |
163 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 235 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
164 | struct ieee80211_supported_band *sband; | 236 | struct ieee80211_supported_band *sband; |
165 | 237 | ||
166 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
167 | sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); | ||
168 | 238 | ||
169 | /* | 239 | if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset == |
170 | * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] | 240 | BAND_ON_BOTH) { |
171 | * to default value(1T1R) | 241 | /* 1: 2.4 G bands */ |
172 | */ | 242 | /* <1> use mac->bands as mem for hw->wiphy->bands */ |
173 | memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, | 243 | sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); |
174 | sizeof(struct ieee80211_supported_band)); | 244 | |
245 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] | ||
246 | * to default value(1T1R) */ | ||
247 | memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, | ||
248 | sizeof(struct ieee80211_supported_band)); | ||
175 | 249 | ||
176 | /* <3> init ht cap base on ant_num */ | 250 | /* <3> init ht cap base on ant_num */ |
177 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | 251 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); |
178 | 252 | ||
179 | /* <4> set mac->sband to wiphy->sband */ | 253 | /* <4> set mac->sband to wiphy->sband */ |
180 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | 254 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; |
181 | 255 | ||
256 | /* 2: 5 G bands */ | ||
257 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
258 | sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); | ||
259 | |||
260 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] | ||
261 | * to default value(1T1R) */ | ||
262 | memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz, | ||
263 | sizeof(struct ieee80211_supported_band)); | ||
264 | |||
265 | /* <3> init ht cap base on ant_num */ | ||
266 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | ||
267 | |||
268 | /* <4> set mac->sband to wiphy->sband */ | ||
269 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | ||
270 | } else { | ||
271 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { | ||
272 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
273 | sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); | ||
274 | |||
275 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] | ||
276 | * to default value(1T1R) */ | ||
277 | memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), | ||
278 | &rtl_band_2ghz, | ||
279 | sizeof(struct ieee80211_supported_band)); | ||
280 | |||
281 | /* <3> init ht cap base on ant_num */ | ||
282 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | ||
283 | |||
284 | /* <4> set mac->sband to wiphy->sband */ | ||
285 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | ||
286 | } else if (rtlhal->current_bandtype == BAND_ON_5G) { | ||
287 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
288 | sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); | ||
289 | |||
290 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] | ||
291 | * to default value(1T1R) */ | ||
292 | memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), | ||
293 | &rtl_band_5ghz, | ||
294 | sizeof(struct ieee80211_supported_band)); | ||
295 | |||
296 | /* <3> init ht cap base on ant_num */ | ||
297 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | ||
298 | |||
299 | /* <4> set mac->sband to wiphy->sband */ | ||
300 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | ||
301 | } else { | ||
302 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
303 | ("Err BAND %d\n", | ||
304 | rtlhal->current_bandtype)); | ||
305 | } | ||
306 | } | ||
182 | /* <5> set hw caps */ | 307 | /* <5> set hw caps */ |
183 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 308 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
184 | IEEE80211_HW_RX_INCLUDES_FCS | | 309 | IEEE80211_HW_RX_INCLUDES_FCS | |
185 | IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/ | 310 | IEEE80211_HW_BEACON_FILTER | |
186 | /*IEEE80211_HW_SUPPORTS_PS | */ | 311 | IEEE80211_HW_AMPDU_AGGREGATION | |
187 | /*IEEE80211_HW_PS_NULLFUNC_STACK | */ | ||
188 | /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ | ||
189 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; | 312 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; |
190 | 313 | ||
314 | /* swlps or hwlps has been set in diff chip in init_sw_vars */ | ||
315 | if (rtlpriv->psc.swctrl_lps) | ||
316 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
317 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
318 | /* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ | ||
319 | 0; | ||
320 | |||
191 | hw->wiphy->interface_modes = | 321 | hw->wiphy->interface_modes = |
192 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); | 322 | BIT(NL80211_IFTYPE_AP) | |
323 | BIT(NL80211_IFTYPE_STATION) | | ||
324 | BIT(NL80211_IFTYPE_ADHOC); | ||
193 | 325 | ||
194 | hw->wiphy->rts_threshold = 2347; | 326 | hw->wiphy->rts_threshold = 2347; |
195 | 327 | ||
@@ -199,9 +331,10 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) | |||
199 | /* TODO: Correct this value for our hw */ | 331 | /* TODO: Correct this value for our hw */ |
200 | /* TODO: define these hard code value */ | 332 | /* TODO: define these hard code value */ |
201 | hw->channel_change_time = 100; | 333 | hw->channel_change_time = 100; |
202 | hw->max_listen_interval = 5; | 334 | hw->max_listen_interval = 10; |
203 | hw->max_rate_tries = 4; | 335 | hw->max_rate_tries = 4; |
204 | /* hw->max_rates = 1; */ | 336 | /* hw->max_rates = 1; */ |
337 | hw->sta_data_size = sizeof(struct rtl_sta_info); | ||
205 | 338 | ||
206 | /* <6> mac address */ | 339 | /* <6> mac address */ |
207 | if (is_valid_ether_addr(rtlefuse->dev_addr)) { | 340 | if (is_valid_ether_addr(rtlefuse->dev_addr)) { |
@@ -230,6 +363,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) | |||
230 | (void *)rtl_watchdog_wq_callback); | 363 | (void *)rtl_watchdog_wq_callback); |
231 | INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, | 364 | INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, |
232 | (void *)rtl_ips_nic_off_wq_callback); | 365 | (void *)rtl_ips_nic_off_wq_callback); |
366 | INIT_DELAYED_WORK(&rtlpriv->works.ps_work, | ||
367 | (void *)rtl_swlps_wq_callback); | ||
368 | INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq, | ||
369 | (void *)rtl_swlps_rfon_wq_callback); | ||
233 | 370 | ||
234 | } | 371 | } |
235 | 372 | ||
@@ -241,6 +378,8 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw) | |||
241 | 378 | ||
242 | cancel_delayed_work(&rtlpriv->works.watchdog_wq); | 379 | cancel_delayed_work(&rtlpriv->works.watchdog_wq); |
243 | cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); | 380 | cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); |
381 | cancel_delayed_work(&rtlpriv->works.ps_work); | ||
382 | cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); | ||
244 | } | 383 | } |
245 | 384 | ||
246 | void rtl_init_rfkill(struct ieee80211_hw *hw) | 385 | void rtl_init_rfkill(struct ieee80211_hw *hw) |
@@ -310,6 +449,8 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
310 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); | 449 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); |
311 | spin_lock_init(&rtlpriv->locks.rf_lock); | 450 | spin_lock_init(&rtlpriv->locks.rf_lock); |
312 | spin_lock_init(&rtlpriv->locks.lps_lock); | 451 | spin_lock_init(&rtlpriv->locks.lps_lock); |
452 | spin_lock_init(&rtlpriv->locks.waitq_lock); | ||
453 | spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); | ||
313 | 454 | ||
314 | rtlmac->link_state = MAC80211_NOLINK; | 455 | rtlmac->link_state = MAC80211_NOLINK; |
315 | 456 | ||
@@ -329,12 +470,6 @@ void rtl_init_rx_config(struct ieee80211_hw *hw) | |||
329 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 470 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
330 | 471 | ||
331 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); | 472 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); |
332 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER, | ||
333 | (u8 *) (&mac->rx_mgt_filter)); | ||
334 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER, | ||
335 | (u8 *) (&mac->rx_ctrl_filter)); | ||
336 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER, | ||
337 | (u8 *) (&mac->rx_data_filter)); | ||
338 | } | 473 | } |
339 | 474 | ||
340 | /********************************************************* | 475 | /********************************************************* |
@@ -361,28 +496,40 @@ static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw, | |||
361 | } | 496 | } |
362 | 497 | ||
363 | static void _rtl_query_shortgi(struct ieee80211_hw *hw, | 498 | static void _rtl_query_shortgi(struct ieee80211_hw *hw, |
499 | struct ieee80211_sta *sta, | ||
364 | struct rtl_tcb_desc *tcb_desc, | 500 | struct rtl_tcb_desc *tcb_desc, |
365 | struct ieee80211_tx_info *info) | 501 | struct ieee80211_tx_info *info) |
366 | { | 502 | { |
367 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 503 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
368 | u8 rate_flag = info->control.rates[0].flags; | 504 | u8 rate_flag = info->control.rates[0].flags; |
369 | 505 | u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0; | |
370 | tcb_desc->use_shortgi = false; | 506 | tcb_desc->use_shortgi = false; |
371 | 507 | ||
372 | if (!mac->ht_enable) | 508 | if (sta == NULL) |
509 | return; | ||
510 | |||
511 | sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; | ||
512 | sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; | ||
513 | |||
514 | if (!(sta->ht_cap.ht_supported)) | ||
373 | return; | 515 | return; |
374 | 516 | ||
375 | if (!mac->sgi_40 && !mac->sgi_20) | 517 | if (!sgi_40 && !sgi_20) |
376 | return; | 518 | return; |
377 | 519 | ||
378 | if ((mac->bw_40 == true) && mac->sgi_40) | 520 | if (mac->opmode == NL80211_IFTYPE_STATION) |
521 | bw_40 = mac->bw_40; | ||
522 | else if (mac->opmode == NL80211_IFTYPE_AP || | ||
523 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
524 | bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
525 | |||
526 | if ((bw_40 == true) && sgi_40) | ||
379 | tcb_desc->use_shortgi = true; | 527 | tcb_desc->use_shortgi = true; |
380 | else if ((mac->bw_40 == false) && mac->sgi_20) | 528 | else if ((bw_40 == false) && sgi_20) |
381 | tcb_desc->use_shortgi = true; | 529 | tcb_desc->use_shortgi = true; |
382 | 530 | ||
383 | if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI)) | 531 | if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI)) |
384 | tcb_desc->use_shortgi = false; | 532 | tcb_desc->use_shortgi = false; |
385 | |||
386 | } | 533 | } |
387 | 534 | ||
388 | static void _rtl_query_protection_mode(struct ieee80211_hw *hw, | 535 | static void _rtl_query_protection_mode(struct ieee80211_hw *hw, |
@@ -410,19 +557,25 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw, | |||
410 | tcb_desc->rts_enable = true; | 557 | tcb_desc->rts_enable = true; |
411 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; | 558 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; |
412 | } | 559 | } |
413 | |||
414 | } | 560 | } |
415 | 561 | ||
416 | static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, | 562 | static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, |
563 | struct ieee80211_sta *sta, | ||
417 | struct rtl_tcb_desc *tcb_desc) | 564 | struct rtl_tcb_desc *tcb_desc) |
418 | { | 565 | { |
419 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 566 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
420 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 567 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
568 | struct rtl_sta_info *sta_entry = NULL; | ||
569 | u8 ratr_index = 7; | ||
421 | 570 | ||
571 | if (sta) { | ||
572 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
573 | ratr_index = sta_entry->ratr_index; | ||
574 | } | ||
422 | if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { | 575 | if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { |
423 | if (mac->opmode == NL80211_IFTYPE_STATION) | 576 | if (mac->opmode == NL80211_IFTYPE_STATION) { |
424 | tcb_desc->ratr_index = 0; | 577 | tcb_desc->ratr_index = 0; |
425 | else if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 578 | } else if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
426 | if (tcb_desc->multicast || tcb_desc->broadcast) { | 579 | if (tcb_desc->multicast || tcb_desc->broadcast) { |
427 | tcb_desc->hw_rate = | 580 | tcb_desc->hw_rate = |
428 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; | 581 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; |
@@ -430,36 +583,61 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, | |||
430 | } else { | 583 | } else { |
431 | /* TODO */ | 584 | /* TODO */ |
432 | } | 585 | } |
586 | tcb_desc->ratr_index = ratr_index; | ||
587 | } else if (mac->opmode == NL80211_IFTYPE_AP) { | ||
588 | tcb_desc->ratr_index = ratr_index; | ||
433 | } | 589 | } |
434 | } | 590 | } |
435 | 591 | ||
436 | if (rtlpriv->dm.useramask) { | 592 | if (rtlpriv->dm.useramask) { |
437 | /* TODO adhoc and station handled differently in the future */ | 593 | /* TODO we will differentiate adhoc and station futrue */ |
438 | tcb_desc->mac_id = 0; | 594 | if (mac->opmode == NL80211_IFTYPE_STATION) { |
439 | 595 | tcb_desc->mac_id = 0; | |
440 | if ((mac->mode == WIRELESS_MODE_N_24G) || | 596 | |
441 | (mac->mode == WIRELESS_MODE_N_5G)) { | 597 | if (mac->mode == WIRELESS_MODE_N_24G) |
442 | tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; | 598 | tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; |
443 | } else if (mac->mode & WIRELESS_MODE_G) { | 599 | else if (mac->mode == WIRELESS_MODE_N_5G) |
444 | tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; | 600 | tcb_desc->ratr_index = RATR_INX_WIRELESS_NG; |
445 | } else if (mac->mode & WIRELESS_MODE_B) { | 601 | else if (mac->mode & WIRELESS_MODE_G) |
446 | tcb_desc->ratr_index = RATR_INX_WIRELESS_B; | 602 | tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; |
603 | else if (mac->mode & WIRELESS_MODE_B) | ||
604 | tcb_desc->ratr_index = RATR_INX_WIRELESS_B; | ||
605 | else if (mac->mode & WIRELESS_MODE_A) | ||
606 | tcb_desc->ratr_index = RATR_INX_WIRELESS_G; | ||
607 | } else if (mac->opmode == NL80211_IFTYPE_AP || | ||
608 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
609 | if (NULL != sta) { | ||
610 | if (sta->aid > 0) | ||
611 | tcb_desc->mac_id = sta->aid + 1; | ||
612 | else | ||
613 | tcb_desc->mac_id = 1; | ||
614 | } else { | ||
615 | tcb_desc->mac_id = 0; | ||
616 | } | ||
447 | } | 617 | } |
448 | } | 618 | } |
449 | 619 | ||
450 | } | 620 | } |
451 | 621 | ||
452 | static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, | 622 | static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, |
623 | struct ieee80211_sta *sta, | ||
453 | struct rtl_tcb_desc *tcb_desc) | 624 | struct rtl_tcb_desc *tcb_desc) |
454 | { | 625 | { |
455 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 626 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
456 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 627 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
457 | 628 | ||
458 | tcb_desc->packet_bw = false; | 629 | tcb_desc->packet_bw = false; |
459 | 630 | if (!sta) | |
460 | if (!mac->bw_40 || !mac->ht_enable) | ||
461 | return; | 631 | return; |
462 | 632 | if (mac->opmode == NL80211_IFTYPE_AP || | |
633 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
634 | if (!(sta->ht_cap.ht_supported) || | ||
635 | !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | ||
636 | return; | ||
637 | } else if (mac->opmode == NL80211_IFTYPE_STATION) { | ||
638 | if (!mac->bw_40 || !(sta->ht_cap.ht_supported)) | ||
639 | return; | ||
640 | } | ||
463 | if (tcb_desc->multicast || tcb_desc->broadcast) | 641 | if (tcb_desc->multicast || tcb_desc->broadcast) |
464 | return; | 642 | return; |
465 | 643 | ||
@@ -486,22 +664,21 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw) | |||
486 | 664 | ||
487 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, | 665 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, |
488 | struct ieee80211_tx_info *info, | 666 | struct ieee80211_tx_info *info, |
667 | struct ieee80211_sta *sta, | ||
489 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc) | 668 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc) |
490 | { | 669 | { |
491 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 670 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
492 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); | 671 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); |
493 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 672 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); |
494 | struct ieee80211_rate *txrate; | 673 | struct ieee80211_rate *txrate; |
495 | __le16 fc = hdr->frame_control; | 674 | __le16 fc = hdr->frame_control; |
496 | 675 | ||
497 | memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | 676 | txrate = ieee80211_get_tx_rate(hw, info); |
677 | tcb_desc->hw_rate = txrate->hw_value; | ||
498 | 678 | ||
499 | if (ieee80211_is_data(fc)) { | 679 | if (ieee80211_is_data(fc)) { |
500 | txrate = ieee80211_get_tx_rate(hw, info); | ||
501 | tcb_desc->hw_rate = txrate->hw_value; | ||
502 | |||
503 | /* | 680 | /* |
504 | *we set data rate RTL_RC_CCK_RATE1M | 681 | *we set data rate INX 0 |
505 | *in rtl_rc.c if skb is special data or | 682 | *in rtl_rc.c if skb is special data or |
506 | *mgt which need low data rate. | 683 | *mgt which need low data rate. |
507 | */ | 684 | */ |
@@ -510,12 +687,11 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
510 | *So tcb_desc->hw_rate is just used for | 687 | *So tcb_desc->hw_rate is just used for |
511 | *special data and mgt frames | 688 | *special data and mgt frames |
512 | */ | 689 | */ |
513 | if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) { | 690 | if (info->control.rates[0].idx == 0 && |
691 | ieee80211_is_nullfunc(fc)) { | ||
514 | tcb_desc->use_driver_rate = true; | 692 | tcb_desc->use_driver_rate = true; |
515 | tcb_desc->ratr_index = 7; | 693 | tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; |
516 | 694 | ||
517 | tcb_desc->hw_rate = | ||
518 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; | ||
519 | tcb_desc->disable_ratefallback = 1; | 695 | tcb_desc->disable_ratefallback = 1; |
520 | } else { | 696 | } else { |
521 | /* | 697 | /* |
@@ -525,7 +701,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
525 | *and N rate will all be controled by FW | 701 | *and N rate will all be controled by FW |
526 | *when tcb_desc->use_driver_rate = false | 702 | *when tcb_desc->use_driver_rate = false |
527 | */ | 703 | */ |
528 | if (rtlmac->ht_enable) { | 704 | if (sta && (sta->ht_cap.ht_supported)) { |
529 | tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw); | 705 | tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw); |
530 | } else { | 706 | } else { |
531 | if (rtlmac->mode == WIRELESS_MODE_B) { | 707 | if (rtlmac->mode == WIRELESS_MODE_B) { |
@@ -543,43 +719,25 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
543 | else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) | 719 | else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) |
544 | tcb_desc->broadcast = 1; | 720 | tcb_desc->broadcast = 1; |
545 | 721 | ||
546 | _rtl_txrate_selectmode(hw, tcb_desc); | 722 | _rtl_txrate_selectmode(hw, sta, tcb_desc); |
547 | _rtl_query_bandwidth_mode(hw, tcb_desc); | 723 | _rtl_query_bandwidth_mode(hw, sta, tcb_desc); |
548 | _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info); | 724 | _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info); |
549 | _rtl_query_shortgi(hw, tcb_desc, info); | 725 | _rtl_query_shortgi(hw, sta, tcb_desc, info); |
550 | _rtl_query_protection_mode(hw, tcb_desc, info); | 726 | _rtl_query_protection_mode(hw, tcb_desc, info); |
551 | } else { | 727 | } else { |
552 | tcb_desc->use_driver_rate = true; | 728 | tcb_desc->use_driver_rate = true; |
553 | tcb_desc->ratr_index = 7; | 729 | tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; |
554 | tcb_desc->disable_ratefallback = 1; | 730 | tcb_desc->disable_ratefallback = 1; |
555 | tcb_desc->mac_id = 0; | 731 | tcb_desc->mac_id = 0; |
556 | 732 | tcb_desc->packet_bw = false; | |
557 | tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; | ||
558 | } | 733 | } |
559 | } | 734 | } |
560 | EXPORT_SYMBOL(rtl_get_tcb_desc); | 735 | EXPORT_SYMBOL(rtl_get_tcb_desc); |
561 | 736 | ||
562 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
563 | { | ||
564 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
565 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
566 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
567 | __le16 fc = hdr->frame_control; | ||
568 | |||
569 | if (ieee80211_is_auth(fc)) { | ||
570 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); | ||
571 | rtl_ips_nic_on(hw); | ||
572 | |||
573 | mac->link_state = MAC80211_LINKING; | ||
574 | } | ||
575 | |||
576 | return true; | ||
577 | } | ||
578 | |||
579 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | 737 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) |
580 | { | 738 | { |
581 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 739 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
582 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 740 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); |
583 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 741 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
584 | __le16 fc = hdr->frame_control; | 742 | __le16 fc = hdr->frame_control; |
585 | u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); | 743 | u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); |
@@ -624,9 +782,8 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
624 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | 782 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) |
625 | { | 783 | { |
626 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 784 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
627 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
628 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 785 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
629 | __le16 fc = hdr->frame_control; | 786 | __le16 fc = rtl_get_fc(skb); |
630 | u16 ether_type; | 787 | u16 ether_type; |
631 | u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); | 788 | u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); |
632 | const struct iphdr *ip; | 789 | const struct iphdr *ip; |
@@ -634,12 +791,11 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
634 | if (!ieee80211_is_data(fc)) | 791 | if (!ieee80211_is_data(fc)) |
635 | return false; | 792 | return false; |
636 | 793 | ||
637 | if (ieee80211_is_nullfunc(fc)) | ||
638 | return true; | ||
639 | 794 | ||
640 | ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + | 795 | ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + |
641 | SNAP_SIZE + PROTOC_TYPE_SIZE); | 796 | SNAP_SIZE + PROTOC_TYPE_SIZE); |
642 | ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); | 797 | ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); |
798 | ether_type = ntohs(ether_type); | ||
643 | 799 | ||
644 | if (ETH_P_IP == ether_type) { | 800 | if (ETH_P_IP == ether_type) { |
645 | if (IPPROTO_UDP == ip->protocol) { | 801 | if (IPPROTO_UDP == ip->protocol) { |
@@ -696,61 +852,92 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
696 | * functions called by core.c | 852 | * functions called by core.c |
697 | * | 853 | * |
698 | *********************************************************/ | 854 | *********************************************************/ |
699 | int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn) | 855 | int rtl_tx_agg_start(struct ieee80211_hw *hw, |
856 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | ||
700 | { | 857 | { |
701 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 858 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
702 | struct rtl_tid_data *tid_data; | 859 | struct rtl_tid_data *tid_data; |
703 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 860 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
861 | struct rtl_sta_info *sta_entry = NULL; | ||
704 | 862 | ||
705 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, | 863 | if (sta == NULL) |
706 | ("on ra = %pM tid = %d\n", ra, tid)); | 864 | return -EINVAL; |
707 | 865 | ||
708 | if (unlikely(tid >= MAX_TID_COUNT)) | 866 | if (unlikely(tid >= MAX_TID_COUNT)) |
709 | return -EINVAL; | 867 | return -EINVAL; |
710 | 868 | ||
711 | if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) { | 869 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
712 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 870 | if (!sta_entry) |
713 | ("Start AGG when state is not RTL_AGG_OFF !\n")); | ||
714 | return -ENXIO; | 871 | return -ENXIO; |
715 | } | 872 | tid_data = &sta_entry->tids[tid]; |
716 | |||
717 | tid_data = &mac->tids[tid]; | ||
718 | *ssn = SEQ_TO_SN(tid_data->seq_number); | ||
719 | 873 | ||
720 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, | 874 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, |
721 | ("HW queue is empty tid:%d\n", tid)); | 875 | ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, |
722 | tid_data->agg.agg_state = RTL_AGG_ON; | 876 | tid_data->seq_number)); |
723 | 877 | ||
724 | ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid); | 878 | *ssn = tid_data->seq_number; |
879 | tid_data->agg.agg_state = RTL_AGG_START; | ||
880 | |||
881 | ieee80211_start_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); | ||
725 | 882 | ||
726 | return 0; | 883 | return 0; |
727 | } | 884 | } |
728 | 885 | ||
729 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid) | 886 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, |
887 | struct ieee80211_sta *sta, u16 tid) | ||
730 | { | 888 | { |
731 | int ssn = -1; | ||
732 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 889 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
733 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 890 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
734 | struct rtl_tid_data *tid_data; | 891 | struct rtl_tid_data *tid_data; |
892 | struct rtl_sta_info *sta_entry = NULL; | ||
893 | |||
894 | if (sta == NULL) | ||
895 | return -EINVAL; | ||
735 | 896 | ||
736 | if (!ra) { | 897 | if (!sta->addr) { |
737 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); | 898 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); |
738 | return -EINVAL; | 899 | return -EINVAL; |
739 | } | 900 | } |
740 | 901 | ||
902 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, | ||
903 | ("on ra = %pM tid = %d\n", sta->addr, tid)); | ||
904 | |||
741 | if (unlikely(tid >= MAX_TID_COUNT)) | 905 | if (unlikely(tid >= MAX_TID_COUNT)) |
742 | return -EINVAL; | 906 | return -EINVAL; |
743 | 907 | ||
744 | if (mac->tids[tid].agg.agg_state != RTL_AGG_ON) | 908 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
745 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 909 | tid_data = &sta_entry->tids[tid]; |
746 | ("Stopping AGG while state not ON or starting\n")); | 910 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; |
747 | 911 | ||
748 | tid_data = &mac->tids[tid]; | 912 | ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); |
749 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; | ||
750 | 913 | ||
751 | mac->tids[tid].agg.agg_state = RTL_AGG_OFF; | 914 | return 0; |
915 | } | ||
916 | |||
917 | int rtl_tx_agg_oper(struct ieee80211_hw *hw, | ||
918 | struct ieee80211_sta *sta, u16 tid) | ||
919 | { | ||
920 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
921 | struct rtl_tid_data *tid_data; | ||
922 | struct rtl_sta_info *sta_entry = NULL; | ||
752 | 923 | ||
753 | ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid); | 924 | if (sta == NULL) |
925 | return -EINVAL; | ||
926 | |||
927 | if (!sta->addr) { | ||
928 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); | ||
929 | return -EINVAL; | ||
930 | } | ||
931 | |||
932 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, | ||
933 | ("on ra = %pM tid = %d\n", sta->addr, tid)); | ||
934 | |||
935 | if (unlikely(tid >= MAX_TID_COUNT)) | ||
936 | return -EINVAL; | ||
937 | |||
938 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; | ||
939 | tid_data = &sta_entry->tids[tid]; | ||
940 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL; | ||
754 | 941 | ||
755 | return 0; | 942 | return 0; |
756 | } | 943 | } |
@@ -769,18 +956,16 @@ void rtl_watchdog_wq_callback(void *data) | |||
769 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 956 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
770 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 957 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
771 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 958 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
772 | |||
773 | bool busytraffic = false; | 959 | bool busytraffic = false; |
774 | bool higher_busytraffic = false; | 960 | bool higher_busytraffic = false; |
775 | bool higher_busyrxtraffic = false; | 961 | bool higher_busyrxtraffic = false; |
776 | bool higher_busytxtraffic = false; | 962 | u8 idx, tid; |
777 | |||
778 | u8 idx = 0; | ||
779 | u32 rx_cnt_inp4eriod = 0; | 963 | u32 rx_cnt_inp4eriod = 0; |
780 | u32 tx_cnt_inp4eriod = 0; | 964 | u32 tx_cnt_inp4eriod = 0; |
781 | u32 aver_rx_cnt_inperiod = 0; | 965 | u32 aver_rx_cnt_inperiod = 0; |
782 | u32 aver_tx_cnt_inperiod = 0; | 966 | u32 aver_tx_cnt_inperiod = 0; |
783 | 967 | u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0}; | |
968 | u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0}; | ||
784 | bool enter_ps = false; | 969 | bool enter_ps = false; |
785 | 970 | ||
786 | if (is_hal_stop(rtlhal)) | 971 | if (is_hal_stop(rtlhal)) |
@@ -794,9 +979,6 @@ void rtl_watchdog_wq_callback(void *data) | |||
794 | mac->cnt_after_linked = 0; | 979 | mac->cnt_after_linked = 0; |
795 | } | 980 | } |
796 | 981 | ||
797 | /* <2> DM */ | ||
798 | rtlpriv->cfg->ops->dm_watchdog(hw); | ||
799 | |||
800 | /* | 982 | /* |
801 | *<3> to check if traffic busy, if | 983 | *<3> to check if traffic busy, if |
802 | * busytraffic we don't change channel | 984 | * busytraffic we don't change channel |
@@ -835,8 +1017,27 @@ void rtl_watchdog_wq_callback(void *data) | |||
835 | /* Extremely high Rx data. */ | 1017 | /* Extremely high Rx data. */ |
836 | if (aver_rx_cnt_inperiod > 5000) | 1018 | if (aver_rx_cnt_inperiod > 5000) |
837 | higher_busyrxtraffic = true; | 1019 | higher_busyrxtraffic = true; |
1020 | } | ||
1021 | |||
1022 | /* check every tid's tx traffic */ | ||
1023 | for (tid = 0; tid <= 7; tid++) { | ||
1024 | for (idx = 0; idx <= 2; idx++) | ||
1025 | rtlpriv->link_info.tidtx_in4period[tid][idx] = | ||
1026 | rtlpriv->link_info.tidtx_in4period[tid] | ||
1027 | [idx + 1]; | ||
1028 | rtlpriv->link_info.tidtx_in4period[tid][3] = | ||
1029 | rtlpriv->link_info.tidtx_inperiod[tid]; | ||
1030 | |||
1031 | for (idx = 0; idx <= 3; idx++) | ||
1032 | tidtx_inp4eriod[tid] += | ||
1033 | rtlpriv->link_info.tidtx_in4period[tid][idx]; | ||
1034 | aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4; | ||
1035 | if (aver_tidtx_inperiod[tid] > 5000) | ||
1036 | rtlpriv->link_info.higher_busytxtraffic[tid] = | ||
1037 | true; | ||
838 | else | 1038 | else |
839 | higher_busytxtraffic = false; | 1039 | rtlpriv->link_info.higher_busytxtraffic[tid] = |
1040 | false; | ||
840 | } | 1041 | } |
841 | 1042 | ||
842 | if (((rtlpriv->link_info.num_rx_inperiod + | 1043 | if (((rtlpriv->link_info.num_rx_inperiod + |
@@ -855,11 +1056,15 @@ void rtl_watchdog_wq_callback(void *data) | |||
855 | 1056 | ||
856 | rtlpriv->link_info.num_rx_inperiod = 0; | 1057 | rtlpriv->link_info.num_rx_inperiod = 0; |
857 | rtlpriv->link_info.num_tx_inperiod = 0; | 1058 | rtlpriv->link_info.num_tx_inperiod = 0; |
1059 | for (tid = 0; tid <= 7; tid++) | ||
1060 | rtlpriv->link_info.tidtx_inperiod[tid] = 0; | ||
858 | 1061 | ||
859 | rtlpriv->link_info.busytraffic = busytraffic; | 1062 | rtlpriv->link_info.busytraffic = busytraffic; |
860 | rtlpriv->link_info.higher_busytraffic = higher_busytraffic; | 1063 | rtlpriv->link_info.higher_busytraffic = higher_busytraffic; |
861 | rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; | 1064 | rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; |
862 | 1065 | ||
1066 | /* <3> DM */ | ||
1067 | rtlpriv->cfg->ops->dm_watchdog(hw); | ||
863 | } | 1068 | } |
864 | 1069 | ||
865 | void rtl_watch_dog_timer_callback(unsigned long data) | 1070 | void rtl_watch_dog_timer_callback(unsigned long data) |
@@ -876,6 +1081,274 @@ void rtl_watch_dog_timer_callback(unsigned long data) | |||
876 | 1081 | ||
877 | /********************************************************* | 1082 | /********************************************************* |
878 | * | 1083 | * |
1084 | * frame process functions | ||
1085 | * | ||
1086 | *********************************************************/ | ||
1087 | u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie) | ||
1088 | { | ||
1089 | struct ieee80211_mgmt *mgmt = (void *)data; | ||
1090 | u8 *pos, *end; | ||
1091 | |||
1092 | pos = (u8 *)mgmt->u.beacon.variable; | ||
1093 | end = data + len; | ||
1094 | while (pos < end) { | ||
1095 | if (pos + 2 + pos[1] > end) | ||
1096 | return NULL; | ||
1097 | |||
1098 | if (pos[0] == ie) | ||
1099 | return pos; | ||
1100 | |||
1101 | pos += 2 + pos[1]; | ||
1102 | } | ||
1103 | return NULL; | ||
1104 | } | ||
1105 | |||
1106 | /* when we use 2 rx ants we send IEEE80211_SMPS_OFF */ | ||
1107 | /* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */ | ||
1108 | struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw, | ||
1109 | enum ieee80211_smps_mode smps, u8 *da, u8 *bssid) | ||
1110 | { | ||
1111 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1112 | struct sk_buff *skb; | ||
1113 | struct ieee80211_mgmt *action_frame; | ||
1114 | |||
1115 | /* 27 = header + category + action + smps mode */ | ||
1116 | skb = dev_alloc_skb(27 + hw->extra_tx_headroom); | ||
1117 | if (!skb) | ||
1118 | return NULL; | ||
1119 | |||
1120 | skb_reserve(skb, hw->extra_tx_headroom); | ||
1121 | action_frame = (void *)skb_put(skb, 27); | ||
1122 | memset(action_frame, 0, 27); | ||
1123 | memcpy(action_frame->da, da, ETH_ALEN); | ||
1124 | memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN); | ||
1125 | memcpy(action_frame->bssid, bssid, ETH_ALEN); | ||
1126 | action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
1127 | IEEE80211_STYPE_ACTION); | ||
1128 | action_frame->u.action.category = WLAN_CATEGORY_HT; | ||
1129 | action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; | ||
1130 | switch (smps) { | ||
1131 | case IEEE80211_SMPS_AUTOMATIC:/* 0 */ | ||
1132 | case IEEE80211_SMPS_NUM_MODES:/* 4 */ | ||
1133 | WARN_ON(1); | ||
1134 | case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/ | ||
1135 | action_frame->u.action.u.ht_smps.smps_control = | ||
1136 | WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */ | ||
1137 | break; | ||
1138 | case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/ | ||
1139 | action_frame->u.action.u.ht_smps.smps_control = | ||
1140 | WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */ | ||
1141 | break; | ||
1142 | case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/ | ||
1143 | action_frame->u.action.u.ht_smps.smps_control = | ||
1144 | WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */ | ||
1145 | break; | ||
1146 | } | ||
1147 | |||
1148 | return skb; | ||
1149 | } | ||
1150 | |||
1151 | int rtl_send_smps_action(struct ieee80211_hw *hw, | ||
1152 | struct ieee80211_sta *sta, u8 *da, u8 *bssid, | ||
1153 | enum ieee80211_smps_mode smps) | ||
1154 | { | ||
1155 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1156 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1157 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1158 | struct sk_buff *skb = rtl_make_smps_action(hw, smps, da, bssid); | ||
1159 | struct rtl_tcb_desc tcb_desc; | ||
1160 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | ||
1161 | |||
1162 | if (rtlpriv->mac80211.act_scanning) | ||
1163 | goto err_free; | ||
1164 | |||
1165 | if (!sta) | ||
1166 | goto err_free; | ||
1167 | |||
1168 | if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) | ||
1169 | goto err_free; | ||
1170 | |||
1171 | if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) | ||
1172 | goto err_free; | ||
1173 | |||
1174 | /* this is a type = mgmt * stype = action frame */ | ||
1175 | if (skb) { | ||
1176 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1177 | struct rtl_sta_info *sta_entry = | ||
1178 | (struct rtl_sta_info *) sta->drv_priv; | ||
1179 | sta_entry->mimo_ps = smps; | ||
1180 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); | ||
1181 | |||
1182 | info->control.rates[0].idx = 0; | ||
1183 | info->control.sta = sta; | ||
1184 | info->band = hw->conf.channel->band; | ||
1185 | #if 0 | ||
1186 | rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); | ||
1187 | #else | ||
1188 | rtlpriv->intf_ops->adapter_tx(hw, skb); | ||
1189 | #endif | ||
1190 | } | ||
1191 | return 1; | ||
1192 | |||
1193 | err_free: | ||
1194 | return 0; | ||
1195 | } | ||
1196 | |||
1197 | /********************************************************* | ||
1198 | * | ||
1199 | * IOT functions | ||
1200 | * | ||
1201 | *********************************************************/ | ||
1202 | static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw, | ||
1203 | struct octet_string vendor_ie) | ||
1204 | { | ||
1205 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1206 | bool matched = false; | ||
1207 | static u8 athcap_1[] = { 0x00, 0x03, 0x7F }; | ||
1208 | static u8 athcap_2[] = { 0x00, 0x13, 0x74 }; | ||
1209 | static u8 broadcap_1[] = { 0x00, 0x10, 0x18 }; | ||
1210 | static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 }; | ||
1211 | static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 }; | ||
1212 | static u8 racap[] = { 0x00, 0x0c, 0x43 }; | ||
1213 | static u8 ciscocap[] = { 0x00, 0x40, 0x96 }; | ||
1214 | static u8 marvcap[] = { 0x00, 0x50, 0x43 }; | ||
1215 | |||
1216 | if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 || | ||
1217 | memcmp(vendor_ie.octet, athcap_2, 3) == 0) { | ||
1218 | rtlpriv->mac80211.vendor = PEER_ATH; | ||
1219 | matched = true; | ||
1220 | } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 || | ||
1221 | memcmp(vendor_ie.octet, broadcap_2, 3) == 0 || | ||
1222 | memcmp(vendor_ie.octet, broadcap_3, 3) == 0) { | ||
1223 | rtlpriv->mac80211.vendor = PEER_BROAD; | ||
1224 | matched = true; | ||
1225 | } else if (memcmp(vendor_ie.octet, racap, 3) == 0) { | ||
1226 | rtlpriv->mac80211.vendor = PEER_RAL; | ||
1227 | matched = true; | ||
1228 | } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) { | ||
1229 | rtlpriv->mac80211.vendor = PEER_CISCO; | ||
1230 | matched = true; | ||
1231 | } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) { | ||
1232 | rtlpriv->mac80211.vendor = PEER_MARV; | ||
1233 | matched = true; | ||
1234 | } | ||
1235 | |||
1236 | return matched; | ||
1237 | } | ||
1238 | |||
1239 | bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data, | ||
1240 | unsigned int len) | ||
1241 | { | ||
1242 | struct ieee80211_mgmt *mgmt = (void *)data; | ||
1243 | struct octet_string vendor_ie; | ||
1244 | u8 *pos, *end; | ||
1245 | |||
1246 | pos = (u8 *)mgmt->u.beacon.variable; | ||
1247 | end = data + len; | ||
1248 | while (pos < end) { | ||
1249 | if (pos[0] == 221) { | ||
1250 | vendor_ie.length = pos[1]; | ||
1251 | vendor_ie.octet = &pos[2]; | ||
1252 | if (rtl_chk_vendor_ouisub(hw, vendor_ie)) | ||
1253 | return true; | ||
1254 | } | ||
1255 | |||
1256 | if (pos + 2 + pos[1] > end) | ||
1257 | return false; | ||
1258 | |||
1259 | pos += 2 + pos[1]; | ||
1260 | } | ||
1261 | return false; | ||
1262 | } | ||
1263 | |||
1264 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) | ||
1265 | { | ||
1266 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1267 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1268 | struct ieee80211_hdr *hdr = (void *)data; | ||
1269 | u32 vendor = PEER_UNKNOWN; | ||
1270 | |||
1271 | static u8 ap3_1[3] = { 0x00, 0x14, 0xbf }; | ||
1272 | static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 }; | ||
1273 | static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e }; | ||
1274 | static u8 ap4_1[3] = { 0x00, 0x90, 0xcc }; | ||
1275 | static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e }; | ||
1276 | static u8 ap4_3[3] = { 0x00, 0x18, 0x02 }; | ||
1277 | static u8 ap4_4[3] = { 0x00, 0x17, 0x3f }; | ||
1278 | static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf }; | ||
1279 | static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 }; | ||
1280 | static u8 ap5_2[3] = { 0x00, 0x21, 0x91 }; | ||
1281 | static u8 ap5_3[3] = { 0x00, 0x24, 0x01 }; | ||
1282 | static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 }; | ||
1283 | static u8 ap5_5[3] = { 0x00, 0x17, 0x9A }; | ||
1284 | static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 }; | ||
1285 | static u8 ap6_1[3] = { 0x00, 0x17, 0x94 }; | ||
1286 | static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 }; | ||
1287 | |||
1288 | if (mac->opmode != NL80211_IFTYPE_STATION) | ||
1289 | return; | ||
1290 | |||
1291 | if (mac->link_state == MAC80211_NOLINK) { | ||
1292 | mac->vendor = PEER_UNKNOWN; | ||
1293 | return; | ||
1294 | } | ||
1295 | |||
1296 | if (mac->cnt_after_linked > 2) | ||
1297 | return; | ||
1298 | |||
1299 | /* check if this really is a beacon */ | ||
1300 | if (!ieee80211_is_beacon(hdr->frame_control)) | ||
1301 | return; | ||
1302 | |||
1303 | /* min. beacon length + FCS_LEN */ | ||
1304 | if (len <= 40 + FCS_LEN) | ||
1305 | return; | ||
1306 | |||
1307 | /* and only beacons from the associated BSSID, please */ | ||
1308 | if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) | ||
1309 | return; | ||
1310 | |||
1311 | if (rtl_find_221_ie(hw, data, len)) | ||
1312 | vendor = mac->vendor; | ||
1313 | |||
1314 | if ((memcmp(mac->bssid, ap5_1, 3) == 0) || | ||
1315 | (memcmp(mac->bssid, ap5_2, 3) == 0) || | ||
1316 | (memcmp(mac->bssid, ap5_3, 3) == 0) || | ||
1317 | (memcmp(mac->bssid, ap5_4, 3) == 0) || | ||
1318 | (memcmp(mac->bssid, ap5_5, 3) == 0) || | ||
1319 | (memcmp(mac->bssid, ap5_6, 3) == 0) || | ||
1320 | vendor == PEER_ATH) { | ||
1321 | vendor = PEER_ATH; | ||
1322 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n")); | ||
1323 | } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || | ||
1324 | (memcmp(mac->bssid, ap4_5, 3) == 0) || | ||
1325 | (memcmp(mac->bssid, ap4_1, 3) == 0) || | ||
1326 | (memcmp(mac->bssid, ap4_2, 3) == 0) || | ||
1327 | (memcmp(mac->bssid, ap4_3, 3) == 0) || | ||
1328 | vendor == PEER_RAL) { | ||
1329 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n")); | ||
1330 | vendor = PEER_RAL; | ||
1331 | } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || | ||
1332 | vendor == PEER_CISCO) { | ||
1333 | vendor = PEER_CISCO; | ||
1334 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n")); | ||
1335 | } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || | ||
1336 | (memcmp(mac->bssid, ap3_2, 3) == 0) || | ||
1337 | (memcmp(mac->bssid, ap3_3, 3) == 0) || | ||
1338 | vendor == PEER_BROAD) { | ||
1339 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n")); | ||
1340 | vendor = PEER_BROAD; | ||
1341 | } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || | ||
1342 | vendor == PEER_MARV) { | ||
1343 | vendor = PEER_MARV; | ||
1344 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n")); | ||
1345 | } | ||
1346 | |||
1347 | mac->vendor = vendor; | ||
1348 | } | ||
1349 | |||
1350 | /********************************************************* | ||
1351 | * | ||
879 | * sysfs functions | 1352 | * sysfs functions |
880 | * | 1353 | * |
881 | *********************************************************/ | 1354 | *********************************************************/ |
@@ -941,12 +1414,13 @@ static int __init rtl_core_module_init(void) | |||
941 | if (rtl_rate_control_register()) | 1414 | if (rtl_rate_control_register()) |
942 | printk(KERN_ERR "rtlwifi: Unable to register rtl_rc," | 1415 | printk(KERN_ERR "rtlwifi: Unable to register rtl_rc," |
943 | "use default RC !!\n"); | 1416 | "use default RC !!\n"); |
1417 | |||
944 | return 0; | 1418 | return 0; |
945 | } | 1419 | } |
946 | 1420 | ||
947 | static void __exit rtl_core_module_exit(void) | 1421 | static void __exit rtl_core_module_exit(void) |
948 | { | 1422 | { |
949 | /*RC*/ | 1423 | /*RC*/ |
950 | rtl_rate_control_unregister(); | 1424 | rtl_rate_control_unregister(); |
951 | } | 1425 | } |
952 | 1426 | ||
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 043045342bc7..a91f3eee59c8 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h | |||
@@ -24,13 +24,26 @@ | |||
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | 26 | * Larry Finger <Larry.Finger@lwfinger.net> |
27 | * | ||
27 | *****************************************************************************/ | 28 | *****************************************************************************/ |
28 | 29 | ||
29 | #ifndef __RTL_BASE_H__ | 30 | #ifndef __RTL_BASE_H__ |
30 | #define __RTL_BASE_H__ | 31 | #define __RTL_BASE_H__ |
31 | 32 | ||
33 | enum ap_peer { | ||
34 | PEER_UNKNOWN = 0, | ||
35 | PEER_RTL = 1, | ||
36 | PEER_RTL_92SE = 2, | ||
37 | PEER_BROAD = 3, | ||
38 | PEER_RAL = 4, | ||
39 | PEER_ATH = 5, | ||
40 | PEER_CISCO = 6, | ||
41 | PEER_MARV = 7, | ||
42 | PEER_AIRGO = 9, | ||
43 | PEER_MAX = 10, | ||
44 | } ; | ||
45 | |||
32 | #define RTL_DUMMY_OFFSET 0 | 46 | #define RTL_DUMMY_OFFSET 0 |
33 | #define RTL_RX_DESC_SIZE 24 | ||
34 | #define RTL_DUMMY_UNIT 8 | 47 | #define RTL_DUMMY_UNIT 8 |
35 | #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) | 48 | #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) |
36 | #define RTL_TX_DESC_SIZE 32 | 49 | #define RTL_TX_DESC_SIZE 32 |
@@ -53,6 +66,14 @@ | |||
53 | #define FRAME_OFFSET_SEQUENCE 22 | 66 | #define FRAME_OFFSET_SEQUENCE 22 |
54 | #define FRAME_OFFSET_ADDRESS4 24 | 67 | #define FRAME_OFFSET_ADDRESS4 24 |
55 | 68 | ||
69 | #define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \ | ||
70 | WRITEEF2BYTE(_hdr, _val) | ||
71 | #define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \ | ||
72 | WRITEEF1BYTE(_hdr, _val) | ||
73 | #define SET_80211_HDR_PWR_MGNT(_hdr, _val) \ | ||
74 | SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val) | ||
75 | #define SET_80211_HDR_TO_DS(_hdr, _val) \ | ||
76 | SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val) | ||
56 | 77 | ||
57 | #define SET_80211_PS_POLL_AID(_hdr, _val) \ | 78 | #define SET_80211_PS_POLL_AID(_hdr, _val) \ |
58 | (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) | 79 | (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) |
@@ -64,11 +85,27 @@ | |||
64 | #define SET_80211_HDR_DURATION(_hdr, _val) \ | 85 | #define SET_80211_HDR_DURATION(_hdr, _val) \ |
65 | (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val)) | 86 | (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val)) |
66 | #define SET_80211_HDR_ADDRESS1(_hdr, _val) \ | 87 | #define SET_80211_HDR_ADDRESS1(_hdr, _val) \ |
67 | memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN) | 88 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val)) |
68 | #define SET_80211_HDR_ADDRESS2(_hdr, _val) \ | 89 | #define SET_80211_HDR_ADDRESS2(_hdr, _val) \ |
69 | memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN) | 90 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val)) |
70 | #define SET_80211_HDR_ADDRESS3(_hdr, _val) \ | 91 | #define SET_80211_HDR_ADDRESS3(_hdr, _val) \ |
71 | memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN) | 92 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val)) |
93 | #define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \ | ||
94 | WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val) | ||
95 | |||
96 | #define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \ | ||
97 | WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val) | ||
98 | #define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \ | ||
99 | WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val) | ||
100 | #define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \ | ||
101 | WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val) | ||
102 | #define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \ | ||
103 | READEF2BYTE(((u8 *)(__phdr)) + 34) | ||
104 | #define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ | ||
105 | WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val) | ||
106 | #define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ | ||
107 | SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \ | ||
108 | (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val)))) | ||
72 | 109 | ||
73 | int rtl_init_core(struct ieee80211_hw *hw); | 110 | int rtl_init_core(struct ieee80211_hw *hw); |
74 | void rtl_deinit_core(struct ieee80211_hw *hw); | 111 | void rtl_deinit_core(struct ieee80211_hw *hw); |
@@ -80,18 +117,27 @@ void rtl_watch_dog_timer_callback(unsigned long data); | |||
80 | void rtl_deinit_deferred_work(struct ieee80211_hw *hw); | 117 | void rtl_deinit_deferred_work(struct ieee80211_hw *hw); |
81 | 118 | ||
82 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | 119 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); |
83 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
84 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | 120 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); |
85 | 121 | ||
86 | void rtl_watch_dog_timer_callback(unsigned long data); | 122 | void rtl_watch_dog_timer_callback(unsigned long data); |
87 | int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, | 123 | int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_sta *sta, |
88 | u16 tid, u16 *ssn); | 124 | u16 tid, u16 *ssn); |
89 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid); | 125 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_sta *sta, |
126 | u16 tid); | ||
127 | int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta, | ||
128 | u16 tid); | ||
90 | void rtl_watchdog_wq_callback(void *data); | 129 | void rtl_watchdog_wq_callback(void *data); |
91 | 130 | ||
92 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, | 131 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, |
93 | struct ieee80211_tx_info *info, | 132 | struct ieee80211_tx_info *info, |
133 | struct ieee80211_sta *sta, | ||
94 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); | 134 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); |
95 | 135 | ||
136 | int rtl_send_smps_action(struct ieee80211_hw *hw, | ||
137 | struct ieee80211_sta *sta, u8 *da, u8 *bssid, | ||
138 | enum ieee80211_smps_mode smps); | ||
139 | u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); | ||
140 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); | ||
141 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid); | ||
96 | extern struct attribute_group rtl_attribute_group; | 142 | extern struct attribute_group rtl_attribute_group; |
97 | #endif | 143 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 59a150ce3064..e2fa78bc1299 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -1242,8 +1242,6 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1242 | u8 own; | 1242 | u8 own; |
1243 | u8 temp_one = 1; | 1243 | u8 temp_one = 1; |
1244 | 1244 | ||
1245 | if (ieee80211_is_mgmt(fc)) | ||
1246 | rtl_tx_mgmt_proc(hw, skb); | ||
1247 | rtl_action_proc(hw, skb, true); | 1245 | rtl_action_proc(hw, skb, true); |
1248 | 1246 | ||
1249 | queue_index = skb_get_queue_mapping(skb); | 1247 | queue_index = skb_get_queue_mapping(skb); |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index c8395fb0c050..bdb3c5f5c4b0 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -416,6 +416,14 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) | |||
416 | } | 416 | } |
417 | } | 417 | } |
418 | 418 | ||
419 | void rtl_swlps_rfon_wq_callback(void *data) | ||
420 | { | ||
421 | } | ||
422 | |||
423 | void rtl_swlps_wq_callback(void *data) | ||
424 | { | ||
425 | } | ||
426 | |||
419 | /*Enter the leisure power save mode.*/ | 427 | /*Enter the leisure power save mode.*/ |
420 | void rtl_lps_enter(struct ieee80211_hw *hw) | 428 | void rtl_lps_enter(struct ieee80211_hw *hw) |
421 | { | 429 | { |
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index ae56da801a23..36aa24d6041f 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h | |||
@@ -40,4 +40,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw); | |||
40 | void rtl_ips_nic_off_wq_callback(void *data); | 40 | void rtl_ips_nic_off_wq_callback(void *data); |
41 | void rtl_lps_enter(struct ieee80211_hw *hw); | 41 | void rtl_lps_enter(struct ieee80211_hw *hw); |
42 | void rtl_lps_leave(struct ieee80211_hw *hw); | 42 | void rtl_lps_leave(struct ieee80211_hw *hw); |
43 | |||
44 | void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len); | ||
45 | void rtl_swlps_wq_callback(void *data); | ||
46 | void rtl_swlps_rfon_wq_callback(void *data); | ||
47 | void rtl_swlps_rf_awake(struct ieee80211_hw *hw); | ||
48 | void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); | ||
49 | |||
43 | #endif | 50 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index aa2b5815600f..356b8513b8a6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
@@ -754,7 +754,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
754 | 754 | ||
755 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | 755 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; |
756 | 756 | ||
757 | rtl_get_tcb_desc(hw, info, skb, &tcb_desc); | 757 | rtl_get_tcb_desc(hw, info, sta, skb, &tcb_desc); |
758 | 758 | ||
759 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); | 759 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); |
760 | 760 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 3f0cb81c424f..0df2fec27a08 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -517,7 +517,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | |||
517 | u8 *txdesc; | 517 | u8 *txdesc; |
518 | 518 | ||
519 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | 519 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; |
520 | rtl_get_tcb_desc(hw, info, skb, &tcb_desc); | 520 | rtl_get_tcb_desc(hw, info, sta, skb, &tcb_desc); |
521 | txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE); | 521 | txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE); |
522 | memset(txdesc, 0, RTL_TX_HEADER_SIZE); | 522 | memset(txdesc, 0, RTL_TX_HEADER_SIZE); |
523 | SET_TX_DESC_PKT_SIZE(txdesc, pktlen); | 523 | SET_TX_DESC_PKT_SIZE(txdesc, pktlen); |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f5d85735d642..f4ab1b7732c3 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -860,8 +860,6 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
860 | u8 tid = 0; | 860 | u8 tid = 0; |
861 | u16 seq_number = 0; | 861 | u16 seq_number = 0; |
862 | 862 | ||
863 | if (ieee80211_is_mgmt(fc)) | ||
864 | rtl_tx_mgmt_proc(hw, skb); | ||
865 | rtl_action_proc(hw, skb, true); | 863 | rtl_action_proc(hw, skb, true); |
866 | if (is_multicast_ether_addr(pda_addr)) | 864 | if (is_multicast_ether_addr(pda_addr)) |
867 | rtlpriv->stats.txbytesmulticast += skb->len; | 865 | rtlpriv->stats.txbytesmulticast += skb->len; |
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index abadfe918d30..d2a63fb3e1e6 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
32 | #include <linux/skbuff.h> | 32 | #include <linux/skbuff.h> |
33 | 33 | ||
34 | #define RTL_RX_DESC_SIZE 24 | ||
35 | |||
34 | #define RTL_USB_DEVICE(vend, prod, cfg) \ | 36 | #define RTL_USB_DEVICE(vend, prod, cfg) \ |
35 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ | 37 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ |
36 | .idVendor = (vend), \ | 38 | .idVendor = (vend), \ |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 9124b30c605d..7c52435a1180 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -1370,10 +1370,11 @@ struct rtl_hal_ops { | |||
1370 | u32 add_msr, u32 rm_msr); | 1370 | u32 add_msr, u32 rm_msr); |
1371 | void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); | 1371 | void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); |
1372 | void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); | 1372 | void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); |
1373 | #if 0 /* temporary */ | 1373 | #if 1 /* temporary */ |
1374 | void (*update_rate_tbl) (struct ieee80211_hw *hw, | 1374 | void (*update_rate_tbl) (struct ieee80211_hw *hw, |
1375 | struct ieee80211_sta *sta, u8 rssi_level); | 1375 | struct ieee80211_sta *sta, u8 rssi_level); |
1376 | #else | 1376 | #endif |
1377 | #if 1 /* temporary */ | ||
1377 | void (*update_rate_table) (struct ieee80211_hw *hw); | 1378 | void (*update_rate_table) (struct ieee80211_hw *hw); |
1378 | #endif | 1379 | #endif |
1379 | void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level); | 1380 | void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level); |