add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8192du / os_dep / linux / mlme_linux.c
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  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20
21
22 #define _MLME_OSDEP_C_
23
24 #include <drv_conf.h>
25 #include <osdep_service.h>
26 #include <drv_types.h>
27 #include <mlme_osdep.h>
28
29
30 #ifdef RTK_DMP_PLATFORM
31 void Linkup_workitem_callback(struct work_struct *work)
32 {
33         struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkup_workitem);
34         _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
35
36 _func_enter_;
37
38         RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkup_workitem_callback\n"));
39
40 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
41         kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKUP);
42 #else
43         kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKUP);
44 #endif
45
46 _func_exit_;
47 }
48
49 void Linkdown_workitem_callback(struct work_struct *work)
50 {
51         struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkdown_workitem);
52         _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
53
54 _func_enter_;
55
56         RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkdown_workitem_callback\n"));
57
58 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
59         kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKDOWN);
60 #else
61         kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKDOWN);
62 #endif
63
64 _func_exit_;
65 }
66 #endif
67
68
69 /*
70 void sitesurvey_ctrl_handler(void *FunctionContext)
71 {
72         _adapter *adapter = (_adapter *)FunctionContext;
73
74         _sitesurvey_ctrl_handler(adapter);
75
76         _set_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, 3000);
77 }
78 */
79
80 void rtw_join_timeout_handler (void *FunctionContext)
81 {
82         _adapter *adapter = (_adapter *)FunctionContext;
83         _rtw_join_timeout_handler(adapter);
84 }
85
86
87 void _rtw_scan_timeout_handler (void *FunctionContext)
88 {
89         _adapter *adapter = (_adapter *)FunctionContext;
90         rtw_scan_timeout_handler(adapter);
91 }
92
93
94 void _dynamic_check_timer_handlder (void *FunctionContext)
95 {
96         _adapter *adapter = (_adapter *)FunctionContext;
97                  
98         rtw_dynamic_check_timer_handlder(adapter);
99         
100         _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000);
101 }
102
103 #ifdef CONFIG_SET_SCAN_DENY_TIMER
104 void _rtw_set_scan_deny_timer_hdl(void *FunctionContext)
105 {
106         _adapter *adapter = (_adapter *)FunctionContext;         
107         rtw_set_scan_deny_timer_hdl(adapter);
108 }
109 #endif
110
111
112 void rtw_init_mlme_timer(_adapter *padapter)
113 {
114         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
115
116         _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, rtw_join_timeout_handler, padapter);
117         //_init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer), padapter->pnetdev, sitesurvey_ctrl_handler, padapter);
118         _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, _rtw_scan_timeout_handler, padapter);
119
120         _init_timer(&(pmlmepriv->dynamic_chk_timer), padapter->pnetdev, _dynamic_check_timer_handlder, padapter);
121
122         #ifdef CONFIG_SET_SCAN_DENY_TIMER
123         _init_timer(&(pmlmepriv->set_scan_deny_timer), padapter->pnetdev, _rtw_set_scan_deny_timer_hdl, padapter);
124         #endif
125
126 #ifdef RTK_DMP_PLATFORM
127         _init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter);
128         _init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter);
129 #endif
130
131 }
132
133 extern void rtw_indicate_wx_assoc_event(_adapter *padapter);
134 extern void rtw_indicate_wx_disassoc_event(_adapter *padapter);
135
136 void rtw_os_indicate_connect(_adapter *adapter)
137 {
138
139 _func_enter_;   
140
141 #ifdef CONFIG_IOCTL_CFG80211
142         rtw_cfg80211_indicate_connect(adapter);
143 #endif //CONFIG_IOCTL_CFG80211
144
145         rtw_indicate_wx_assoc_event(adapter);
146         netif_carrier_on(adapter->pnetdev);
147
148         if(adapter->pid[2] !=0)
149                 rtw_signal_process(adapter->pid[2], SIGALRM);
150
151 #ifdef RTK_DMP_PLATFORM
152         _set_workitem(&adapter->mlmepriv.Linkup_workitem);
153 #endif
154
155 _func_exit_;    
156
157 }
158
159 extern void indicate_wx_scan_complete_event(_adapter *padapter);
160 void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted)
161 {
162 #ifdef CONFIG_IOCTL_CFG80211
163         rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), aborted);
164 #endif
165         indicate_wx_scan_complete_event(padapter);
166 }
167
168 static RT_PMKID_LIST   backupPMKIDList[ NUM_PMKID_CACHE ];
169 void rtw_reset_securitypriv( _adapter *adapter )
170 {
171         u8      backupPMKIDIndex = 0;
172         u8      backupTKIPCountermeasure = 0x00;
173         u32     backupTKIPcountermeasure_time = 0;
174         // add for CONFIG_IEEE80211W, none 11w also can use
175         _irqL irqL;
176         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
177         
178         _enter_critical_bh(&adapter->security_key_mutex, &irqL);
179         
180         if(adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)//802.1x
181         {                
182                 // Added by Albert 2009/02/18
183                 // We have to backup the PMK information for WiFi PMK Caching test item.
184                 //
185                 // Backup the btkip_countermeasure information.
186                 // When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds.
187
188                 _rtw_memset( &backupPMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
189
190                 _rtw_memcpy( &backupPMKIDList[ 0 ], &adapter->securitypriv.PMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
191                 backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
192                 backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure;
193                 backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time;                
194 #ifdef CONFIG_IEEE80211W
195                 //reset RX BIP packet number
196                 pmlmeext->mgnt_80211w_IPN_rx = 0;
197 #endif //CONFIG_IEEE80211W
198                 _rtw_memset((unsigned char *)&adapter->securitypriv, 0, sizeof (struct security_priv));
199                 //_init_timer(&(adapter->securitypriv.tkip_timer),adapter->pnetdev, rtw_use_tkipkey_handler, adapter);
200
201                 // Added by Albert 2009/02/18
202                 // Restore the PMK information to securitypriv structure for the following connection.
203                 _rtw_memcpy( &adapter->securitypriv.PMKIDList[ 0 ], &backupPMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
204                 adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
205                 adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure;
206                 adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time;                
207
208                 adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
209                 adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
210
211         }
212         else //reset values in securitypriv 
213         {
214                 //if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE)
215                 //{
216                 struct security_priv *psec_priv=&adapter->securitypriv;
217
218                 psec_priv->dot11AuthAlgrthm =dot11AuthAlgrthm_Open;  //open system
219                 psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
220                 psec_priv->dot11PrivacyKeyIndex = 0;
221
222                 psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_;
223                 psec_priv->dot118021XGrpKeyid = 1;
224
225                 psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
226                 psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
227                 //}
228         }
229         // add for CONFIG_IEEE80211W, none 11w also can use
230         _exit_critical_bh(&adapter->security_key_mutex, &irqL);
231 }
232
233 void rtw_os_indicate_disconnect( _adapter *adapter )
234 {
235    //RT_PMKID_LIST   backupPMKIDList[ NUM_PMKID_CACHE ];
236   
237 _func_enter_;
238
239         netif_carrier_off(adapter->pnetdev); // Do it first for tx broadcast pkt after disconnection issue!
240
241 #ifdef CONFIG_IOCTL_CFG80211
242         rtw_cfg80211_indicate_disconnect(adapter);      
243 #endif //CONFIG_IOCTL_CFG80211
244
245         rtw_indicate_wx_disassoc_event(adapter);        
246
247 #ifdef RTK_DMP_PLATFORM
248         _set_workitem(&adapter->mlmepriv.Linkdown_workitem);
249 #endif
250          //modify for CONFIG_IEEE80211W, none 11w also can use the same command
251          rtw_reset_securitypriv_cmd(adapter);
252
253 _func_exit_;
254
255 }
256
257 void rtw_report_sec_ie(_adapter *adapter,u8 authmode,u8 *sec_ie)
258 {
259         uint    len;
260         u8      *buff,*p,i;
261         union iwreq_data wrqu;
262
263 _func_enter_;
264
265         RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+rtw_report_sec_ie, authmode=%d\n", authmode));
266
267         buff = NULL;
268         if(authmode==_WPA_IE_ID_)
269         {
270                 RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("rtw_report_sec_ie, authmode=%d\n", authmode));
271                 
272                 buff = rtw_malloc(IW_CUSTOM_MAX);
273                 
274                 _rtw_memset(buff,0,IW_CUSTOM_MAX);
275                 
276                 p=buff;
277                 
278                 p+=sprintf(p,"ASSOCINFO(ReqIEs=");
279
280                 len = sec_ie[1]+2;
281                 len =  (len < IW_CUSTOM_MAX) ? len:IW_CUSTOM_MAX;
282                         
283                 for(i=0;i<len;i++){
284                         p+=sprintf(p,"%02x",sec_ie[i]);
285                 }
286
287                 p+=sprintf(p,")");
288                 
289                 _rtw_memset(&wrqu,0,sizeof(wrqu));
290                 
291                 wrqu.data.length=p-buff;
292                 
293                 wrqu.data.length = (wrqu.data.length<IW_CUSTOM_MAX) ? wrqu.data.length:IW_CUSTOM_MAX;
294                 
295                 wireless_send_event(adapter->pnetdev,IWEVCUSTOM,&wrqu,buff);
296
297                 if(buff)
298                     rtw_mfree(buff, IW_CUSTOM_MAX);
299                 
300         }
301
302 _func_exit_;
303
304 }
305
306 void _survey_timer_hdl (void *FunctionContext)
307 {
308         _adapter *padapter = (_adapter *)FunctionContext;
309         
310         survey_timer_hdl(padapter);
311 }
312
313 void _link_timer_hdl (void *FunctionContext)
314 {
315         _adapter *padapter = (_adapter *)FunctionContext;
316         link_timer_hdl(padapter);
317 }
318
319 void _addba_timer_hdl(void *FunctionContext)
320 {
321         struct sta_info *psta = (struct sta_info *)FunctionContext;
322         addba_timer_hdl(psta);
323 }
324
325 #ifdef CONFIG_IEEE80211W
326 void _sa_query_timer_hdl (void *FunctionContext)
327 {
328         _adapter *padapter = (_adapter *)FunctionContext;
329         sa_query_timer_hdl(padapter);
330 }
331 #endif //CONFIG_IEEE80211W
332
333 void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta)
334 {
335
336         _init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta);
337 }
338
339 /*
340 void _reauth_timer_hdl(void *FunctionContext)
341 {
342         _adapter *padapter = (_adapter *)FunctionContext;
343         reauth_timer_hdl(padapter);
344 }
345
346 void _reassoc_timer_hdl(void *FunctionContext)
347 {
348         _adapter *padapter = (_adapter *)FunctionContext;
349         reassoc_timer_hdl(padapter);
350 }
351 */
352
353 void init_mlme_ext_timer(_adapter *padapter)
354 {       
355         struct  mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
356
357         _init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter);
358         _init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter);
359 #ifdef CONFIG_IEEE80211W
360         _init_timer(&pmlmeext->sa_query_timer, padapter->pnetdev, _sa_query_timer_hdl, padapter);
361 #endif //CONFIG_IEEE80211W
362         //_init_timer(&pmlmeext->ADDBA_timer, padapter->pnetdev, _addba_timer_hdl, padapter);
363
364         //_init_timer(&pmlmeext->reauth_timer, padapter->pnetdev, _reauth_timer_hdl, padapter);
365         //_init_timer(&pmlmeext->reassoc_timer, padapter->pnetdev, _reassoc_timer_hdl, padapter);
366 }
367
368 #ifdef CONFIG_AP_MODE
369
370 void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta)
371 {
372         union iwreq_data wrqu;
373         struct sta_priv *pstapriv = &padapter->stapriv;
374
375         if(psta==NULL)
376                 return;
377
378         if(psta->aid > NUM_STA)
379                 return;
380
381         if(pstapriv->sta_aid[psta->aid - 1] != psta)
382                 return;
383         
384         
385         wrqu.addr.sa_family = ARPHRD_ETHER;     
386         
387         _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
388
389         DBG_871X("+rtw_indicate_sta_assoc_event\n");
390         
391         wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL);
392
393 }
394
395 void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta)
396 {
397         union iwreq_data wrqu;
398         struct sta_priv *pstapriv = &padapter->stapriv;
399
400         if(psta==NULL)
401                 return;
402
403         if(psta->aid > NUM_STA)
404                 return;
405
406         if(pstapriv->sta_aid[psta->aid - 1] != psta)
407                 return;
408         
409         
410         wrqu.addr.sa_family = ARPHRD_ETHER;     
411         
412         _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
413
414         DBG_871X("+rtw_indicate_sta_disassoc_event\n");
415         
416         wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL);
417         
418 }
419
420
421 #ifdef CONFIG_HOSTAPD_MLME
422
423 static int mgnt_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev)
424 {
425         struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
426         _adapter *padapter = (_adapter *)phostapdpriv->padapter;
427
428         //DBG_871X("%s\n", __FUNCTION__);
429
430         return rtw_hal_hostap_mgnt_xmit_entry(padapter, skb);
431 }
432
433 static int mgnt_netdev_open(struct net_device *pnetdev)
434 {
435         struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
436
437         DBG_871X("mgnt_netdev_open: MAC Address:" MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr));
438
439
440         init_usb_anchor(&phostapdpriv->anchored);
441         
442         if(!rtw_netif_queue_stopped(pnetdev))
443                 rtw_netif_start_queue(pnetdev);
444         else
445                 rtw_netif_wake_queue(pnetdev);
446
447
448         netif_carrier_on(pnetdev);
449                 
450         //rtw_write16(phostapdpriv->padapter, 0x0116, 0x0100);//only excluding beacon 
451                 
452         return 0;       
453 }
454 static int mgnt_netdev_close(struct net_device *pnetdev)
455 {
456         struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
457
458         DBG_871X("%s\n", __FUNCTION__);
459
460         usb_kill_anchored_urbs(&phostapdpriv->anchored);
461
462         netif_carrier_off(pnetdev);
463
464         if (!rtw_netif_queue_stopped(pnetdev))
465                 rtw_netif_stop_queue(pnetdev);
466         
467         //rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f);
468         
469         return 0;       
470 }
471
472 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
473 static const struct net_device_ops rtl871x_mgnt_netdev_ops = {
474         .ndo_open = mgnt_netdev_open,
475        .ndo_stop = mgnt_netdev_close,
476        .ndo_start_xmit = mgnt_xmit_entry,
477        //.ndo_set_mac_address = r871x_net_set_mac_address,
478        //.ndo_get_stats = r871x_net_get_stats,
479        //.ndo_do_ioctl = r871x_mp_ioctl,
480 };
481 #endif
482
483 int hostapd_mode_init(_adapter *padapter)
484 {
485         unsigned char mac[ETH_ALEN];
486         struct hostapd_priv *phostapdpriv;
487         struct net_device *pnetdev;
488         
489         pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv));      
490         if (!pnetdev)
491            return -ENOMEM;
492
493         //SET_MODULE_OWNER(pnetdev);
494        ether_setup(pnetdev);
495
496         //pnetdev->type = ARPHRD_IEEE80211;
497         
498         phostapdpriv = rtw_netdev_priv(pnetdev);
499         phostapdpriv->pmgnt_netdev = pnetdev;
500         phostapdpriv->padapter= padapter;
501         padapter->phostapdpriv = phostapdpriv;
502         
503         //pnetdev->init = NULL;
504         
505 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
506
507         DBG_871X("register rtl871x_mgnt_netdev_ops to netdev_ops\n");
508
509         pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops;
510         
511 #else
512
513         pnetdev->open = mgnt_netdev_open;
514
515         pnetdev->stop = mgnt_netdev_close;      
516         
517         pnetdev->hard_start_xmit = mgnt_xmit_entry;
518         
519         //pnetdev->set_mac_address = r871x_net_set_mac_address;
520         
521         //pnetdev->get_stats = r871x_net_get_stats;
522
523         //pnetdev->do_ioctl = r871x_mp_ioctl;
524         
525 #endif
526
527         pnetdev->watchdog_timeo = HZ; /* 1 second timeout */    
528
529         //pnetdev->wireless_handlers = NULL;
530
531 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
532         pnetdev->features |= NETIF_F_IP_CSUM;
533 #endif  
534
535         
536         
537         if(dev_alloc_name(pnetdev,"mgnt.wlan%d") < 0)
538         {
539                 DBG_871X("hostapd_mode_init(): dev_alloc_name, fail! \n");              
540         }
541
542
543         //SET_NETDEV_DEV(pnetdev, pintfpriv->udev);
544
545
546         mac[0]=0x00;
547         mac[1]=0xe0;
548         mac[2]=0x4c;
549         mac[3]=0x87;
550         mac[4]=0x11;
551         mac[5]=0x12;
552                                 
553         _rtw_memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
554         
555
556         netif_carrier_off(pnetdev);
557
558
559         /* Tell the network stack we exist */
560         if (register_netdev(pnetdev) != 0)
561         {
562                 DBG_871X("hostapd_mode_init(): register_netdev fail!\n");
563                 
564                 if(pnetdev)
565                 {        
566                         rtw_free_netdev(pnetdev);
567                 }
568         }
569         
570         return 0;
571         
572 }
573
574 void hostapd_mode_unload(_adapter *padapter)
575 {
576         struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
577         struct net_device *pnetdev = phostapdpriv->pmgnt_netdev;
578
579         unregister_netdev(pnetdev);
580         rtw_free_netdev(pnetdev);
581         
582 }
583
584 #endif
585 #endif
586