1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
21 #include <linux/module.h>
22 #include <linux/netdevice.h>
24 #include <rtw_android.h>
25 #include <osdep_service.h>
26 #include <rtw_debug.h>
27 #include <ioctl_cfg80211.h>
28 #include <rtw_ioctl_set.h>
30 #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)
31 #include <linux/platform_device.h>
32 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
33 #include <linux/wlan_plat.h>
35 #include <linux/wifi_tiwlan.h>
37 #endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */
39 const char *android_wifi_cmd_str
[ANDROID_WIFI_CMD_MAX
] = {
81 #define PNO_TLV_PREFIX 'S'
82 #define PNO_TLV_VERSION '1'
83 #define PNO_TLV_SUBVERSION '2'
84 #define PNO_TLV_RESERVED '0'
85 #define PNO_TLV_TYPE_SSID_IE 'S'
86 #define PNO_TLV_TYPE_TIME 'T'
87 #define PNO_TLV_FREQ_REPEAT 'R'
88 #define PNO_TLV_FREQ_EXPO_MAX 'M'
90 typedef struct cmd_tlv
{
96 #endif /* PNO_SUPPORT */
98 typedef struct android_wifi_priv_cmd
{
108 } android_wifi_priv_cmd
;
111 * Local (static) functions and variables
114 /* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
115 * time (only) in dhd_open, subsequential wifi on will be handled by
118 static int g_wifi_on
= _TRUE
;
122 static int wl_android_set_pno_setup(struct net_device
*dev
, char *command
, int total_len
)
124 wlc_ssid_t ssids_local
[MAX_PFN_LIST_COUNT
];
127 cmd_tlv_t
*cmd_tlv_temp
;
132 int pno_freq_expo_max
= 0;
136 char pno_in_example
[] = {
137 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
141 'd', 'l', 'i', 'n', 'k',
153 #endif /* PNO_SET_DEBUG */
155 DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__
, command
, total_len
));
157 if (total_len
< (strlen(CMD_PNOSETUP_SET
) + sizeof(cmd_tlv_t
))) {
158 DBG_871X("%s argument=%d less min size\n", __FUNCTION__
, total_len
);
163 memcpy(command
, pno_in_example
, sizeof(pno_in_example
));
164 for (i
= 0; i
< sizeof(pno_in_example
); i
++)
165 printf("%02X ", command
[i
]);
167 total_len
= sizeof(pno_in_example
);
170 str_ptr
= command
+ strlen(CMD_PNOSETUP_SET
);
171 tlv_size_left
= total_len
- strlen(CMD_PNOSETUP_SET
);
173 cmd_tlv_temp
= (cmd_tlv_t
*)str_ptr
;
174 memset(ssids_local
, 0, sizeof(ssids_local
));
176 if ((cmd_tlv_temp
->prefix
== PNO_TLV_PREFIX
) &&
177 (cmd_tlv_temp
->version
== PNO_TLV_VERSION
) &&
178 (cmd_tlv_temp
->subver
== PNO_TLV_SUBVERSION
)) {
180 str_ptr
+= sizeof(cmd_tlv_t
);
181 tlv_size_left
-= sizeof(cmd_tlv_t
);
183 if ((nssid
= wl_iw_parse_ssid_list_tlv(&str_ptr
, ssids_local
,
184 MAX_PFN_LIST_COUNT
, &tlv_size_left
)) <= 0) {
185 DBG_871X("SSID is not presented or corrupted ret=%d\n", nssid
);
188 if ((str_ptr
[0] != PNO_TLV_TYPE_TIME
) || (tlv_size_left
<= 1)) {
189 DBG_871X("%s scan duration corrupted field size %d\n",
190 __FUNCTION__
, tlv_size_left
);
194 pno_time
= simple_strtoul(str_ptr
, &str_ptr
, 16);
195 DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__
, pno_time
));
197 if (str_ptr
[0] != 0) {
198 if ((str_ptr
[0] != PNO_TLV_FREQ_REPEAT
)) {
199 DBG_871X("%s pno repeat : corrupted field\n",
204 pno_repeat
= simple_strtoul(str_ptr
, &str_ptr
, 16);
205 DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__
, pno_repeat
));
206 if (str_ptr
[0] != PNO_TLV_FREQ_EXPO_MAX
) {
207 DBG_871X("%s FREQ_EXPO_MAX corrupted field size\n",
212 pno_freq_expo_max
= simple_strtoul(str_ptr
, &str_ptr
, 16);
213 DHD_INFO(("%s: pno_freq_expo_max=%d\n",
214 __FUNCTION__
, pno_freq_expo_max
));
218 DBG_871X("%s get wrong TLV command\n", __FUNCTION__
);
222 res
= dhd_dev_pno_set(dev
, ssids_local
, nssid
, pno_time
, pno_repeat
, pno_freq_expo_max
);
227 #endif /* PNO_SUPPORT */
229 int rtw_android_cmdstr_to_num(char *cmdstr
)
232 for(cmd_num
=0 ; cmd_num
<ANDROID_WIFI_CMD_MAX
; cmd_num
++)
233 if(0 == strncasecmp(cmdstr
, android_wifi_cmd_str
[cmd_num
], strlen(android_wifi_cmd_str
[cmd_num
])) )
239 int rtw_android_get_rssi(struct net_device
*net
, char *command
, int total_len
)
241 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(net
);
242 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
243 struct wlan_network
*pcur_network
= &pmlmepriv
->cur_network
;
244 int bytes_written
= 0;
246 if(check_fwstate(pmlmepriv
, _FW_LINKED
) == _TRUE
) {
247 bytes_written
+= snprintf(&command
[bytes_written
], total_len
, "%s rssi %d",
248 pcur_network
->network
.Ssid
.Ssid
, padapter
->recvpriv
.rssi
);
251 return bytes_written
;
254 int rtw_android_get_link_speed(struct net_device
*net
, char *command
, int total_len
)
256 _adapter
*padapter
= (_adapter
*)rtw_netdev_priv(net
);
257 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
258 struct wlan_network
*pcur_network
= &pmlmepriv
->cur_network
;
259 int bytes_written
= 0;
262 link_speed
= rtw_get_cur_max_rate(padapter
)/10;
263 bytes_written
= snprintf(command
, total_len
, "LinkSpeed %d", link_speed
);
265 return bytes_written
;
268 int rtw_android_get_macaddr(struct net_device
*net
, char *command
, int total_len
)
270 _adapter
*adapter
= (_adapter
*)rtw_netdev_priv(net
);
271 int bytes_written
= 0;
273 bytes_written
= snprintf(command
, total_len
, "Macaddr = "MAC_FMT
, MAC_ARG(net
->dev_addr
));
274 return bytes_written
;
277 int rtw_android_set_country(struct net_device
*net
, char *command
, int total_len
)
279 _adapter
*adapter
= (_adapter
*)rtw_netdev_priv(net
);
280 char *country_code
= command
+ strlen(android_wifi_cmd_str
[ANDROID_WIFI_CMD_COUNTRY
]) + 1;
283 ret
= rtw_set_country(adapter
, country_code
);
285 return (ret
==_SUCCESS
)?0:-1;
288 int rtw_android_get_p2p_dev_addr(struct net_device
*net
, char *command
, int total_len
)
290 int bytes_written
= 0;
292 //We use the same address as our HW MAC address
293 _rtw_memcpy(command
, net
->dev_addr
, ETH_ALEN
);
295 bytes_written
= ETH_ALEN
;
296 return bytes_written
;
299 int rtw_android_set_block(struct net_device
*net
, char *command
, int total_len
)
301 _adapter
*adapter
= (_adapter
*)rtw_netdev_priv(net
);
302 char *block_value
= command
+ strlen(android_wifi_cmd_str
[ANDROID_WIFI_CMD_BLOCK
]) + 1;
304 #ifdef CONFIG_IOCTL_CFG80211
305 wdev_to_priv(adapter
->rtw_wdev
)->block
= (*block_value
=='0')?_FALSE
:_TRUE
;
311 int rtw_android_setband(struct net_device
*net
, char *command
, int total_len
)
313 _adapter
*adapter
= (_adapter
*)rtw_netdev_priv(net
);
314 char *arg
= command
+ strlen(android_wifi_cmd_str
[ANDROID_WIFI_CMD_SETBAND
]) + 1;
318 sscanf(arg
, "%u", &band
);
319 ret
= rtw_set_band(adapter
, band
);
321 return (ret
==_SUCCESS
)?0:-1;
324 int rtw_android_getband(struct net_device
*net
, char *command
, int total_len
)
326 _adapter
*adapter
= (_adapter
*)rtw_netdev_priv(net
);
327 int bytes_written
= 0;
329 bytes_written
= snprintf(command
, total_len
, "%u", adapter
->setband
);
331 return bytes_written
;
334 int get_int_from_command( char* pcmd
)
338 for( i
= 0; i
< strlen( pcmd
); i
++ )
340 if ( pcmd
[ i
] == '=' )
342 // Skip the '=' and space characters.
347 return ( rtw_atoi( pcmd
+ i
) );
350 int rtw_android_priv_cmd(struct net_device
*net
, struct ifreq
*ifr
, int cmd
)
353 char *command
= NULL
;
355 int bytes_written
= 0;
356 android_wifi_priv_cmd priv_cmd
;
360 if (!ifr
->ifr_data
) {
364 if (copy_from_user(&priv_cmd
, ifr
->ifr_data
, sizeof(android_wifi_priv_cmd
))) {
369 command
= rtw_zmalloc(priv_cmd
.total_len
);
372 DBG_871X("%s: failed to allocate memory\n", __FUNCTION__
);
377 if (!access_ok(VERIFY_READ
, priv_cmd
.buf
, priv_cmd
.total_len
)){
378 DBG_871X("%s: failed to access memory\n", __FUNCTION__
);
382 if (copy_from_user(command
, (void *)priv_cmd
.buf
, priv_cmd
.total_len
)) {
387 DBG_871X("%s: Android private cmd \"%s\" on %s\n"
388 , __FUNCTION__
, command
, ifr
->ifr_name
);
390 cmd_num
= rtw_android_cmdstr_to_num(command
);
393 case ANDROID_WIFI_CMD_START
:
394 //bytes_written = wl_android_wifi_on(net);
396 case ANDROID_WIFI_CMD_SETFWPATH
:
401 DBG_871X("%s: Ignore private cmd \"%s\" - iface %s is down\n"
402 ,__FUNCTION__
, command
, ifr
->ifr_name
);
409 case ANDROID_WIFI_CMD_STOP
:
410 //bytes_written = wl_android_wifi_off(net);
413 case ANDROID_WIFI_CMD_SCAN_ACTIVE
:
414 //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_ACTIVE);
415 #ifdef CONFIG_PLATFORM_MSTAR
416 #ifdef CONFIG_IOCTL_CFG80211
417 (wdev_to_priv(net
->ieee80211_ptr
))->bandroid_scan
= _TRUE
;
418 #endif //CONFIG_IOCTL_CFG80211
419 #endif //CONFIG_PLATFORM_MSTAR
421 case ANDROID_WIFI_CMD_SCAN_PASSIVE
:
422 //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_PASSIVE);
425 case ANDROID_WIFI_CMD_RSSI
:
426 bytes_written
= rtw_android_get_rssi(net
, command
, priv_cmd
.total_len
);
428 case ANDROID_WIFI_CMD_LINKSPEED
:
429 bytes_written
= rtw_android_get_link_speed(net
, command
, priv_cmd
.total_len
);
432 case ANDROID_WIFI_CMD_MACADDR
:
433 bytes_written
= rtw_android_get_macaddr(net
, command
, priv_cmd
.total_len
);
436 case ANDROID_WIFI_CMD_BLOCK
:
437 bytes_written
= rtw_android_set_block(net
, command
, priv_cmd
.total_len
);
440 case ANDROID_WIFI_CMD_RXFILTER_START
:
441 //bytes_written = net_os_set_packet_filter(net, 1);
443 case ANDROID_WIFI_CMD_RXFILTER_STOP
:
444 //bytes_written = net_os_set_packet_filter(net, 0);
446 case ANDROID_WIFI_CMD_RXFILTER_ADD
:
447 //int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0';
448 //bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num);
450 case ANDROID_WIFI_CMD_RXFILTER_REMOVE
:
451 //int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0';
452 //bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num);
455 case ANDROID_WIFI_CMD_BTCOEXSCAN_START
:
456 /* TBD: BTCOEXSCAN-START */
458 case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP
:
459 /* TBD: BTCOEXSCAN-STOP */
461 case ANDROID_WIFI_CMD_BTCOEXMODE
:
463 uint mode
= *(command
+ strlen(CMD_BTCOEXMODE
) + 1) - '0';
465 net_os_set_packet_filter(net
, 0); /* DHCP starts */
467 net_os_set_packet_filter(net
, 1); /* DHCP ends */
469 bytes_written
= wl_cfg80211_set_btcoex_dhcp(net
, command
);
474 case ANDROID_WIFI_CMD_SETSUSPENDOPT
:
475 //bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len);
478 case ANDROID_WIFI_CMD_SETBAND
:
479 bytes_written
= rtw_android_setband(net
, command
, priv_cmd
.total_len
);
482 case ANDROID_WIFI_CMD_GETBAND
:
483 bytes_written
= rtw_android_getband(net
, command
, priv_cmd
.total_len
);
486 case ANDROID_WIFI_CMD_COUNTRY
:
487 bytes_written
= rtw_android_set_country(net
, command
, priv_cmd
.total_len
);
491 case ANDROID_WIFI_CMD_PNOSSIDCLR_SET
:
492 //bytes_written = dhd_dev_pno_reset(net);
494 case ANDROID_WIFI_CMD_PNOSETUP_SET
:
495 //bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len);
497 case ANDROID_WIFI_CMD_PNOENABLE_SET
:
498 //uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0';
499 //bytes_written = dhd_dev_pno_enable(net, pfn_enabled);
503 case ANDROID_WIFI_CMD_P2P_DEV_ADDR
:
504 bytes_written
= rtw_android_get_p2p_dev_addr(net
, command
, priv_cmd
.total_len
);
506 case ANDROID_WIFI_CMD_P2P_SET_NOA
:
507 //int skip = strlen(CMD_P2P_SET_NOA) + 1;
508 //bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip);
510 case ANDROID_WIFI_CMD_P2P_GET_NOA
:
511 //bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len);
513 case ANDROID_WIFI_CMD_P2P_SET_PS
:
514 //int skip = strlen(CMD_P2P_SET_PS) + 1;
515 //bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, priv_cmd.total_len - skip);
518 #ifdef CONFIG_IOCTL_CFG80211
519 case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE
:
521 int skip
= strlen(android_wifi_cmd_str
[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE
]) + 3;
522 bytes_written
= rtw_cfg80211_set_mgnt_wpsp2pie(net
, command
+ skip
, priv_cmd
.total_len
- skip
, *(command
+ skip
- 2) - '0');
525 #endif //CONFIG_IOCTL_CFG80211
528 case ANDROID_WIFI_CMD_WFD_ENABLE
:
530 // Commented by Albert 2012/07/24
531 // We can enable the WFD function by using the following command:
532 // wpa_cli driver wfd-enable
534 struct wifi_display_info
*pwfd_info
;
535 _adapter
* padapter
= ( _adapter
* ) rtw_netdev_priv(net
);
537 pwfd_info
= &padapter
->wfd_info
;
538 if( padapter
->wdinfo
.driver_interface
== DRIVER_CFG80211
)
539 pwfd_info
->wfd_enable
= _TRUE
;
543 case ANDROID_WIFI_CMD_WFD_DISABLE
:
545 // Commented by Albert 2012/07/24
546 // We can disable the WFD function by using the following command:
547 // wpa_cli driver wfd-disable
549 struct wifi_display_info
*pwfd_info
;
550 _adapter
* padapter
= ( _adapter
* ) rtw_netdev_priv(net
);
552 pwfd_info
= &padapter
->wfd_info
;
553 if( padapter
->wdinfo
.driver_interface
== DRIVER_CFG80211
)
554 pwfd_info
->wfd_enable
= _FALSE
;
557 case ANDROID_WIFI_CMD_WFD_SET_TCPPORT
:
559 // Commented by Albert 2012/07/24
560 // We can set the tcp port number by using the following command:
561 // wpa_cli driver wfd-set-tcpport = 554
563 struct wifi_display_info
*pwfd_info
;
564 _adapter
* padapter
= ( _adapter
* ) rtw_netdev_priv(net
);
566 pwfd_info
= &padapter
->wfd_info
;
567 if( padapter
->wdinfo
.driver_interface
== DRIVER_CFG80211
)
568 pwfd_info
->rtsp_ctrlport
= ( u16
) get_int_from_command( priv_cmd
.buf
);
571 case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT
:
577 case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE
:
579 // Commented by Albert 2012/08/28
580 // Specify the WFD device type ( WFD source/primary sink )
582 struct wifi_display_info
*pwfd_info
;
583 _adapter
* padapter
= ( _adapter
* ) rtw_netdev_priv(net
);
585 pwfd_info
= &padapter
->wfd_info
;
586 if( padapter
->wdinfo
.driver_interface
== DRIVER_CFG80211
)
588 pwfd_info
->wfd_device_type
= ( u8
) get_int_from_command( priv_cmd
.buf
);
590 pwfd_info
->wfd_device_type
&= WFD_DEVINFO_DUAL
;
596 DBG_871X("Unknown PRIVATE command %s - ignored\n", command
);
597 snprintf(command
, 3, "OK");
598 bytes_written
= strlen("OK");
602 if (bytes_written
>= 0) {
603 if ((bytes_written
== 0) && (priv_cmd
.total_len
> 0))
605 if (bytes_written
>= priv_cmd
.total_len
) {
606 DBG_871X("%s: bytes_written = %d\n", __FUNCTION__
, bytes_written
);
607 bytes_written
= priv_cmd
.total_len
;
611 priv_cmd
.used_len
= bytes_written
;
612 if (copy_to_user((void *)priv_cmd
.buf
, command
, bytes_written
)) {
613 DBG_871X("%s: failed to copy data to user buffer\n", __FUNCTION__
);
622 rtw_unlock_suspend();
624 rtw_mfree(command
, priv_cmd
.total_len
);
632 * Functions for Android WiFi card detection
634 #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)
636 static int g_wifidev_registered
= 0;
637 static struct semaphore wifi_control_sem
;
638 static struct wifi_platform_data
*wifi_control_data
= NULL
;
639 static struct resource
*wifi_irqres
= NULL
;
641 static int wifi_add_dev(void);
642 static void wifi_del_dev(void);
644 int rtw_android_wifictrl_func_add(void)
647 sema_init(&wifi_control_sem
, 0);
649 ret
= wifi_add_dev();
651 DBG_871X("%s: platform_driver_register failed\n", __FUNCTION__
);
654 g_wifidev_registered
= 1;
656 /* Waiting callback after platform_driver_register is done or exit with error */
657 if (down_timeout(&wifi_control_sem
, msecs_to_jiffies(1000)) != 0) {
659 DBG_871X("%s: platform_driver_register timeout\n", __FUNCTION__
);
665 void rtw_android_wifictrl_func_del(void)
667 if (g_wifidev_registered
)
670 g_wifidev_registered
= 0;
674 void *wl_android_prealloc(int section
, unsigned long size
)
676 void *alloc_ptr
= NULL
;
677 if (wifi_control_data
&& wifi_control_data
->mem_prealloc
) {
678 alloc_ptr
= wifi_control_data
->mem_prealloc(section
, size
);
680 DBG_871X("success alloc section %d\n", section
);
682 memset(alloc_ptr
, 0, size
);
687 DBG_871X("can't alloc section %d\n", section
);
691 int wifi_get_irq_number(unsigned long *irq_flags_ptr
)
694 *irq_flags_ptr
= wifi_irqres
->flags
& IRQF_TRIGGER_MASK
;
695 return (int)wifi_irqres
->start
;
697 #ifdef CUSTOM_OOB_GPIO_NUM
698 return CUSTOM_OOB_GPIO_NUM
;
704 int wifi_set_power(int on
, unsigned long msec
)
706 DBG_871X("%s = %d\n", __FUNCTION__
, on
);
707 if (wifi_control_data
&& wifi_control_data
->set_power
) {
708 wifi_control_data
->set_power(on
);
715 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
716 int wifi_get_mac_addr(unsigned char *buf
)
718 DBG_871X("%s\n", __FUNCTION__
);
721 if (wifi_control_data
&& wifi_control_data
->get_mac_addr
) {
722 return wifi_control_data
->get_mac_addr(buf
);
726 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */
728 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) || defined(COMPAT_KERNEL_RELEASE)
729 void *wifi_get_country_code(char *ccode
)
731 DBG_871X("%s\n", __FUNCTION__
);
734 if (wifi_control_data
&& wifi_control_data
->get_country_code
) {
735 return wifi_control_data
->get_country_code(ccode
);
739 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */
741 static int wifi_set_carddetect(int on
)
743 DBG_871X("%s = %d\n", __FUNCTION__
, on
);
744 if (wifi_control_data
&& wifi_control_data
->set_carddetect
) {
745 wifi_control_data
->set_carddetect(on
);
750 static int wifi_probe(struct platform_device
*pdev
)
752 struct wifi_platform_data
*wifi_ctrl
=
753 (struct wifi_platform_data
*)(pdev
->dev
.platform_data
);
755 DBG_871X("## %s\n", __FUNCTION__
);
756 wifi_irqres
= platform_get_resource_byname(pdev
, IORESOURCE_IRQ
, "bcmdhd_wlan_irq");
757 if (wifi_irqres
== NULL
)
758 wifi_irqres
= platform_get_resource_byname(pdev
,
759 IORESOURCE_IRQ
, "bcm4329_wlan_irq");
760 wifi_control_data
= wifi_ctrl
;
762 wifi_set_power(1, 0); /* Power On */
763 wifi_set_carddetect(1); /* CardDetect (0->1) */
765 up(&wifi_control_sem
);
769 static int wifi_remove(struct platform_device
*pdev
)
771 struct wifi_platform_data
*wifi_ctrl
=
772 (struct wifi_platform_data
*)(pdev
->dev
.platform_data
);
774 DBG_871X("## %s\n", __FUNCTION__
);
775 wifi_control_data
= wifi_ctrl
;
777 wifi_set_power(0, 0); /* Power Off */
778 wifi_set_carddetect(0); /* CardDetect (1->0) */
780 up(&wifi_control_sem
);
784 static int wifi_suspend(struct platform_device
*pdev
, pm_message_t state
)
786 DBG_871X("##> %s\n", __FUNCTION__
);
787 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
788 bcmsdh_oob_intr_set(0);
793 static int wifi_resume(struct platform_device
*pdev
)
795 DBG_871X("##> %s\n", __FUNCTION__
);
796 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
797 if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
798 bcmsdh_oob_intr_set(1);
803 /* temporarily use these two */
804 static struct platform_driver wifi_device
= {
806 .remove
= wifi_remove
,
807 .suspend
= wifi_suspend
,
808 .resume
= wifi_resume
,
810 .name
= "bcmdhd_wlan",
814 static struct platform_driver wifi_device_legacy
= {
816 .remove
= wifi_remove
,
817 .suspend
= wifi_suspend
,
818 .resume
= wifi_resume
,
820 .name
= "bcm4329_wlan",
824 static int wifi_add_dev(void)
826 DBG_871X("## Calling platform_driver_register\n");
827 platform_driver_register(&wifi_device
);
828 platform_driver_register(&wifi_device_legacy
);
832 static void wifi_del_dev(void)
834 DBG_871X("## Unregister platform_driver_register\n");
835 platform_driver_unregister(&wifi_device
);
836 platform_driver_unregister(&wifi_device_legacy
);
838 #endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */