GNU Linux-libre 4.19.314-gnu1
[releases.git] / drivers / staging / rtl8723bs / os_dep / sdio_intf.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _HCI_INTF_C_
8
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include <linux/jiffies.h>
12
13 #ifndef dev_to_sdio_func
14 #define dev_to_sdio_func(d)     container_of(d, struct sdio_func, dev)
15 #endif
16
17 static const struct sdio_device_id sdio_ids[] =
18 {
19         { SDIO_DEVICE(0x024c, 0x0523), },
20         { SDIO_DEVICE(0x024c, 0x0525), },
21         { SDIO_DEVICE(0x024c, 0x0623), },
22         { SDIO_DEVICE(0x024c, 0x0626), },
23         { SDIO_DEVICE(0x024c, 0x0627), },
24         { SDIO_DEVICE(0x024c, 0xb723), },
25         { /* end: all zeroes */                         },
26 };
27 MODULE_DEVICE_TABLE(sdio, sdio_ids);
28
29 static int rtw_drv_init(struct sdio_func *func, const struct sdio_device_id *id);
30 static void rtw_dev_remove(struct sdio_func *func);
31 static int rtw_sdio_resume(struct device *dev);
32 static int rtw_sdio_suspend(struct device *dev);
33
34 static const struct dev_pm_ops rtw_sdio_pm_ops = {
35         .suspend        = rtw_sdio_suspend,
36         .resume = rtw_sdio_resume,
37 };
38
39 struct sdio_drv_priv {
40         struct sdio_driver r871xs_drv;
41         int drv_registered;
42 };
43
44 static struct sdio_drv_priv sdio_drvpriv = {
45         .r871xs_drv.probe = rtw_drv_init,
46         .r871xs_drv.remove = rtw_dev_remove,
47         .r871xs_drv.name = "rtl8723bs",
48         .r871xs_drv.id_table = sdio_ids,
49         .r871xs_drv.drv = {
50                 .pm = &rtw_sdio_pm_ops,
51         }
52 };
53
54 static void sd_sync_int_hdl(struct sdio_func *func)
55 {
56         struct dvobj_priv *psdpriv;
57
58
59         psdpriv = sdio_get_drvdata(func);
60
61         if (!psdpriv->if1) {
62                 DBG_871X("%s if1 == NULL\n", __func__);
63                 return;
64         }
65
66         rtw_sdio_set_irq_thd(psdpriv, current);
67         sd_int_hdl(psdpriv->if1);
68         rtw_sdio_set_irq_thd(psdpriv, NULL);
69 }
70
71 static int sdio_alloc_irq(struct dvobj_priv *dvobj)
72 {
73         PSDIO_DATA psdio_data;
74         struct sdio_func *func;
75         int err;
76
77         psdio_data = &dvobj->intf_data;
78         func = psdio_data->func;
79
80         sdio_claim_host(func);
81
82         err = sdio_claim_irq(func, &sd_sync_int_hdl);
83         if (err)
84         {
85                 dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++;
86                 printk(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err);
87         }
88         else
89         {
90                 dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++;
91                 dvobj->irq_alloc = 1;
92         }
93
94         sdio_release_host(func);
95
96         return err?_FAIL:_SUCCESS;
97 }
98
99 static void sdio_free_irq(struct dvobj_priv *dvobj)
100 {
101     PSDIO_DATA psdio_data;
102     struct sdio_func *func;
103     int err;
104
105     if (dvobj->irq_alloc) {
106         psdio_data = &dvobj->intf_data;
107         func = psdio_data->func;
108
109         if (func) {
110             sdio_claim_host(func);
111             err = sdio_release_irq(func);
112             if (err)
113             {
114                                 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
115                                 DBG_871X_LEVEL(_drv_err_,"%s: sdio_release_irq FAIL(%d)!\n", __func__, err);
116             }
117             else
118                 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
119             sdio_release_host(func);
120         }
121         dvobj->irq_alloc = 0;
122     }
123 }
124
125 #ifdef CONFIG_GPIO_WAKEUP
126 extern unsigned int oob_irq;
127 static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data)
128 {
129         struct adapter *padapter = data;
130         DBG_871X_LEVEL(_drv_always_, "gpio_hostwakeup_irq_thread\n");
131         /* Disable interrupt before calling handler */
132         /* disable_irq_nosync(oob_irq); */
133         rtw_lock_suspend_timeout(HZ/2);
134         return IRQ_HANDLED;
135 }
136
137 static u8 gpio_hostwakeup_alloc_irq(struct adapter *padapter)
138 {
139         int err;
140         if (oob_irq == 0) {
141                 DBG_871X("oob_irq ZERO!\n");
142                 return _FAIL;
143         }
144         /* dont set it IRQF_TRIGGER_LOW, or wowlan */
145         /* power is high after suspend */
146         /* and failing can prevent can not sleep issue if */
147         /* wifi gpio12 pin is not linked with CPU */
148         err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL,
149                 /* IRQF_TRIGGER_LOW | IRQF_ONESHOT, */
150                 IRQF_TRIGGER_FALLING,
151                 "rtw_wifi_gpio_wakeup", padapter);
152         if (err < 0) {
153                 DBG_871X("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err);
154                 return false;
155         } else {
156                 DBG_871X("allocate gpio irq %d ok\n", oob_irq);
157         }
158
159         enable_irq_wake(oob_irq);
160         return _SUCCESS;
161 }
162
163 static void gpio_hostwakeup_free_irq(struct adapter *padapter)
164 {
165         if (oob_irq == 0)
166                 return;
167
168         disable_irq_wake(oob_irq);
169         free_irq(oob_irq, padapter);
170 }
171 #endif
172
173 static u32 sdio_init(struct dvobj_priv *dvobj)
174 {
175         PSDIO_DATA psdio_data;
176         struct sdio_func *func;
177         int err;
178
179         psdio_data = &dvobj->intf_data;
180         func = psdio_data->func;
181
182         /* 3 1. init SDIO bus */
183         sdio_claim_host(func);
184
185         err = sdio_enable_func(func);
186         if (err) {
187                 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
188                 DBG_8192C(KERN_CRIT "%s: sdio_enable_func FAIL(%d)!\n", __func__, err);
189                 goto release;
190         }
191
192         err = sdio_set_block_size(func, 512);
193         if (err) {
194                 dvobj->drv_dbg.dbg_sdio_init_error_cnt++;
195                 DBG_8192C(KERN_CRIT "%s: sdio_set_block_size FAIL(%d)!\n", __func__, err);
196                 goto release;
197         }
198         psdio_data->block_transfer_len = 512;
199         psdio_data->tx_block_mode = 1;
200         psdio_data->rx_block_mode = 1;
201
202 release:
203         sdio_release_host(func);
204
205         if (err)
206                 return _FAIL;
207         return _SUCCESS;
208 }
209
210 static void sdio_deinit(struct dvobj_priv *dvobj)
211 {
212         struct sdio_func *func;
213         int err;
214
215
216         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_deinit\n"));
217
218         func = dvobj->intf_data.func;
219
220         if (func) {
221                 sdio_claim_host(func);
222                 err = sdio_disable_func(func);
223                 if (err)
224                 {
225                         dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++;
226                         DBG_8192C(KERN_ERR "%s: sdio_disable_func(%d)\n", __func__, err);
227                 }
228
229                 if (dvobj->irq_alloc) {
230                         err = sdio_release_irq(func);
231                         if (err)
232                         {
233                                 dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++;
234                                 DBG_8192C(KERN_ERR "%s: sdio_release_irq(%d)\n", __func__, err);
235                         }
236                         else
237                                 dvobj->drv_dbg.dbg_sdio_free_irq_cnt++;
238                 }
239
240                 sdio_release_host(func);
241         }
242 }
243 static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func)
244 {
245         int status = _FAIL;
246         struct dvobj_priv *dvobj = NULL;
247         PSDIO_DATA psdio;
248
249         dvobj = devobj_init();
250         if (dvobj == NULL) {
251                 goto exit;
252         }
253
254         sdio_set_drvdata(func, dvobj);
255
256         psdio = &dvobj->intf_data;
257         psdio->func = func;
258
259         if (sdio_init(dvobj) != _SUCCESS) {
260                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!\n", __func__));
261                 goto free_dvobj;
262         }
263         rtw_reset_continual_io_error(dvobj);
264         status = _SUCCESS;
265
266 free_dvobj:
267         if (status != _SUCCESS && dvobj) {
268                 sdio_set_drvdata(func, NULL);
269
270                 devobj_deinit(dvobj);
271
272                 dvobj = NULL;
273         }
274 exit:
275         return dvobj;
276 }
277
278 static void sdio_dvobj_deinit(struct sdio_func *func)
279 {
280         struct dvobj_priv *dvobj = sdio_get_drvdata(func);
281
282         sdio_set_drvdata(func, NULL);
283         if (dvobj) {
284                 sdio_deinit(dvobj);
285                 devobj_deinit(dvobj);
286         }
287         return;
288 }
289
290 void rtw_set_hal_ops(struct adapter *padapter)
291 {
292         /* alloc memory for HAL DATA */
293         rtw_hal_data_init(padapter);
294
295         rtl8723bs_set_hal_ops(padapter);
296 }
297
298 static void sd_intf_start(struct adapter *padapter)
299 {
300         if (padapter == NULL) {
301                 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
302                 return;
303         }
304
305         /*  hal dep */
306         rtw_hal_enable_interrupt(padapter);
307 }
308
309 static void sd_intf_stop(struct adapter *padapter)
310 {
311         if (padapter == NULL) {
312                 DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__);
313                 return;
314         }
315
316         /*  hal dep */
317         rtw_hal_disable_interrupt(padapter);
318 }
319
320
321 static struct adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj, const struct sdio_device_id  *pdid)
322 {
323         int status = _FAIL;
324         struct net_device *pnetdev;
325         struct adapter *padapter = NULL;
326         PSDIO_DATA psdio = &dvobj->intf_data;
327
328         padapter = vzalloc(sizeof(*padapter));
329         if (padapter == NULL) {
330                 goto exit;
331         }
332
333         padapter->dvobj = dvobj;
334         dvobj->if1 = padapter;
335
336         padapter->bDriverStopped =true;
337
338         dvobj->padapters = padapter;
339         padapter->iface_id = 0;
340
341         /* 3 1. init network device data */
342         pnetdev = rtw_init_netdev(padapter);
343         if (!pnetdev)
344                 goto free_adapter;
345
346         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
347
348         padapter = rtw_netdev_priv(pnetdev);
349
350         rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj));
351
352         /* 3 3. init driver special setting, interface, OS and hardware relative */
353
354         /* 4 3.1 set hardware operation functions */
355         rtw_set_hal_ops(padapter);
356
357
358         /* 3 5. initialize Chip version */
359         padapter->intf_start = &sd_intf_start;
360         padapter->intf_stop = &sd_intf_stop;
361
362         padapter->intf_init = &sdio_init;
363         padapter->intf_deinit = &sdio_deinit;
364         padapter->intf_alloc_irq = &sdio_alloc_irq;
365         padapter->intf_free_irq = &sdio_free_irq;
366
367         if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL)
368         {
369                 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
370                         ("rtw_drv_init: Can't init io_priv\n"));
371                 goto free_hal_data;
372         }
373
374         rtw_hal_read_chip_version(padapter);
375
376         rtw_hal_chip_configure(padapter);
377
378         rtw_btcoex_Initialize(padapter);
379
380         /* 3 6. read efuse/eeprom data */
381         rtw_hal_read_chip_info(padapter);
382
383         /* 3 7. init driver common data */
384         if (rtw_init_drv_sw(padapter) == _FAIL) {
385                 RT_TRACE(_module_hci_intfs_c_, _drv_err_,
386                          ("rtw_drv_init: Initialize driver software resource Failed!\n"));
387                 goto free_hal_data;
388         }
389
390         /* 3 8. get WLan MAC address */
391         /*  set mac addr */
392         rtw_macaddr_cfg(&psdio->func->dev, padapter->eeprompriv.mac_addr);
393
394         rtw_hal_disable_interrupt(padapter);
395
396         DBG_871X("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n"
397                 , padapter->bDriverStopped
398                 , padapter->bSurpriseRemoved
399                 , padapter->bup
400                 , padapter->hw_init_completed
401         );
402
403         status = _SUCCESS;
404
405 free_hal_data:
406         if (status != _SUCCESS && padapter->HalData)
407                 kfree(padapter->HalData);
408
409         if (status != _SUCCESS) {
410                 rtw_wdev_unregister(padapter->rtw_wdev);
411                 rtw_wdev_free(padapter->rtw_wdev);
412         }
413
414 free_adapter:
415         if (status != _SUCCESS) {
416                 if (pnetdev)
417                         rtw_free_netdev(pnetdev);
418                 else
419                         vfree((u8 *)padapter);
420                 padapter = NULL;
421         }
422 exit:
423         return padapter;
424 }
425
426 static void rtw_sdio_if1_deinit(struct adapter *if1)
427 {
428         struct net_device *pnetdev = if1->pnetdev;
429         struct mlme_priv *pmlmepriv = &if1->mlmepriv;
430
431         if (check_fwstate(pmlmepriv, _FW_LINKED))
432                 rtw_disassoc_cmd(if1, 0, false);
433
434         free_mlme_ap_info(if1);
435
436 #ifdef CONFIG_GPIO_WAKEUP
437         gpio_hostwakeup_free_irq(if1);
438 #endif
439
440         rtw_cancel_all_timer(if1);
441
442 #ifdef CONFIG_WOWLAN
443         adapter_to_pwrctl(if1)->wowlan_mode =false;
444         DBG_871X_LEVEL(_drv_always_, "%s wowlan_mode:%d\n", __func__, adapter_to_pwrctl(if1)->wowlan_mode);
445 #endif /* CONFIG_WOWLAN */
446
447         rtw_dev_unload(if1);
448         DBG_871X("+r871xu_dev_remove, hw_init_completed =%d\n", if1->hw_init_completed);
449
450         if (if1->rtw_wdev) {
451                 rtw_wdev_free(if1->rtw_wdev);
452         }
453
454         rtw_free_drv_sw(if1);
455
456         if (pnetdev)
457                 rtw_free_netdev(pnetdev);
458 }
459
460 /*
461  * drv_init() - a device potentially for us
462  *
463  * notes: drv_init() is called when the bus driver has located a card for us to support.
464  *        We accept the new device by returning 0.
465  */
466 static int rtw_drv_init(
467         struct sdio_func *func,
468         const struct sdio_device_id *id)
469 {
470         int status = _FAIL;
471         struct adapter *if1 = NULL, *if2 = NULL;
472         struct dvobj_priv *dvobj;
473
474         dvobj = sdio_dvobj_init(func);
475         if (dvobj == NULL) {
476                 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n"));
477                 goto exit;
478         }
479
480         if1 = rtw_sdio_if1_init(dvobj, id);
481         if (if1 == NULL) {
482                 DBG_871X("rtw_init_primarystruct adapter Failed!\n");
483                 goto free_dvobj;
484         }
485
486         /* dev_alloc_name && register_netdev */
487         status = rtw_drv_register_netdev(if1);
488         if (status != _SUCCESS) {
489                 goto free_if2;
490         }
491
492         if (sdio_alloc_irq(dvobj) != _SUCCESS)
493                 goto free_if2;
494
495 #ifdef  CONFIG_GPIO_WAKEUP
496         gpio_hostwakeup_alloc_irq(if1);
497 #endif
498
499         RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-871x_drv - drv_init, success!\n"));
500
501         rtw_ndev_notifier_register();
502         status = _SUCCESS;
503
504 free_if2:
505         if (status != _SUCCESS && if2) {
506         }
507         if (status != _SUCCESS && if1) {
508                 rtw_sdio_if1_deinit(if1);
509         }
510 free_dvobj:
511         if (status != _SUCCESS)
512                 sdio_dvobj_deinit(func);
513 exit:
514         return status == _SUCCESS?0:-ENODEV;
515 }
516
517 static void rtw_dev_remove(struct sdio_func *func)
518 {
519         struct dvobj_priv *dvobj = sdio_get_drvdata(func);
520         struct adapter *padapter = dvobj->if1;
521
522         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+rtw_dev_remove\n"));
523
524         dvobj->processing_dev_remove = true;
525
526         rtw_unregister_netdevs(dvobj);
527
528         if (padapter->bSurpriseRemoved == false) {
529                 int err;
530
531                 /* test surprise remove */
532                 sdio_claim_host(func);
533                 sdio_readb(func, 0, &err);
534                 sdio_release_host(func);
535                 if (err == -ENOMEDIUM) {
536                         padapter->bSurpriseRemoved = true;
537                         DBG_871X(KERN_NOTICE "%s: device had been removed!\n", __func__);
538                 }
539         }
540
541         rtw_ps_deny(padapter, PS_DENY_DRV_REMOVE);
542
543         rtw_pm_set_ips(padapter, IPS_NONE);
544         rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
545
546         LeaveAllPowerSaveMode(padapter);
547
548         rtw_btcoex_HaltNotify(padapter);
549
550         rtw_sdio_if1_deinit(padapter);
551
552         sdio_dvobj_deinit(func);
553
554         RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-rtw_dev_remove\n"));
555 }
556
557 extern int pm_netdev_open(struct net_device *pnetdev, u8 bnormal);
558 extern int pm_netdev_close(struct net_device *pnetdev, u8 bnormal);
559
560 static int rtw_sdio_suspend(struct device *dev)
561 {
562         struct sdio_func *func =dev_to_sdio_func(dev);
563         struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
564         struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv);
565         struct adapter *padapter = psdpriv->if1;
566         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
567
568         if (padapter->bDriverStopped == true)
569         {
570                 DBG_871X("%s bDriverStopped = %d\n", __func__, padapter->bDriverStopped);
571                 return 0;
572         }
573
574         if (pwrpriv->bInSuspend == true)
575         {
576                 DBG_871X("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend);
577                 pdbgpriv->dbg_suspend_error_cnt++;
578                 return 0;
579         }
580
581         return rtw_suspend_common(padapter);
582 }
583
584 static int rtw_resume_process(struct adapter *padapter)
585 {
586         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
587         struct dvobj_priv *psdpriv = padapter->dvobj;
588         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
589
590         if (pwrpriv->bInSuspend == false)
591         {
592                 pdbgpriv->dbg_resume_error_cnt++;
593                 DBG_871X("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend);
594                 return -1;
595         }
596
597         return rtw_resume_common(padapter);
598 }
599
600 static int rtw_sdio_resume(struct device *dev)
601 {
602         struct sdio_func *func =dev_to_sdio_func(dev);
603         struct dvobj_priv *psdpriv = sdio_get_drvdata(func);
604         struct adapter *padapter = psdpriv->if1;
605         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
606         int ret = 0;
607         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
608
609         DBG_871X("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
610
611         pdbgpriv->dbg_resume_cnt++;
612
613         ret = rtw_resume_process(padapter);
614
615         pmlmeext->last_scan_time = jiffies;
616         DBG_871X("<========  %s return %d\n", __func__, ret);
617         return ret;
618 }
619
620 static int __init rtw_drv_entry(void)
621 {
622         int ret = 0;
623
624         DBG_871X_LEVEL(_drv_always_, "module init start\n");
625         dump_drv_version(RTW_DBGDUMP);
626 #ifdef BTCOEXVERSION
627         DBG_871X_LEVEL(_drv_always_, "rtl8723bs BT-Coex version = %s\n", BTCOEXVERSION);
628 #endif /*  BTCOEXVERSION */
629
630         sdio_drvpriv.drv_registered = true;
631         rtw_drv_proc_init();
632
633         ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv);
634         if (ret != 0)
635         {
636                 sdio_drvpriv.drv_registered = false;
637                 rtw_drv_proc_deinit();
638                 rtw_ndev_notifier_unregister();
639                 DBG_871X("%s: register driver failed!!(%d)\n", __func__, ret);
640                 goto exit;
641         }
642
643         goto exit;
644
645 exit:
646         DBG_871X_LEVEL(_drv_always_, "module init ret =%d\n", ret);
647         return ret;
648 }
649
650 static void __exit rtw_drv_halt(void)
651 {
652         DBG_871X_LEVEL(_drv_always_, "module exit start\n");
653
654         sdio_drvpriv.drv_registered = false;
655
656         sdio_unregister_driver(&sdio_drvpriv.r871xs_drv);
657
658         rtw_drv_proc_deinit();
659         rtw_ndev_notifier_unregister();
660
661         DBG_871X_LEVEL(_drv_always_, "module exit success\n");
662
663         rtw_mstat_dump(RTW_DBGDUMP);
664 }
665
666
667 module_init(rtw_drv_entry);
668 module_exit(rtw_drv_halt);