Commit | Line | Data |
---|---|---|
5adef66a LF |
1 | /****************************************************************************** |
2 | * | |
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
5adef66a LF |
14 | ******************************************************************************/ |
15 | #define _OS_INTFS_C_ | |
16 | ||
17 | #include <osdep_service.h> | |
0a95a7f4 | 18 | #include <osdep_intf.h> |
5adef66a LF |
19 | #include <drv_types.h> |
20 | #include <xmit_osdep.h> | |
21 | #include <recv_osdep.h> | |
22 | #include <hal_intf.h> | |
23 | #include <rtw_ioctl.h> | |
d6c28c23 | 24 | #include <rtl8188e_hal.h> |
5adef66a | 25 | |
5adef66a | 26 | #include <usb_hal.h> |
5adef66a LF |
27 | |
28 | MODULE_LICENSE("GPL"); | |
29 | MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); | |
30 | MODULE_AUTHOR("Realtek Semiconductor Corp."); | |
31 | MODULE_VERSION(DRIVERVERSION); | |
32 | ||
5adef66a LF |
33 | #define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */ |
34 | ||
35 | /* module param defaults */ | |
22a1279b | 36 | /* Ndis802_11Infrastructure; infra, ad-hoc, auto */ |
5adef66a LF |
37 | static int rtw_channel = 1;/* ad-hoc support requirement */ |
38 | static int rtw_wireless_mode = WIRELESS_11BG_24N; | |
39 | static int rtw_vrtl_carrier_sense = AUTO_VCS; | |
40 | static int rtw_vcs_type = RTS_CTS;/* */ | |
41 | static int rtw_rts_thresh = 2347;/* */ | |
42 | static int rtw_frag_thresh = 2346;/* */ | |
43 | static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */ | |
5adef66a LF |
44 | static int rtw_power_mgnt = 1; |
45 | static int rtw_ips_mode = IPS_NORMAL; | |
46 | ||
47 | static int rtw_smart_ps = 2; | |
48 | ||
49 | module_param(rtw_ips_mode, int, 0644); | |
50 | MODULE_PARM_DESC(rtw_ips_mode, "The default IPS mode"); | |
51 | ||
52 | static int rtw_debug = 1; | |
5adef66a | 53 | |
5adef66a LF |
54 | static int rtw_software_encrypt; |
55 | static int rtw_software_decrypt; | |
56 | ||
57 | static int rtw_acm_method;/* 0:By SW 1:By HW. */ | |
58 | ||
59 | static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */ | |
60 | static int rtw_uapsd_enable; | |
5adef66a | 61 | |
987bc3fe | 62 | static int rtw_ht_enable = 1; |
22a1279b LC |
63 | /* 0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */ |
64 | static int rtw_cbw40_enable = 3; | |
987bc3fe | 65 | static int rtw_ampdu_enable = 1;/* for enable tx_ampdu */ |
22a1279b LC |
66 | |
67 | /* 0: disable | |
68 | * bit(0):enable 2.4g | |
69 | * bit(1):enable 5g | |
70 | * default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ | |
71 | */ | |
72 | static int rtw_rx_stbc = 1; | |
5adef66a LF |
73 | static int rtw_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto */ |
74 | ||
5adef66a LF |
75 | static int rtw_wifi_spec; |
76 | static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX; | |
5adef66a LF |
77 | |
78 | static int rtw_antdiv_cfg = 2; /* 0:OFF , 1:ON, 2:decide by Efuse config */ | |
22a1279b LC |
79 | |
80 | /* 0: decide by efuse | |
81 | * 1: for 88EE, 1Tx and 1RxCG are diversity (2 Ant with SPDT) | |
82 | * 2: for 88EE, 1Tx and 2Rx are diversity (2 Ant, Tx and RxCG are both on aux | |
83 | * port, RxCS is on main port) | |
84 | * 3: for 88EE, 1Tx and 1RxCG are fixed (1Ant, Tx and RxCG are both on aux port) | |
85 | */ | |
86 | static int rtw_antdiv_type; | |
5adef66a LF |
87 | |
88 | static int rtw_enusbss;/* 0:disable, 1:enable */ | |
89 | ||
90 | static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */ | |
91 | ||
5adef66a LF |
92 | int rtw_mc2u_disable; |
93 | ||
94 | static int rtw_80211d; | |
95 | ||
96 | static char *ifname = "wlan%d"; | |
97 | module_param(ifname, charp, 0644); | |
98 | MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); | |
99 | ||
100 | static char *if2name = "wlan%d"; | |
101 | module_param(if2name, charp, 0644); | |
102 | MODULE_PARM_DESC(if2name, "The default name to allocate for second interface"); | |
103 | ||
22a1279b LC |
104 | /* temp mac address if users want to use instead of the mac address in Efuse */ |
105 | char *rtw_initmac; | |
5adef66a LF |
106 | |
107 | module_param(rtw_initmac, charp, 0644); | |
108 | module_param(rtw_channel_plan, int, 0644); | |
5adef66a | 109 | module_param(rtw_channel, int, 0644); |
5adef66a LF |
110 | module_param(rtw_wmm_enable, int, 0644); |
111 | module_param(rtw_vrtl_carrier_sense, int, 0644); | |
112 | module_param(rtw_vcs_type, int, 0644); | |
5adef66a LF |
113 | module_param(rtw_ht_enable, int, 0644); |
114 | module_param(rtw_cbw40_enable, int, 0644); | |
115 | module_param(rtw_ampdu_enable, int, 0644); | |
116 | module_param(rtw_rx_stbc, int, 0644); | |
117 | module_param(rtw_ampdu_amsdu, int, 0644); | |
5adef66a LF |
118 | module_param(rtw_power_mgnt, int, 0644); |
119 | module_param(rtw_smart_ps, int, 0644); | |
5adef66a LF |
120 | module_param(rtw_wifi_spec, int, 0644); |
121 | module_param(rtw_antdiv_cfg, int, 0644); | |
122 | module_param(rtw_antdiv_type, int, 0644); | |
123 | module_param(rtw_enusbss, int, 0644); | |
124 | module_param(rtw_hwpdn_mode, int, 0644); | |
5adef66a LF |
125 | |
126 | static uint rtw_max_roaming_times = 2; | |
127 | module_param(rtw_max_roaming_times, uint, 0644); | |
128 | MODULE_PARM_DESC(rtw_max_roaming_times, "The max roaming times to try"); | |
129 | ||
130 | static int rtw_fw_iol = 1;/* 0:Disable, 1:enable, 2:by usb speed */ | |
131 | module_param(rtw_fw_iol, int, 0644); | |
132 | MODULE_PARM_DESC(rtw_fw_iol, "FW IOL"); | |
133 | ||
134 | module_param(rtw_mc2u_disable, int, 0644); | |
135 | ||
136 | module_param(rtw_80211d, int, 0644); | |
137 | MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); | |
138 | ||
139 | static uint rtw_notch_filter = RTW_NOTCH_FILTER; | |
140 | module_param(rtw_notch_filter, uint, 0644); | |
141 | MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P"); | |
142 | module_param_named(debug, rtw_debug, int, 0444); | |
143 | MODULE_PARM_DESC(debug, "Set debug level (1-9) (default 1)"); | |
144 | ||
0a0796eb JS |
145 | static bool rtw_monitor_enable; |
146 | module_param_named(monitor_enable, rtw_monitor_enable, bool, 0444); | |
147 | MODULE_PARM_DESC(monitor_enable, "Enable monitor inferface (default: false)"); | |
148 | ||
8b9ffb43 LC |
149 | static int netdev_open(struct net_device *pnetdev); |
150 | static int netdev_close(struct net_device *pnetdev); | |
151 | ||
cfaf917e | 152 | static void loadparam(struct adapter *padapter, struct net_device *pnetdev) |
5adef66a | 153 | { |
5adef66a LF |
154 | struct registry_priv *registry_par = &padapter->registrypriv; |
155 | ||
5adef66a | 156 | GlobalDebugLevel = rtw_debug; |
5adef66a LF |
157 | |
158 | memcpy(registry_par->ssid.Ssid, "ANY", 3); | |
159 | registry_par->ssid.SsidLength = 3; | |
160 | ||
161 | registry_par->channel = (u8)rtw_channel; | |
162 | registry_par->wireless_mode = (u8)rtw_wireless_mode; | |
7be921a2 | 163 | registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense; |
5adef66a LF |
164 | registry_par->vcs_type = (u8)rtw_vcs_type; |
165 | registry_par->rts_thresh = (u16)rtw_rts_thresh; | |
166 | registry_par->frag_thresh = (u16)rtw_frag_thresh; | |
167 | registry_par->preamble = (u8)rtw_preamble; | |
5adef66a LF |
168 | registry_par->smart_ps = (u8)rtw_smart_ps; |
169 | registry_par->power_mgnt = (u8)rtw_power_mgnt; | |
170 | registry_par->ips_mode = (u8)rtw_ips_mode; | |
0cccd45f | 171 | registry_par->mp_mode = 0; |
5adef66a LF |
172 | registry_par->software_encrypt = (u8)rtw_software_encrypt; |
173 | registry_par->software_decrypt = (u8)rtw_software_decrypt; | |
174 | registry_par->acm_method = (u8)rtw_acm_method; | |
175 | ||
176 | /* UAPSD */ | |
177 | registry_par->wmm_enable = (u8)rtw_wmm_enable; | |
178 | registry_par->uapsd_enable = (u8)rtw_uapsd_enable; | |
5adef66a LF |
179 | |
180 | registry_par->ht_enable = (u8)rtw_ht_enable; | |
181 | registry_par->cbw40_enable = (u8)rtw_cbw40_enable; | |
182 | registry_par->ampdu_enable = (u8)rtw_ampdu_enable; | |
183 | registry_par->rx_stbc = (u8)rtw_rx_stbc; | |
184 | registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu; | |
5adef66a LF |
185 | registry_par->wifi_spec = (u8)rtw_wifi_spec; |
186 | registry_par->channel_plan = (u8)rtw_channel_plan; | |
d6c6ad96 | 187 | registry_par->accept_addba_req = true; |
5adef66a LF |
188 | registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg; |
189 | registry_par->antdiv_type = (u8)rtw_antdiv_type; | |
3446ef56 | 190 | registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode; |
5adef66a LF |
191 | |
192 | registry_par->max_roaming_times = (u8)rtw_max_roaming_times; | |
193 | ||
194 | registry_par->fw_iol = rtw_fw_iol; | |
195 | ||
196 | registry_par->enable80211d = (u8)rtw_80211d; | |
197 | snprintf(registry_par->ifname, 16, "%s", ifname); | |
198 | snprintf(registry_par->if2name, 16, "%s", if2name); | |
199 | registry_par->notch_filter = (u8)rtw_notch_filter; | |
0a0796eb | 200 | registry_par->monitor_enable = rtw_monitor_enable; |
5adef66a LF |
201 | } |
202 | ||
203 | static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) | |
204 | { | |
205 | struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); | |
206 | struct sockaddr *addr = p; | |
207 | ||
208 | if (!padapter->bup) | |
209 | memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN); | |
210 | ||
211 | return 0; | |
212 | } | |
213 | ||
214 | static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) | |
215 | { | |
216 | struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); | |
217 | struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); | |
218 | struct recv_priv *precvpriv = &(padapter->recvpriv); | |
219 | ||
4b248ab2 LC |
220 | padapter->stats.tx_packets = pxmitpriv->tx_pkts; |
221 | padapter->stats.rx_packets = precvpriv->rx_pkts; | |
5adef66a LF |
222 | padapter->stats.tx_dropped = pxmitpriv->tx_drop; |
223 | padapter->stats.rx_dropped = precvpriv->rx_drop; | |
224 | padapter->stats.tx_bytes = pxmitpriv->tx_bytes; | |
225 | padapter->stats.rx_bytes = precvpriv->rx_bytes; | |
226 | return &padapter->stats; | |
227 | } | |
228 | ||
229 | /* | |
230 | * AC to queue mapping | |
231 | * | |
232 | * AC_VO -> queue 0 | |
233 | * AC_VI -> queue 1 | |
234 | * AC_BE -> queue 2 | |
235 | * AC_BK -> queue 3 | |
236 | */ | |
237 | static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; | |
238 | ||
239 | /* Given a data frame determine the 802.1p/1d tag to use. */ | |
240 | static unsigned int rtw_classify8021d(struct sk_buff *skb) | |
241 | { | |
242 | unsigned int dscp; | |
243 | ||
244 | /* skb->priority values from 256->263 are magic values to | |
245 | * directly indicate a specific 802.1d priority. This is used | |
246 | * to allow 802.1d priority to be passed directly in from VLAN | |
247 | * tags, etc. | |
248 | */ | |
249 | if (skb->priority >= 256 && skb->priority <= 263) | |
250 | return skb->priority - 256; | |
251 | ||
252 | switch (skb->protocol) { | |
253 | case htons(ETH_P_IP): | |
254 | dscp = ip_hdr(skb)->tos & 0xfc; | |
255 | break; | |
256 | default: | |
257 | return 0; | |
258 | } | |
259 | ||
260 | return dscp >> 5; | |
261 | } | |
262 | ||
f663dd9a | 263 | static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, |
99932d4f | 264 | void *accel_priv, select_queue_fallback_t fallback) |
5adef66a LF |
265 | { |
266 | struct adapter *padapter = rtw_netdev_priv(dev); | |
267 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; | |
268 | ||
269 | skb->priority = rtw_classify8021d(skb); | |
270 | ||
271 | if (pmlmepriv->acm_mask != 0) | |
272 | skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority); | |
273 | ||
274 | return rtw_1d_to_queue[skb->priority]; | |
275 | } | |
276 | ||
277 | u16 rtw_recv_select_queue(struct sk_buff *skb) | |
278 | { | |
279 | struct iphdr *piphdr; | |
280 | unsigned int dscp; | |
281 | __be16 eth_type; | |
282 | u32 priority; | |
283 | u8 *pdata = skb->data; | |
284 | ||
285 | memcpy(ð_type, pdata+(ETH_ALEN<<1), 2); | |
286 | ||
287 | switch (eth_type) { | |
288 | case htons(ETH_P_IP): | |
289 | piphdr = (struct iphdr *)(pdata+ETH_HLEN); | |
290 | dscp = piphdr->tos & 0xfc; | |
291 | priority = dscp >> 5; | |
292 | break; | |
293 | default: | |
294 | priority = 0; | |
295 | } | |
296 | ||
297 | return rtw_1d_to_queue[priority]; | |
298 | } | |
299 | ||
300 | static const struct net_device_ops rtw_netdev_ops = { | |
301 | .ndo_open = netdev_open, | |
302 | .ndo_stop = netdev_close, | |
303 | .ndo_start_xmit = rtw_xmit_entry, | |
304 | .ndo_select_queue = rtw_select_queue, | |
305 | .ndo_set_mac_address = rtw_net_set_mac_address, | |
306 | .ndo_get_stats = rtw_net_get_stats, | |
307 | .ndo_do_ioctl = rtw_ioctl, | |
308 | }; | |
309 | ||
310 | int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) | |
311 | { | |
312 | if (dev_alloc_name(pnetdev, ifname) < 0) | |
313 | RT_TRACE(_module_os_intfs_c_, _drv_err_, ("dev_alloc_name, fail!\n")); | |
314 | ||
315 | netif_carrier_off(pnetdev); | |
316 | return 0; | |
317 | } | |
318 | ||
0d1206be LF |
319 | static const struct device_type wlan_type = { |
320 | .name = "wlan", | |
321 | }; | |
322 | ||
5adef66a LF |
323 | struct net_device *rtw_init_netdev(struct adapter *old_padapter) |
324 | { | |
325 | struct adapter *padapter; | |
0fb77787 | 326 | struct net_device *pnetdev = NULL; |
5adef66a LF |
327 | |
328 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+init_net_dev\n")); | |
329 | ||
330 | if (old_padapter != NULL) | |
f8a1a236 | 331 | pnetdev = rtw_alloc_etherdev_with_old_priv((void *)old_padapter); |
5adef66a LF |
332 | |
333 | if (!pnetdev) | |
334 | return NULL; | |
335 | ||
0d1206be | 336 | pnetdev->dev.type = &wlan_type; |
5adef66a LF |
337 | padapter = rtw_netdev_priv(pnetdev); |
338 | padapter->pnetdev = pnetdev; | |
339 | DBG_88E("register rtw_netdev_ops to netdev_ops\n"); | |
340 | pnetdev->netdev_ops = &rtw_netdev_ops; | |
341 | pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */ | |
342 | pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; | |
343 | ||
5adef66a LF |
344 | loadparam(padapter, pnetdev); |
345 | ||
346 | return pnetdev; | |
347 | } | |
348 | ||
7fc0406f | 349 | static int rtw_start_drv_threads(struct adapter *padapter) |
5adef66a | 350 | { |
7fc0406f | 351 | int err = 0; |
5adef66a LF |
352 | |
353 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_start_drv_threads\n")); | |
354 | ||
47145053 LC |
355 | padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, |
356 | "RTW_CMD_THREAD"); | |
5adef66a | 357 | if (IS_ERR(padapter->cmdThread)) |
7fc0406f | 358 | err = PTR_ERR(padapter->cmdThread); |
5adef66a | 359 | else |
22a1279b | 360 | /* wait for cmd_thread to run */ |
16677cca | 361 | wait_for_completion_interruptible(&padapter->cmdpriv.terminate_cmdthread_comp); |
5adef66a | 362 | |
7fc0406f | 363 | return err; |
5adef66a LF |
364 | } |
365 | ||
366 | void rtw_stop_drv_threads(struct adapter *padapter) | |
367 | { | |
368 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_stop_drv_threads\n")); | |
369 | ||
84b2f798 | 370 | /* Below is to terminate rtw_cmd_thread & event_thread... */ |
c84f5e28 | 371 | complete(&padapter->cmdpriv.cmd_queue_comp); |
5adef66a | 372 | if (padapter->cmdThread) |
16677cca | 373 | wait_for_completion_interruptible(&padapter->cmdpriv.terminate_cmdthread_comp); |
5adef66a | 374 | |
5adef66a LF |
375 | } |
376 | ||
377 | static u8 rtw_init_default_value(struct adapter *padapter) | |
378 | { | |
5adef66a LF |
379 | struct registry_priv *pregistrypriv = &padapter->registrypriv; |
380 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; | |
381 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; | |
382 | struct security_priv *psecuritypriv = &padapter->securitypriv; | |
383 | ||
384 | /* xmit_priv */ | |
385 | pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; | |
386 | pxmitpriv->vcs = pregistrypriv->vcs_type; | |
387 | pxmitpriv->vcs_type = pregistrypriv->vcs_type; | |
388 | pxmitpriv->frag_len = pregistrypriv->frag_thresh; | |
389 | ||
390 | /* mlme_priv */ | |
391 | pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ | |
392 | pmlmepriv->scan_mode = SCAN_ACTIVE; | |
393 | ||
394 | /* ht_priv */ | |
395 | pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */ | |
396 | ||
397 | /* security_priv */ | |
398 | psecuritypriv->binstallGrpkey = _FAIL; | |
399 | psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; | |
400 | psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; | |
2ff4e79f | 401 | psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; |
5adef66a LF |
402 | psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; |
403 | psecuritypriv->dot11PrivacyKeyIndex = 0; | |
404 | psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; | |
405 | psecuritypriv->dot118021XGrpKeyid = 1; | |
406 | psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; | |
407 | psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; | |
408 | ||
409 | /* registry_priv */ | |
410 | rtw_init_registrypriv_dev_network(padapter); | |
411 | rtw_update_registrypriv_dev_network(padapter); | |
412 | ||
413 | /* hal_priv */ | |
414 | rtw_hal_def_value_init(padapter); | |
415 | ||
416 | /* misc. */ | |
417 | padapter->bReadPortCancel = false; | |
418 | padapter->bWritePortCancel = false; | |
419 | padapter->bRxRSSIDisplay = 0; | |
c78a964c | 420 | return _SUCCESS; |
5adef66a LF |
421 | } |
422 | ||
423 | u8 rtw_reset_drv_sw(struct adapter *padapter) | |
424 | { | |
5adef66a LF |
425 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; |
426 | struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; | |
427 | ||
428 | /* hal_priv */ | |
429 | rtw_hal_def_value_init(padapter); | |
430 | padapter->bReadPortCancel = false; | |
431 | padapter->bWritePortCancel = false; | |
432 | padapter->bRxRSSIDisplay = 0; | |
433 | pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ | |
434 | ||
435 | padapter->xmitpriv.tx_pkts = 0; | |
436 | padapter->recvpriv.rx_pkts = 0; | |
437 | ||
438 | pmlmepriv->LinkDetectInfo.bBusyTraffic = false; | |
439 | ||
440 | _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING); | |
6c911834 | 441 | rtw_hal_sreset_init(padapter); |
5adef66a LF |
442 | pwrctrlpriv->pwr_state_check_cnts = 0; |
443 | ||
444 | /* mlmeextpriv */ | |
445 | padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE; | |
446 | ||
447 | rtw_set_signal_stat_timer(&padapter->recvpriv); | |
448 | ||
c78a964c | 449 | return _SUCCESS; |
5adef66a LF |
450 | } |
451 | ||
452 | u8 rtw_init_drv_sw(struct adapter *padapter) | |
453 | { | |
454 | u8 ret8 = _SUCCESS; | |
455 | ||
5adef66a LF |
456 | |
457 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_init_drv_sw\n")); | |
458 | ||
459 | if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { | |
460 | RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init cmd_priv\n")); | |
461 | ret8 = _FAIL; | |
462 | goto exit; | |
463 | } | |
464 | ||
465 | padapter->cmdpriv.padapter = padapter; | |
466 | ||
5adef66a LF |
467 | if (rtw_init_mlme_priv(padapter) == _FAIL) { |
468 | RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init mlme_priv\n")); | |
469 | ret8 = _FAIL; | |
470 | goto exit; | |
471 | } | |
472 | ||
5adef66a LF |
473 | if (init_mlme_ext_priv(padapter) == _FAIL) { |
474 | RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init mlme_ext_priv\n")); | |
475 | ret8 = _FAIL; | |
476 | goto exit; | |
477 | } | |
478 | ||
479 | if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { | |
480 | DBG_88E("Can't _rtw_init_xmit_priv\n"); | |
481 | ret8 = _FAIL; | |
482 | goto exit; | |
483 | } | |
484 | ||
485 | if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) { | |
486 | DBG_88E("Can't _rtw_init_recv_priv\n"); | |
487 | ret8 = _FAIL; | |
488 | goto exit; | |
489 | } | |
490 | ||
491 | if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) { | |
492 | DBG_88E("Can't _rtw_init_sta_priv\n"); | |
493 | ret8 = _FAIL; | |
494 | goto exit; | |
495 | } | |
496 | ||
497 | padapter->stapriv.padapter = padapter; | |
498 | ||
499 | rtw_init_bcmc_stainfo(padapter); | |
500 | ||
501 | rtw_init_pwrctrl_priv(padapter); | |
502 | ||
5adef66a LF |
503 | ret8 = rtw_init_default_value(padapter); |
504 | ||
505 | rtw_hal_dm_init(padapter); | |
506 | rtw_hal_sw_led_init(padapter); | |
507 | ||
508 | rtw_hal_sreset_init(padapter); | |
509 | ||
5adef66a LF |
510 | exit: |
511 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_init_drv_sw\n")); | |
512 | ||
5adef66a LF |
513 | |
514 | return ret8; | |
515 | } | |
516 | ||
517 | void rtw_cancel_all_timer(struct adapter *padapter) | |
518 | { | |
519 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_cancel_all_timer\n")); | |
520 | ||
c495fc9e | 521 | del_timer_sync(&padapter->mlmepriv.assoc_timer); |
5adef66a LF |
522 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel association timer complete!\n")); |
523 | ||
c495fc9e | 524 | del_timer_sync(&padapter->mlmepriv.scan_to_timer); |
5adef66a LF |
525 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel scan_to_timer!\n")); |
526 | ||
c495fc9e | 527 | del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer); |
5adef66a LF |
528 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel dynamic_chk_timer!\n")); |
529 | ||
530 | /* cancel sw led timer */ | |
531 | rtw_hal_sw_led_deinit(padapter); | |
532 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel DeInitSwLeds!\n")); | |
533 | ||
c495fc9e | 534 | del_timer_sync(&padapter->pwrctrlpriv.pwr_state_check_timer); |
5adef66a | 535 | |
c495fc9e | 536 | del_timer_sync(&padapter->recvpriv.signal_stat_timer); |
5adef66a LF |
537 | } |
538 | ||
539 | u8 rtw_free_drv_sw(struct adapter *padapter) | |
540 | { | |
541 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>rtw_free_drv_sw")); | |
542 | ||
5adef66a LF |
543 | free_mlme_ext_priv(&padapter->mlmeextpriv); |
544 | ||
5adef66a LF |
545 | rtw_free_mlme_priv(&padapter->mlmepriv); |
546 | _rtw_free_xmit_priv(&padapter->xmitpriv); | |
547 | ||
22a1279b LC |
548 | /* will free bcmc_stainfo here */ |
549 | _rtw_free_sta_priv(&padapter->stapriv); | |
5adef66a LF |
550 | |
551 | _rtw_free_recv_priv(&padapter->recvpriv); | |
552 | ||
5adef66a LF |
553 | rtw_hal_free_data(padapter); |
554 | ||
555 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== rtw_free_drv_sw\n")); | |
556 | ||
fc8b5ae9 | 557 | mutex_destroy(&padapter->hw_init_mutex); |
558 | ||
5adef66a LF |
559 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_free_drv_sw\n")); |
560 | ||
561 | return _SUCCESS; | |
562 | } | |
563 | ||
8b9ffb43 | 564 | static int _netdev_open(struct net_device *pnetdev) |
5adef66a LF |
565 | { |
566 | uint status; | |
7fc0406f | 567 | int err; |
5adef66a LF |
568 | struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); |
569 | struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; | |
570 | ||
571 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - dev_open\n")); | |
572 | DBG_88E("+88eu_drv - drv_open, bup =%d\n", padapter->bup); | |
573 | ||
574 | if (pwrctrlpriv->ps_flag) { | |
575 | padapter->net_closed = false; | |
576 | goto netdev_open_normal_process; | |
577 | } | |
578 | ||
579 | if (!padapter->bup) { | |
580 | padapter->bDriverStopped = false; | |
581 | padapter->bSurpriseRemoved = false; | |
5adef66a LF |
582 | |
583 | status = rtw_hal_init(padapter); | |
584 | if (status == _FAIL) { | |
585 | RT_TRACE(_module_os_intfs_c_, _drv_err_, ("rtl88eu_hal_init(): Can't init h/w!\n")); | |
586 | goto netdev_open_error; | |
587 | } | |
588 | ||
589 | pr_info("MAC Address = %pM\n", pnetdev->dev_addr); | |
590 | ||
7fc0406f LC |
591 | err = rtw_start_drv_threads(padapter); |
592 | if (err) { | |
5adef66a LF |
593 | pr_info("Initialize driver software resource Failed!\n"); |
594 | goto netdev_open_error; | |
595 | } | |
596 | ||
597 | if (init_hw_mlme_ext(padapter) == _FAIL) { | |
598 | pr_info("can't init mlme_ext_priv\n"); | |
599 | goto netdev_open_error; | |
600 | } | |
601 | if (padapter->intf_start) | |
602 | padapter->intf_start(padapter); | |
5adef66a LF |
603 | |
604 | rtw_led_control(padapter, LED_CTL_NO_LINK); | |
605 | ||
606 | padapter->bup = true; | |
607 | } | |
608 | padapter->net_closed = false; | |
609 | ||
4d4efe3e VT |
610 | mod_timer(&padapter->mlmepriv.dynamic_chk_timer, |
611 | jiffies + msecs_to_jiffies(2000)); | |
5adef66a LF |
612 | |
613 | padapter->pwrctrlpriv.bips_processing = false; | |
614 | rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); | |
615 | ||
616 | if (!rtw_netif_queue_stopped(pnetdev)) | |
77886973 | 617 | netif_tx_start_all_queues(pnetdev); |
5adef66a | 618 | else |
457c7b6a | 619 | netif_tx_wake_all_queues(pnetdev); |
5adef66a | 620 | |
5adef66a LF |
621 | netdev_open_normal_process: |
622 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - dev_open\n")); | |
623 | DBG_88E("-88eu_drv - drv_open, bup =%d\n", padapter->bup); | |
624 | return 0; | |
625 | ||
626 | netdev_open_error: | |
627 | padapter->bup = false; | |
628 | netif_carrier_off(pnetdev); | |
945c0972 | 629 | netif_tx_stop_all_queues(pnetdev); |
5adef66a LF |
630 | RT_TRACE(_module_os_intfs_c_, _drv_err_, ("-88eu_drv - dev_open, fail!\n")); |
631 | DBG_88E("-88eu_drv - drv_open fail, bup =%d\n", padapter->bup); | |
632 | return -1; | |
633 | } | |
634 | ||
8b9ffb43 | 635 | static int netdev_open(struct net_device *pnetdev) |
5adef66a LF |
636 | { |
637 | int ret; | |
638 | struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); | |
639 | ||
ac0a3667 AK |
640 | if (mutex_lock_interruptible(&padapter->hw_init_mutex)) |
641 | return -ERESTARTSYS; | |
5adef66a | 642 | ret = _netdev_open(pnetdev); |
fc8b5ae9 | 643 | mutex_unlock(&padapter->hw_init_mutex); |
5adef66a LF |
644 | return ret; |
645 | } | |
646 | ||
647 | static int ips_netdrv_open(struct adapter *padapter) | |
648 | { | |
649 | int status = _SUCCESS; | |
ede000f3 | 650 | |
5adef66a LF |
651 | padapter->net_closed = false; |
652 | DBG_88E("===> %s.........\n", __func__); | |
653 | ||
654 | padapter->bDriverStopped = false; | |
655 | padapter->bSurpriseRemoved = false; | |
5adef66a LF |
656 | |
657 | status = rtw_hal_init(padapter); | |
658 | if (status == _FAIL) { | |
659 | RT_TRACE(_module_os_intfs_c_, _drv_err_, ("ips_netdrv_open(): Can't init h/w!\n")); | |
660 | goto netdev_open_error; | |
661 | } | |
662 | ||
663 | if (padapter->intf_start) | |
664 | padapter->intf_start(padapter); | |
665 | ||
666 | rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); | |
4d4efe3e VT |
667 | mod_timer(&padapter->mlmepriv.dynamic_chk_timer, |
668 | jiffies + msecs_to_jiffies(5000)); | |
5adef66a LF |
669 | |
670 | return _SUCCESS; | |
671 | ||
672 | netdev_open_error: | |
673 | DBG_88E("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup); | |
674 | ||
675 | return _FAIL; | |
676 | } | |
677 | ||
678 | ||
679 | int rtw_ips_pwr_up(struct adapter *padapter) | |
680 | { | |
681 | int result; | |
ed737494 | 682 | unsigned long start_time = jiffies; |
ede000f3 | 683 | |
5adef66a LF |
684 | DBG_88E("===> rtw_ips_pwr_up..............\n"); |
685 | rtw_reset_drv_sw(padapter); | |
686 | ||
687 | result = ips_netdrv_open(padapter); | |
688 | ||
689 | rtw_led_control(padapter, LED_CTL_NO_LINK); | |
690 | ||
ed737494 RO |
691 | DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", |
692 | jiffies_to_msecs(jiffies - start_time)); | |
5adef66a LF |
693 | return result; |
694 | } | |
695 | ||
696 | void rtw_ips_pwr_down(struct adapter *padapter) | |
697 | { | |
ed737494 | 698 | unsigned long start_time = jiffies; |
ede000f3 | 699 | |
5adef66a LF |
700 | DBG_88E("===> rtw_ips_pwr_down...................\n"); |
701 | ||
5adef66a LF |
702 | padapter->net_closed = true; |
703 | ||
704 | rtw_led_control(padapter, LED_CTL_POWER_OFF); | |
705 | ||
706 | rtw_ips_dev_unload(padapter); | |
ed737494 RO |
707 | DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", |
708 | jiffies_to_msecs(jiffies - start_time)); | |
5adef66a LF |
709 | } |
710 | ||
711 | void rtw_ips_dev_unload(struct adapter *padapter) | |
712 | { | |
713 | DBG_88E("====> %s...\n", __func__); | |
714 | ||
715 | rtw_hal_set_hwreg(padapter, HW_VAR_FIFO_CLEARN_UP, NULL); | |
716 | ||
717 | if (padapter->intf_stop) | |
718 | padapter->intf_stop(padapter); | |
719 | ||
720 | /* s5. */ | |
721 | if (!padapter->bSurpriseRemoved) | |
722 | rtw_hal_deinit(padapter); | |
723 | } | |
724 | ||
725 | int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) | |
726 | { | |
727 | int status; | |
728 | ||
729 | if (bnormal) | |
730 | status = netdev_open(pnetdev); | |
731 | else | |
732 | status = (_SUCCESS == ips_netdrv_open((struct adapter *)rtw_netdev_priv(pnetdev))) ? (0) : (-1); | |
733 | return status; | |
734 | } | |
735 | ||
8b9ffb43 | 736 | static int netdev_close(struct net_device *pnetdev) |
5adef66a LF |
737 | { |
738 | struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); | |
739 | ||
740 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - drv_close\n")); | |
741 | ||
742 | if (padapter->pwrctrlpriv.bInternalAutoSuspend) { | |
743 | if (padapter->pwrctrlpriv.rf_pwrstate == rf_off) | |
744 | padapter->pwrctrlpriv.ps_flag = true; | |
745 | } | |
746 | padapter->net_closed = true; | |
747 | ||
748 | if (padapter->pwrctrlpriv.rf_pwrstate == rf_on) { | |
749 | DBG_88E("(2)88eu_drv - drv_close, bup =%d, hw_init_completed =%d\n", | |
750 | padapter->bup, padapter->hw_init_completed); | |
751 | ||
752 | /* s1. */ | |
753 | if (pnetdev) { | |
754 | if (!rtw_netif_queue_stopped(pnetdev)) | |
945c0972 | 755 | netif_tx_stop_all_queues(pnetdev); |
5adef66a LF |
756 | } |
757 | ||
758 | /* s2. */ | |
759 | LeaveAllPowerSaveMode(padapter); | |
760 | rtw_disassoc_cmd(padapter, 500, false); | |
761 | /* s2-2. indicate disconnect to os */ | |
762 | rtw_indicate_disconnect(padapter); | |
763 | /* s2-3. */ | |
b4ba3b57 | 764 | rtw_free_assoc_resources(padapter); |
5adef66a LF |
765 | /* s2-4. */ |
766 | rtw_free_network_queue(padapter, true); | |
767 | /* Close LED */ | |
768 | rtw_led_control(padapter, LED_CTL_POWER_OFF); | |
769 | } | |
770 | ||
5adef66a LF |
771 | RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - drv_close\n")); |
772 | DBG_88E("-88eu_drv - drv_close, bup =%d\n", padapter->bup); | |
773 | return 0; | |
774 | } |