1554c0a3aSHans de Goede /****************************************************************************** 2554c0a3aSHans de Goede * 3554c0a3aSHans de Goede * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 4554c0a3aSHans de Goede * 5554c0a3aSHans de Goede * This program is free software; you can redistribute it and/or modify it 6554c0a3aSHans de Goede * under the terms of version 2 of the GNU General Public License as 7554c0a3aSHans de Goede * published by the Free Software Foundation. 8554c0a3aSHans de Goede * 9554c0a3aSHans de Goede * This program is distributed in the hope that it will be useful, but WITHOUT 10554c0a3aSHans de Goede * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11554c0a3aSHans de Goede * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12554c0a3aSHans de Goede * more details. 13554c0a3aSHans de Goede * 14554c0a3aSHans de Goede ******************************************************************************/ 15554c0a3aSHans de Goede #define _OS_INTFS_C_ 16554c0a3aSHans de Goede 17554c0a3aSHans de Goede #include <drv_types.h> 18554c0a3aSHans de Goede #include <rtw_debug.h> 19554c0a3aSHans de Goede #include <hal_data.h> 20554c0a3aSHans de Goede 21554c0a3aSHans de Goede MODULE_LICENSE("GPL"); 22554c0a3aSHans de Goede MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); 23554c0a3aSHans de Goede MODULE_AUTHOR("Realtek Semiconductor Corp."); 24554c0a3aSHans de Goede MODULE_VERSION(DRIVERVERSION); 25554c0a3aSHans de Goede 26554c0a3aSHans de Goede /* module param defaults */ 27322e7049SHarsha Sharma static int rtw_chip_version; 28554c0a3aSHans de Goede static int rtw_rfintfs = HWPI; 29322e7049SHarsha Sharma static int rtw_lbkmode;/* RTL8712_AIR_TRX; */ 30554c0a3aSHans de Goede 31554c0a3aSHans de Goede 32554c0a3aSHans de Goede static int rtw_network_mode = Ndis802_11IBSS;/* Ndis802_11Infrastructure;infra, ad-hoc, auto */ 33554c0a3aSHans de Goede /* struct ndis_802_11_ssid ssid; */ 34554c0a3aSHans de Goede static int rtw_channel = 1;/* ad-hoc support requirement */ 35554c0a3aSHans de Goede static int rtw_wireless_mode = WIRELESS_MODE_MAX; 36554c0a3aSHans de Goede static int rtw_vrtl_carrier_sense = AUTO_VCS; 37554c0a3aSHans de Goede static int rtw_vcs_type = RTS_CTS;/* */ 38554c0a3aSHans de Goede static int rtw_rts_thresh = 2347;/* */ 39554c0a3aSHans de Goede static int rtw_frag_thresh = 2346;/* */ 40554c0a3aSHans de Goede static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */ 41554c0a3aSHans de Goede static int rtw_scan_mode = 1;/* active, passive */ 42554c0a3aSHans de Goede static int rtw_adhoc_tx_pwr = 1; 43322e7049SHarsha Sharma static int rtw_soft_ap; 44554c0a3aSHans de Goede /* int smart_ps = 1; */ 45554c0a3aSHans de Goede static int rtw_power_mgnt = 1; 46554c0a3aSHans de Goede static int rtw_ips_mode = IPS_NORMAL; 47554c0a3aSHans de Goede module_param(rtw_ips_mode, int, 0644); 48554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_ips_mode,"The default IPS mode"); 49554c0a3aSHans de Goede 50554c0a3aSHans de Goede static int rtw_smart_ps = 2; 51554c0a3aSHans de Goede 52554c0a3aSHans de Goede static int rtw_check_fw_ps = 1; 53554c0a3aSHans de Goede 54554c0a3aSHans de Goede static int rtw_usb_rxagg_mode = 2;/* USB_RX_AGG_DMA = 1, USB_RX_AGG_USB =2 */ 55554c0a3aSHans de Goede module_param(rtw_usb_rxagg_mode, int, 0644); 56554c0a3aSHans de Goede 57554c0a3aSHans de Goede static int rtw_radio_enable = 1; 58554c0a3aSHans de Goede static int rtw_long_retry_lmt = 7; 59554c0a3aSHans de Goede static int rtw_short_retry_lmt = 7; 60554c0a3aSHans de Goede static int rtw_busy_thresh = 40; 61554c0a3aSHans de Goede /* int qos_enable = 0; */ 62554c0a3aSHans de Goede static int rtw_ack_policy = NORMAL_ACK; 63554c0a3aSHans de Goede 64322e7049SHarsha Sharma static int rtw_software_encrypt; 65322e7049SHarsha Sharma static int rtw_software_decrypt; 66554c0a3aSHans de Goede 67322e7049SHarsha Sharma static int rtw_acm_method;/* 0:By SW 1:By HW. */ 68554c0a3aSHans de Goede 69554c0a3aSHans de Goede static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */ 70322e7049SHarsha Sharma static int rtw_uapsd_enable; 71554c0a3aSHans de Goede static int rtw_uapsd_max_sp = NO_LIMIT; 72322e7049SHarsha Sharma static int rtw_uapsd_acbk_en; 73322e7049SHarsha Sharma static int rtw_uapsd_acbe_en; 74322e7049SHarsha Sharma static int rtw_uapsd_acvi_en; 75322e7049SHarsha Sharma static int rtw_uapsd_acvo_en; 76554c0a3aSHans de Goede 77554c0a3aSHans de Goede int rtw_ht_enable = 1; 78554c0a3aSHans de Goede /* 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160MHz, 4: 80+80MHz */ 79554c0a3aSHans de Goede /* 2.4G use bit 0 ~ 3, 5G use bit 4 ~ 7 */ 80554c0a3aSHans de Goede /* 0x21 means enable 2.4G 40MHz & 5G 80MHz */ 81554c0a3aSHans de Goede static int rtw_bw_mode = 0x21; 82554c0a3aSHans de Goede static int rtw_ampdu_enable = 1;/* for enable tx_ampdu ,0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */ 83554c0a3aSHans de Goede static int rtw_rx_stbc = 1;/* 0: disable, 1:enable 2.4g */ 84322e7049SHarsha Sharma static int rtw_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto . There is an IOT issu with DLINK DIR-629 when the flag turn on */ 85554c0a3aSHans de Goede /* Short GI support Bit Map */ 86554c0a3aSHans de Goede /* BIT0 - 20MHz, 0: non-support, 1: support */ 87554c0a3aSHans de Goede /* BIT1 - 40MHz, 0: non-support, 1: support */ 88554c0a3aSHans de Goede /* BIT2 - 80MHz, 0: non-support, 1: support */ 89554c0a3aSHans de Goede /* BIT3 - 160MHz, 0: non-support, 1: support */ 90554c0a3aSHans de Goede static int rtw_short_gi = 0xf; 91554c0a3aSHans de Goede /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */ 92554c0a3aSHans de Goede static int rtw_ldpc_cap = 0x33; 93554c0a3aSHans de Goede /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */ 94554c0a3aSHans de Goede static int rtw_stbc_cap = 0x13; 95554c0a3aSHans de Goede /* BIT0: Enable VHT Beamformer, BIT1: Enable VHT Beamformee, BIT4: Enable HT Beamformer, BIT5: Enable HT Beamformee */ 96554c0a3aSHans de Goede static int rtw_beamform_cap = 0x2; 97554c0a3aSHans de Goede 98554c0a3aSHans de Goede static int rtw_lowrate_two_xmit = 1;/* Use 2 path Tx to transmit MCS0~7 and legacy mode */ 99554c0a3aSHans de Goede 100554c0a3aSHans de Goede /* int rf_config = RF_1T2R; 1T2R */ 101554c0a3aSHans de Goede static int rtw_rf_config = RF_MAX_TYPE; /* auto */ 102322e7049SHarsha Sharma static int rtw_low_power; 103322e7049SHarsha Sharma static int rtw_wifi_spec; 104554c0a3aSHans de Goede static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX; 105554c0a3aSHans de Goede 106554c0a3aSHans de Goede static int rtw_btcoex_enable = 1; 107554c0a3aSHans de Goede module_param(rtw_btcoex_enable, int, 0644); 108554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_btcoex_enable, "Enable BT co-existence mechanism"); 109554c0a3aSHans de Goede static int rtw_bt_iso = 2;/* 0:Low, 1:High, 2:From Efuse */ 110554c0a3aSHans de Goede static int rtw_bt_sco = 3;/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy */ 111554c0a3aSHans de Goede static int rtw_bt_ampdu = 1 ;/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ 112554c0a3aSHans de Goede static int rtw_ant_num = -1; /* <0: undefined, >0: Antenna number */ 113554c0a3aSHans de Goede module_param(rtw_ant_num, int, 0644); 114554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_ant_num, "Antenna number setting"); 115554c0a3aSHans de Goede 116554c0a3aSHans de Goede static int rtw_AcceptAddbaReq = true;/* 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */ 117554c0a3aSHans de Goede 118554c0a3aSHans de Goede static int rtw_antdiv_cfg = 1; /* 0:OFF , 1:ON, 2:decide by Efuse config */ 119322e7049SHarsha Sharma static int rtw_antdiv_type; /* 0:decide by efuse 1: for 88EE, 1Tx and 1RxCG are diversity.(2 Ant with SPDT), 2: for 88EE, 1Tx and 2Rx are diversity.(2 Ant, Tx and RxCG are both on aux port, RxCS is on main port), 3: for 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */ 120554c0a3aSHans de Goede 121554c0a3aSHans de Goede 122322e7049SHarsha Sharma static int rtw_enusbss;/* 0:disable, 1:enable */ 123554c0a3aSHans de Goede 124554c0a3aSHans de Goede static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */ 125554c0a3aSHans de Goede 126554c0a3aSHans de Goede #ifdef CONFIG_HW_PWRP_DETECTION 127554c0a3aSHans de Goede static int rtw_hwpwrp_detect = 1; 128554c0a3aSHans de Goede #else 129322e7049SHarsha Sharma static int rtw_hwpwrp_detect; /* HW power ping detect 0:disable , 1:enable */ 130554c0a3aSHans de Goede #endif 131554c0a3aSHans de Goede 132322e7049SHarsha Sharma static int rtw_hw_wps_pbc; 133554c0a3aSHans de Goede 134554c0a3aSHans de Goede int rtw_mc2u_disable = 0; 135554c0a3aSHans de Goede 136322e7049SHarsha Sharma static int rtw_80211d; 137554c0a3aSHans de Goede 138554c0a3aSHans de Goede #ifdef CONFIG_QOS_OPTIMIZATION 139554c0a3aSHans de Goede static int rtw_qos_opt_enable = 1;/* 0: disable, 1:enable */ 140554c0a3aSHans de Goede #else 141322e7049SHarsha Sharma static int rtw_qos_opt_enable;/* 0: disable, 1:enable */ 142554c0a3aSHans de Goede #endif 143554c0a3aSHans de Goede module_param(rtw_qos_opt_enable, int, 0644); 144554c0a3aSHans de Goede 145554c0a3aSHans de Goede static char* ifname = "wlan%d"; 146554c0a3aSHans de Goede module_param(ifname, charp, 0644); 147554c0a3aSHans de Goede MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); 148554c0a3aSHans de Goede 149554c0a3aSHans de Goede char* rtw_initmac = NULL; /* temp mac address if users want to use instead of the mac address in Efuse */ 150554c0a3aSHans de Goede 151554c0a3aSHans de Goede module_param(rtw_initmac, charp, 0644); 152554c0a3aSHans de Goede module_param(rtw_channel_plan, int, 0644); 153554c0a3aSHans de Goede module_param(rtw_chip_version, int, 0644); 154554c0a3aSHans de Goede module_param(rtw_rfintfs, int, 0644); 155554c0a3aSHans de Goede module_param(rtw_lbkmode, int, 0644); 156554c0a3aSHans de Goede module_param(rtw_network_mode, int, 0644); 157554c0a3aSHans de Goede module_param(rtw_channel, int, 0644); 158554c0a3aSHans de Goede module_param(rtw_wmm_enable, int, 0644); 159554c0a3aSHans de Goede module_param(rtw_vrtl_carrier_sense, int, 0644); 160554c0a3aSHans de Goede module_param(rtw_vcs_type, int, 0644); 161554c0a3aSHans de Goede module_param(rtw_busy_thresh, int, 0644); 162554c0a3aSHans de Goede 163554c0a3aSHans de Goede module_param(rtw_ht_enable, int, 0644); 164554c0a3aSHans de Goede module_param(rtw_bw_mode, int, 0644); 165554c0a3aSHans de Goede module_param(rtw_ampdu_enable, int, 0644); 166554c0a3aSHans de Goede module_param(rtw_rx_stbc, int, 0644); 167554c0a3aSHans de Goede module_param(rtw_ampdu_amsdu, int, 0644); 168554c0a3aSHans de Goede 169554c0a3aSHans de Goede module_param(rtw_lowrate_two_xmit, int, 0644); 170554c0a3aSHans de Goede 171554c0a3aSHans de Goede module_param(rtw_rf_config, int, 0644); 172554c0a3aSHans de Goede module_param(rtw_power_mgnt, int, 0644); 173554c0a3aSHans de Goede module_param(rtw_smart_ps, int, 0644); 174554c0a3aSHans de Goede module_param(rtw_low_power, int, 0644); 175554c0a3aSHans de Goede module_param(rtw_wifi_spec, int, 0644); 176554c0a3aSHans de Goede 177554c0a3aSHans de Goede module_param(rtw_antdiv_cfg, int, 0644); 178554c0a3aSHans de Goede module_param(rtw_antdiv_type, int, 0644); 179554c0a3aSHans de Goede 180554c0a3aSHans de Goede module_param(rtw_enusbss, int, 0644); 181554c0a3aSHans de Goede module_param(rtw_hwpdn_mode, int, 0644); 182554c0a3aSHans de Goede module_param(rtw_hwpwrp_detect, int, 0644); 183554c0a3aSHans de Goede 184554c0a3aSHans de Goede module_param(rtw_hw_wps_pbc, int, 0644); 185554c0a3aSHans de Goede 186554c0a3aSHans de Goede static uint rtw_max_roaming_times = 2; 187554c0a3aSHans de Goede module_param(rtw_max_roaming_times, uint, 0644); 188554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_max_roaming_times,"The max roaming times to try"); 189554c0a3aSHans de Goede 190554c0a3aSHans de Goede module_param(rtw_mc2u_disable, int, 0644); 191554c0a3aSHans de Goede 192554c0a3aSHans de Goede module_param(rtw_80211d, int, 0644); 193554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); 194554c0a3aSHans de Goede 195322e7049SHarsha Sharma static uint rtw_notch_filter; 196554c0a3aSHans de Goede module_param(rtw_notch_filter, uint, 0644); 197554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P"); 198554c0a3aSHans de Goede 199554c0a3aSHans de Goede #define CONFIG_RTW_HIQ_FILTER 1 200554c0a3aSHans de Goede 201554c0a3aSHans de Goede static uint rtw_hiq_filter = CONFIG_RTW_HIQ_FILTER; 202554c0a3aSHans de Goede module_param(rtw_hiq_filter, uint, 0644); 203554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_hiq_filter, "0:allow all, 1:allow special, 2:deny all"); 204554c0a3aSHans de Goede 205322e7049SHarsha Sharma static int rtw_tx_pwr_lmt_enable; 206322e7049SHarsha Sharma static int rtw_tx_pwr_by_rate; 207554c0a3aSHans de Goede 208554c0a3aSHans de Goede module_param(rtw_tx_pwr_lmt_enable, int, 0644); 209554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_tx_pwr_lmt_enable,"0:Disable, 1:Enable, 2: Depend on efuse"); 210554c0a3aSHans de Goede 211554c0a3aSHans de Goede module_param(rtw_tx_pwr_by_rate, int, 0644); 212554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_tx_pwr_by_rate,"0:Disable, 1:Enable, 2: Depend on efuse"); 213554c0a3aSHans de Goede 214554c0a3aSHans de Goede char *rtw_phy_file_path = ""; 215554c0a3aSHans de Goede module_param(rtw_phy_file_path, charp, 0644); 216554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_phy_file_path, "The path of phy parameter"); 217554c0a3aSHans de Goede /* PHY FILE Bit Map */ 218554c0a3aSHans de Goede /* BIT0 - MAC, 0: non-support, 1: support */ 219554c0a3aSHans de Goede /* BIT1 - BB, 0: non-support, 1: support */ 220554c0a3aSHans de Goede /* BIT2 - BB_PG, 0: non-support, 1: support */ 221554c0a3aSHans de Goede /* BIT3 - BB_MP, 0: non-support, 1: support */ 222554c0a3aSHans de Goede /* BIT4 - RF, 0: non-support, 1: support */ 223554c0a3aSHans de Goede /* BIT5 - RF_TXPWR_TRACK, 0: non-support, 1: support */ 224554c0a3aSHans de Goede /* BIT6 - RF_TXPWR_LMT, 0: non-support, 1: support */ 225554c0a3aSHans de Goede static int rtw_load_phy_file = (BIT2 | BIT6); 226554c0a3aSHans de Goede module_param(rtw_load_phy_file, int, 0644); 227554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_load_phy_file,"PHY File Bit Map"); 228322e7049SHarsha Sharma static int rtw_decrypt_phy_file; 229554c0a3aSHans de Goede module_param(rtw_decrypt_phy_file, int, 0644); 230554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_decrypt_phy_file,"Enable Decrypt PHY File"); 231554c0a3aSHans de Goede 232554c0a3aSHans de Goede int _netdev_open(struct net_device *pnetdev); 233554c0a3aSHans de Goede int netdev_open (struct net_device *pnetdev); 234554c0a3aSHans de Goede static int netdev_close (struct net_device *pnetdev); 235554c0a3aSHans de Goede 236554c0a3aSHans de Goede static uint loadparam(struct adapter *padapter, _nic_hdl pnetdev) 237554c0a3aSHans de Goede { 238554c0a3aSHans de Goede uint status = _SUCCESS; 239554c0a3aSHans de Goede struct registry_priv *registry_par = &padapter->registrypriv; 240554c0a3aSHans de Goede 241554c0a3aSHans de Goede registry_par->chip_version = (u8)rtw_chip_version; 242554c0a3aSHans de Goede registry_par->rfintfs = (u8)rtw_rfintfs; 243554c0a3aSHans de Goede registry_par->lbkmode = (u8)rtw_lbkmode; 244554c0a3aSHans de Goede /* registry_par->hci = (u8)hci; */ 245554c0a3aSHans de Goede registry_par->network_mode = (u8)rtw_network_mode; 246554c0a3aSHans de Goede 247554c0a3aSHans de Goede memcpy(registry_par->ssid.Ssid, "ANY", 3); 248554c0a3aSHans de Goede registry_par->ssid.SsidLength = 3; 249554c0a3aSHans de Goede 250554c0a3aSHans de Goede registry_par->channel = (u8)rtw_channel; 251554c0a3aSHans de Goede registry_par->wireless_mode = (u8)rtw_wireless_mode; 252554c0a3aSHans de Goede 253554c0a3aSHans de Goede if (registry_par->channel > 14) 254554c0a3aSHans de Goede registry_par->channel = 1; 255554c0a3aSHans de Goede 256554c0a3aSHans de Goede registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense ; 257554c0a3aSHans de Goede registry_par->vcs_type = (u8)rtw_vcs_type; 258554c0a3aSHans de Goede registry_par->rts_thresh = (u16)rtw_rts_thresh; 259554c0a3aSHans de Goede registry_par->frag_thresh = (u16)rtw_frag_thresh; 260554c0a3aSHans de Goede registry_par->preamble = (u8)rtw_preamble; 261554c0a3aSHans de Goede registry_par->scan_mode = (u8)rtw_scan_mode; 262554c0a3aSHans de Goede registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr; 263554c0a3aSHans de Goede registry_par->soft_ap = (u8)rtw_soft_ap; 264554c0a3aSHans de Goede registry_par->smart_ps = (u8)rtw_smart_ps; 265554c0a3aSHans de Goede registry_par->check_fw_ps = (u8)rtw_check_fw_ps; 266554c0a3aSHans de Goede registry_par->power_mgnt = (u8)rtw_power_mgnt; 267554c0a3aSHans de Goede registry_par->ips_mode = (u8)rtw_ips_mode; 268554c0a3aSHans de Goede registry_par->radio_enable = (u8)rtw_radio_enable; 269554c0a3aSHans de Goede registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt; 270554c0a3aSHans de Goede registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt; 271554c0a3aSHans de Goede registry_par->busy_thresh = (u16)rtw_busy_thresh; 272554c0a3aSHans de Goede /* registry_par->qos_enable = (u8)rtw_qos_enable; */ 273554c0a3aSHans de Goede registry_par->ack_policy = (u8)rtw_ack_policy; 274554c0a3aSHans de Goede registry_par->software_encrypt = (u8)rtw_software_encrypt; 275554c0a3aSHans de Goede registry_par->software_decrypt = (u8)rtw_software_decrypt; 276554c0a3aSHans de Goede 277554c0a3aSHans de Goede registry_par->acm_method = (u8)rtw_acm_method; 278554c0a3aSHans de Goede registry_par->usb_rxagg_mode = (u8)rtw_usb_rxagg_mode; 279554c0a3aSHans de Goede 280554c0a3aSHans de Goede /* UAPSD */ 281554c0a3aSHans de Goede registry_par->wmm_enable = (u8)rtw_wmm_enable; 282554c0a3aSHans de Goede registry_par->uapsd_enable = (u8)rtw_uapsd_enable; 283554c0a3aSHans de Goede registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp; 284554c0a3aSHans de Goede registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en; 285554c0a3aSHans de Goede registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en; 286554c0a3aSHans de Goede registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en; 287554c0a3aSHans de Goede registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en; 288554c0a3aSHans de Goede 289554c0a3aSHans de Goede registry_par->ht_enable = (u8)rtw_ht_enable; 290554c0a3aSHans de Goede registry_par->bw_mode = (u8)rtw_bw_mode; 291554c0a3aSHans de Goede registry_par->ampdu_enable = (u8)rtw_ampdu_enable; 292554c0a3aSHans de Goede registry_par->rx_stbc = (u8)rtw_rx_stbc; 293554c0a3aSHans de Goede registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu; 294554c0a3aSHans de Goede registry_par->short_gi = (u8)rtw_short_gi; 295554c0a3aSHans de Goede registry_par->ldpc_cap = (u8)rtw_ldpc_cap; 296554c0a3aSHans de Goede registry_par->stbc_cap = (u8)rtw_stbc_cap; 297554c0a3aSHans de Goede registry_par->beamform_cap = (u8)rtw_beamform_cap; 298554c0a3aSHans de Goede 299554c0a3aSHans de Goede registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; 300554c0a3aSHans de Goede registry_par->rf_config = (u8)rtw_rf_config; 301554c0a3aSHans de Goede registry_par->low_power = (u8)rtw_low_power; 302554c0a3aSHans de Goede 303554c0a3aSHans de Goede 304554c0a3aSHans de Goede registry_par->wifi_spec = (u8)rtw_wifi_spec; 305554c0a3aSHans de Goede 306554c0a3aSHans de Goede registry_par->channel_plan = (u8)rtw_channel_plan; 307554c0a3aSHans de Goede 308554c0a3aSHans de Goede registry_par->btcoex = (u8)rtw_btcoex_enable; 309554c0a3aSHans de Goede registry_par->bt_iso = (u8)rtw_bt_iso; 310554c0a3aSHans de Goede registry_par->bt_sco = (u8)rtw_bt_sco; 311554c0a3aSHans de Goede registry_par->bt_ampdu = (u8)rtw_bt_ampdu; 312554c0a3aSHans de Goede registry_par->ant_num = (s8)rtw_ant_num; 313554c0a3aSHans de Goede 314554c0a3aSHans de Goede registry_par->bAcceptAddbaReq = (u8)rtw_AcceptAddbaReq; 315554c0a3aSHans de Goede 316554c0a3aSHans de Goede registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg; 317554c0a3aSHans de Goede registry_par->antdiv_type = (u8)rtw_antdiv_type; 318554c0a3aSHans de Goede 319554c0a3aSHans de Goede registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc; 320554c0a3aSHans de Goede 321554c0a3aSHans de Goede registry_par->max_roaming_times = (u8)rtw_max_roaming_times; 322554c0a3aSHans de Goede #ifdef CONFIG_INTEL_WIDI 323554c0a3aSHans de Goede registry_par->max_roaming_times = (u8)rtw_max_roaming_times + 2; 324554c0a3aSHans de Goede #endif /* CONFIG_INTEL_WIDI */ 325554c0a3aSHans de Goede 326554c0a3aSHans de Goede registry_par->enable80211d = (u8)rtw_80211d; 327554c0a3aSHans de Goede 328554c0a3aSHans de Goede snprintf(registry_par->ifname, 16, "%s", ifname); 329554c0a3aSHans de Goede 330554c0a3aSHans de Goede registry_par->notch_filter = (u8)rtw_notch_filter; 331554c0a3aSHans de Goede 332554c0a3aSHans de Goede registry_par->RegEnableTxPowerLimit = (u8)rtw_tx_pwr_lmt_enable; 333554c0a3aSHans de Goede registry_par->RegEnableTxPowerByRate = (u8)rtw_tx_pwr_by_rate; 334554c0a3aSHans de Goede 335554c0a3aSHans de Goede registry_par->RegPowerBase = 14; 336554c0a3aSHans de Goede registry_par->TxBBSwing_2G = 0xFF; 337554c0a3aSHans de Goede registry_par->TxBBSwing_5G = 0xFF; 338554c0a3aSHans de Goede registry_par->bEn_RFE = 1; 339554c0a3aSHans de Goede registry_par->RFE_Type = 64; 340554c0a3aSHans de Goede 341554c0a3aSHans de Goede registry_par->load_phy_file = (u8)rtw_load_phy_file; 342554c0a3aSHans de Goede registry_par->RegDecryptCustomFile = (u8)rtw_decrypt_phy_file; 343554c0a3aSHans de Goede registry_par->qos_opt_enable = (u8)rtw_qos_opt_enable; 344554c0a3aSHans de Goede 345554c0a3aSHans de Goede registry_par->hiq_filter = (u8)rtw_hiq_filter; 346554c0a3aSHans de Goede return status; 347554c0a3aSHans de Goede } 348554c0a3aSHans de Goede 349554c0a3aSHans de Goede static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) 350554c0a3aSHans de Goede { 351554c0a3aSHans de Goede struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); 352554c0a3aSHans de Goede struct sockaddr *addr = p; 353554c0a3aSHans de Goede 354ffd3c648SHarsha Sharma if (padapter->bup == false) { 355554c0a3aSHans de Goede /* DBG_871X("r8711_net_set_mac_address(), MAC =%x:%x:%x:%x:%x:%x\n", addr->sa_data[0], addr->sa_data[1], addr->sa_data[2], addr->sa_data[3], */ 356554c0a3aSHans de Goede /* addr->sa_data[4], addr->sa_data[5]); */ 357554c0a3aSHans de Goede memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN); 358554c0a3aSHans de Goede /* memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN); */ 359554c0a3aSHans de Goede /* padapter->bset_hwaddr = true; */ 360554c0a3aSHans de Goede } 361554c0a3aSHans de Goede 362554c0a3aSHans de Goede return 0; 363554c0a3aSHans de Goede } 364554c0a3aSHans de Goede 365554c0a3aSHans de Goede static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) 366554c0a3aSHans de Goede { 367554c0a3aSHans de Goede struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); 368554c0a3aSHans de Goede struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 369554c0a3aSHans de Goede struct recv_priv *precvpriv = &(padapter->recvpriv); 370554c0a3aSHans de Goede 371554c0a3aSHans de Goede padapter->stats.tx_packets = pxmitpriv->tx_pkts;/* pxmitpriv->tx_pkts++; */ 372554c0a3aSHans de Goede padapter->stats.rx_packets = precvpriv->rx_pkts;/* precvpriv->rx_pkts++; */ 373554c0a3aSHans de Goede padapter->stats.tx_dropped = pxmitpriv->tx_drop; 374554c0a3aSHans de Goede padapter->stats.rx_dropped = precvpriv->rx_drop; 375554c0a3aSHans de Goede padapter->stats.tx_bytes = pxmitpriv->tx_bytes; 376554c0a3aSHans de Goede padapter->stats.rx_bytes = precvpriv->rx_bytes; 377554c0a3aSHans de Goede 378554c0a3aSHans de Goede return &padapter->stats; 379554c0a3aSHans de Goede } 380554c0a3aSHans de Goede 381554c0a3aSHans de Goede /* 382554c0a3aSHans de Goede * AC to queue mapping 383554c0a3aSHans de Goede * 384554c0a3aSHans de Goede * AC_VO -> queue 0 385554c0a3aSHans de Goede * AC_VI -> queue 1 386554c0a3aSHans de Goede * AC_BE -> queue 2 387554c0a3aSHans de Goede * AC_BK -> queue 3 388554c0a3aSHans de Goede */ 389554c0a3aSHans de Goede static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; 390554c0a3aSHans de Goede 391554c0a3aSHans de Goede /* Given a data frame determine the 802.1p/1d tag to use. */ 392554c0a3aSHans de Goede static unsigned int rtw_classify8021d(struct sk_buff *skb) 393554c0a3aSHans de Goede { 394554c0a3aSHans de Goede unsigned int dscp; 395554c0a3aSHans de Goede 396554c0a3aSHans de Goede /* skb->priority values from 256->263 are magic values to 397554c0a3aSHans de Goede * directly indicate a specific 802.1d priority. This is used 398554c0a3aSHans de Goede * to allow 802.1d priority to be passed directly in from VLAN 399554c0a3aSHans de Goede * tags, etc. 400554c0a3aSHans de Goede */ 401554c0a3aSHans de Goede if (skb->priority >= 256 && skb->priority <= 263) 402554c0a3aSHans de Goede return skb->priority - 256; 403554c0a3aSHans de Goede 404554c0a3aSHans de Goede switch (skb->protocol) { 405554c0a3aSHans de Goede case htons(ETH_P_IP): 406554c0a3aSHans de Goede dscp = ip_hdr(skb)->tos & 0xfc; 407554c0a3aSHans de Goede break; 408554c0a3aSHans de Goede default: 409554c0a3aSHans de Goede return 0; 410554c0a3aSHans de Goede } 411554c0a3aSHans de Goede 412554c0a3aSHans de Goede return dscp >> 5; 413554c0a3aSHans de Goede } 414554c0a3aSHans de Goede 415554c0a3aSHans de Goede 416554c0a3aSHans de Goede static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb 417554c0a3aSHans de Goede , void *accel_priv 418554c0a3aSHans de Goede , select_queue_fallback_t fallback 419554c0a3aSHans de Goede ) 420554c0a3aSHans de Goede { 421554c0a3aSHans de Goede struct adapter *padapter = rtw_netdev_priv(dev); 422554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 423554c0a3aSHans de Goede 424554c0a3aSHans de Goede skb->priority = rtw_classify8021d(skb); 425554c0a3aSHans de Goede 426554c0a3aSHans de Goede if (pmlmepriv->acm_mask != 0) 427554c0a3aSHans de Goede skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority); 428554c0a3aSHans de Goede 429554c0a3aSHans de Goede return rtw_1d_to_queue[skb->priority]; 430554c0a3aSHans de Goede } 431554c0a3aSHans de Goede 432554c0a3aSHans de Goede u16 rtw_recv_select_queue(struct sk_buff *skb) 433554c0a3aSHans de Goede { 434554c0a3aSHans de Goede struct iphdr *piphdr; 435554c0a3aSHans de Goede unsigned int dscp; 436554c0a3aSHans de Goede __be16 eth_type; 437554c0a3aSHans de Goede u32 priority; 438554c0a3aSHans de Goede u8 *pdata = skb->data; 439554c0a3aSHans de Goede 440554c0a3aSHans de Goede memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); 441554c0a3aSHans de Goede 442554c0a3aSHans de Goede switch (be16_to_cpu(eth_type)) { 443554c0a3aSHans de Goede case ETH_P_IP: 444554c0a3aSHans de Goede 445554c0a3aSHans de Goede piphdr = (struct iphdr *)(pdata + ETH_HLEN); 446554c0a3aSHans de Goede 447554c0a3aSHans de Goede dscp = piphdr->tos & 0xfc; 448554c0a3aSHans de Goede 449554c0a3aSHans de Goede priority = dscp >> 5; 450554c0a3aSHans de Goede 451554c0a3aSHans de Goede break; 452554c0a3aSHans de Goede default: 453554c0a3aSHans de Goede priority = 0; 454554c0a3aSHans de Goede } 455554c0a3aSHans de Goede 456554c0a3aSHans de Goede return rtw_1d_to_queue[priority]; 457554c0a3aSHans de Goede 458554c0a3aSHans de Goede } 459554c0a3aSHans de Goede 460554c0a3aSHans de Goede static int rtw_ndev_notifier_call(struct notifier_block * nb, unsigned long state, void *ptr) 461554c0a3aSHans de Goede { 462554c0a3aSHans de Goede struct net_device *dev = netdev_notifier_info_to_dev(ptr); 463554c0a3aSHans de Goede 464554c0a3aSHans de Goede if (dev->netdev_ops->ndo_do_ioctl != rtw_ioctl) 465554c0a3aSHans de Goede return NOTIFY_DONE; 466554c0a3aSHans de Goede 467554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_info_, FUNC_NDEV_FMT " state:%lu\n", FUNC_NDEV_ARG(dev), state); 468554c0a3aSHans de Goede 469554c0a3aSHans de Goede switch (state) { 470554c0a3aSHans de Goede case NETDEV_CHANGENAME: 471554c0a3aSHans de Goede rtw_adapter_proc_replace(dev); 472554c0a3aSHans de Goede break; 473554c0a3aSHans de Goede } 474554c0a3aSHans de Goede 475554c0a3aSHans de Goede return NOTIFY_DONE; 476554c0a3aSHans de Goede } 477554c0a3aSHans de Goede 478554c0a3aSHans de Goede static struct notifier_block rtw_ndev_notifier = { 479554c0a3aSHans de Goede .notifier_call = rtw_ndev_notifier_call, 480554c0a3aSHans de Goede }; 481554c0a3aSHans de Goede 482554c0a3aSHans de Goede int rtw_ndev_notifier_register(void) 483554c0a3aSHans de Goede { 484554c0a3aSHans de Goede return register_netdevice_notifier(&rtw_ndev_notifier); 485554c0a3aSHans de Goede } 486554c0a3aSHans de Goede 487554c0a3aSHans de Goede void rtw_ndev_notifier_unregister(void) 488554c0a3aSHans de Goede { 489554c0a3aSHans de Goede unregister_netdevice_notifier(&rtw_ndev_notifier); 490554c0a3aSHans de Goede } 491554c0a3aSHans de Goede 492554c0a3aSHans de Goede 493554c0a3aSHans de Goede static int rtw_ndev_init(struct net_device *dev) 494554c0a3aSHans de Goede { 495554c0a3aSHans de Goede struct adapter *adapter = rtw_netdev_priv(dev); 496554c0a3aSHans de Goede 497554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter)); 498554c0a3aSHans de Goede strncpy(adapter->old_ifname, dev->name, IFNAMSIZ); 499554c0a3aSHans de Goede rtw_adapter_proc_init(dev); 500554c0a3aSHans de Goede 501554c0a3aSHans de Goede return 0; 502554c0a3aSHans de Goede } 503554c0a3aSHans de Goede 504554c0a3aSHans de Goede static void rtw_ndev_uninit(struct net_device *dev) 505554c0a3aSHans de Goede { 506554c0a3aSHans de Goede struct adapter *adapter = rtw_netdev_priv(dev); 507554c0a3aSHans de Goede 508554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter)); 509554c0a3aSHans de Goede rtw_adapter_proc_deinit(dev); 510554c0a3aSHans de Goede } 511554c0a3aSHans de Goede 512554c0a3aSHans de Goede static const struct net_device_ops rtw_netdev_ops = { 513554c0a3aSHans de Goede .ndo_init = rtw_ndev_init, 514554c0a3aSHans de Goede .ndo_uninit = rtw_ndev_uninit, 515554c0a3aSHans de Goede .ndo_open = netdev_open, 516554c0a3aSHans de Goede .ndo_stop = netdev_close, 517554c0a3aSHans de Goede .ndo_start_xmit = rtw_xmit_entry, 518554c0a3aSHans de Goede .ndo_select_queue = rtw_select_queue, 519554c0a3aSHans de Goede .ndo_set_mac_address = rtw_net_set_mac_address, 520554c0a3aSHans de Goede .ndo_get_stats = rtw_net_get_stats, 521554c0a3aSHans de Goede .ndo_do_ioctl = rtw_ioctl, 522554c0a3aSHans de Goede }; 523554c0a3aSHans de Goede 524554c0a3aSHans de Goede int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) 525554c0a3aSHans de Goede { 526554c0a3aSHans de Goede if (dev_alloc_name(pnetdev, ifname) < 0) { 527554c0a3aSHans de Goede pr_err("dev_alloc_name, fail for %s\n", ifname); 528554c0a3aSHans de Goede return 1; 529554c0a3aSHans de Goede } 530554c0a3aSHans de Goede netif_carrier_off(pnetdev); 531554c0a3aSHans de Goede /* rtw_netif_stop_queue(pnetdev); */ 532554c0a3aSHans de Goede 533554c0a3aSHans de Goede return 0; 534554c0a3aSHans de Goede } 535554c0a3aSHans de Goede 536554c0a3aSHans de Goede struct net_device *rtw_init_netdev(struct adapter *old_padapter) 537554c0a3aSHans de Goede { 538554c0a3aSHans de Goede struct adapter *padapter; 539554c0a3aSHans de Goede struct net_device *pnetdev; 540554c0a3aSHans de Goede 541554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+init_net_dev\n")); 542554c0a3aSHans de Goede 543554c0a3aSHans de Goede if (old_padapter != NULL) 544554c0a3aSHans de Goede pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter); 545554c0a3aSHans de Goede else 546554c0a3aSHans de Goede pnetdev = rtw_alloc_etherdev(sizeof(struct adapter)); 547554c0a3aSHans de Goede 548554c0a3aSHans de Goede pr_info("pnetdev = %p\n", pnetdev); 549554c0a3aSHans de Goede if (!pnetdev) 550554c0a3aSHans de Goede return NULL; 551554c0a3aSHans de Goede 552554c0a3aSHans de Goede padapter = rtw_netdev_priv(pnetdev); 553554c0a3aSHans de Goede padapter->pnetdev = pnetdev; 554554c0a3aSHans de Goede 555554c0a3aSHans de Goede /* pnetdev->init = NULL; */ 556554c0a3aSHans de Goede 557554c0a3aSHans de Goede DBG_871X("register rtw_netdev_ops to netdev_ops\n"); 558554c0a3aSHans de Goede pnetdev->netdev_ops = &rtw_netdev_ops; 559554c0a3aSHans de Goede 560554c0a3aSHans de Goede /* pnetdev->tx_timeout = NULL; */ 561554c0a3aSHans de Goede pnetdev->watchdog_timeo = HZ * 3; /* 3 second timeout */ 562554c0a3aSHans de Goede pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; 563554c0a3aSHans de Goede 564554c0a3aSHans de Goede /* step 2. */ 565554c0a3aSHans de Goede loadparam(padapter, pnetdev); 566554c0a3aSHans de Goede 567554c0a3aSHans de Goede return pnetdev; 568554c0a3aSHans de Goede } 569554c0a3aSHans de Goede 570554c0a3aSHans de Goede void rtw_unregister_netdevs(struct dvobj_priv *dvobj) 571554c0a3aSHans de Goede { 572554c0a3aSHans de Goede struct adapter *padapter = NULL; 573554c0a3aSHans de Goede struct net_device *pnetdev = NULL; 574554c0a3aSHans de Goede 575554c0a3aSHans de Goede padapter = dvobj->padapters; 576554c0a3aSHans de Goede 577554c0a3aSHans de Goede if (padapter == NULL) 578554c0a3aSHans de Goede return; 579554c0a3aSHans de Goede 580554c0a3aSHans de Goede pnetdev = padapter->pnetdev; 581554c0a3aSHans de Goede 582554c0a3aSHans de Goede if ((padapter->DriverState != DRIVER_DISAPPEAR) && pnetdev) 583554c0a3aSHans de Goede unregister_netdev(pnetdev); /* will call netdev_close() */ 584554c0a3aSHans de Goede rtw_wdev_unregister(padapter->rtw_wdev); 585554c0a3aSHans de Goede } 586554c0a3aSHans de Goede 587554c0a3aSHans de Goede u32 rtw_start_drv_threads(struct adapter *padapter) 588554c0a3aSHans de Goede { 589554c0a3aSHans de Goede u32 _status = _SUCCESS; 590554c0a3aSHans de Goede 591554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_start_drv_threads\n")); 592554c0a3aSHans de Goede padapter->xmitThread = kthread_run(rtw_xmit_thread, padapter, "RTW_XMIT_THREAD"); 593554c0a3aSHans de Goede if (IS_ERR(padapter->xmitThread)) 594554c0a3aSHans de Goede _status = _FAIL; 595554c0a3aSHans de Goede 596554c0a3aSHans de Goede padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); 597554c0a3aSHans de Goede if (IS_ERR(padapter->cmdThread)) 598554c0a3aSHans de Goede _status = _FAIL; 599554c0a3aSHans de Goede else 600554c0a3aSHans de Goede down(&padapter->cmdpriv.terminate_cmdthread_sema); /* wait for cmd_thread to run */ 601554c0a3aSHans de Goede 602554c0a3aSHans de Goede rtw_hal_start_thread(padapter); 603554c0a3aSHans de Goede return _status; 604554c0a3aSHans de Goede } 605554c0a3aSHans de Goede 606554c0a3aSHans de Goede void rtw_stop_drv_threads (struct adapter *padapter) 607554c0a3aSHans de Goede { 608554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_stop_drv_threads\n")); 609554c0a3aSHans de Goede 610554c0a3aSHans de Goede rtw_stop_cmd_thread(padapter); 611554c0a3aSHans de Goede 612554c0a3aSHans de Goede /* Below is to termindate tx_thread... */ 613554c0a3aSHans de Goede up(&padapter->xmitpriv.xmit_sema); 614554c0a3aSHans de Goede down(&padapter->xmitpriv.terminate_xmitthread_sema); 615554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("\n drv_halt: rtw_xmit_thread can be terminated !\n")); 616554c0a3aSHans de Goede 617554c0a3aSHans de Goede rtw_hal_stop_thread(padapter); 618554c0a3aSHans de Goede } 619554c0a3aSHans de Goede 620554c0a3aSHans de Goede static u8 rtw_init_default_value(struct adapter *padapter) 621554c0a3aSHans de Goede { 622554c0a3aSHans de Goede u8 ret = _SUCCESS; 623554c0a3aSHans de Goede struct registry_priv* pregistrypriv = &padapter->registrypriv; 624554c0a3aSHans de Goede struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 625554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 626554c0a3aSHans de Goede struct security_priv *psecuritypriv = &padapter->securitypriv; 627554c0a3aSHans de Goede 628554c0a3aSHans de Goede /* xmit_priv */ 629554c0a3aSHans de Goede pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; 630554c0a3aSHans de Goede pxmitpriv->vcs = pregistrypriv->vcs_type; 631554c0a3aSHans de Goede pxmitpriv->vcs_type = pregistrypriv->vcs_type; 632554c0a3aSHans de Goede /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */ 633554c0a3aSHans de Goede pxmitpriv->frag_len = pregistrypriv->frag_thresh; 634554c0a3aSHans de Goede 635554c0a3aSHans de Goede /* recv_priv */ 636554c0a3aSHans de Goede 637554c0a3aSHans de Goede /* mlme_priv */ 638554c0a3aSHans de Goede pmlmepriv->scan_mode = SCAN_ACTIVE; 639554c0a3aSHans de Goede 640554c0a3aSHans de Goede /* qos_priv */ 641554c0a3aSHans de Goede /* pmlmepriv->qospriv.qos_option = pregistrypriv->wmm_enable; */ 642554c0a3aSHans de Goede 643554c0a3aSHans de Goede /* ht_priv */ 644554c0a3aSHans de Goede pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */ 645554c0a3aSHans de Goede 646554c0a3aSHans de Goede /* security_priv */ 647554c0a3aSHans de Goede /* rtw_get_encrypt_decrypt_from_registrypriv(padapter); */ 648554c0a3aSHans de Goede psecuritypriv->binstallGrpkey = _FAIL; 649554c0a3aSHans de Goede #ifdef CONFIG_GTK_OL 650554c0a3aSHans de Goede psecuritypriv->binstallKCK_KEK = _FAIL; 651554c0a3aSHans de Goede #endif /* CONFIG_GTK_OL */ 652554c0a3aSHans de Goede psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; 653554c0a3aSHans de Goede psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; 654554c0a3aSHans de Goede 655554c0a3aSHans de Goede psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 656554c0a3aSHans de Goede psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; 657554c0a3aSHans de Goede 658554c0a3aSHans de Goede psecuritypriv->dot11PrivacyKeyIndex = 0; 659554c0a3aSHans de Goede 660554c0a3aSHans de Goede psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 661554c0a3aSHans de Goede psecuritypriv->dot118021XGrpKeyid = 1; 662554c0a3aSHans de Goede 663554c0a3aSHans de Goede psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; 664554c0a3aSHans de Goede psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; 665554c0a3aSHans de Goede 666554c0a3aSHans de Goede /* registry_priv */ 667554c0a3aSHans de Goede rtw_init_registrypriv_dev_network(padapter); 668554c0a3aSHans de Goede rtw_update_registrypriv_dev_network(padapter); 669554c0a3aSHans de Goede 670554c0a3aSHans de Goede /* hal_priv */ 671554c0a3aSHans de Goede rtw_hal_def_value_init(padapter); 672554c0a3aSHans de Goede 673554c0a3aSHans de Goede /* misc. */ 674554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_RX_BIT); 675554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_TX_BIT); 676554c0a3aSHans de Goede padapter->bLinkInfoDump = 0; 677554c0a3aSHans de Goede padapter->bNotifyChannelChange = 0; 678554c0a3aSHans de Goede 679554c0a3aSHans de Goede /* for debug purpose */ 680554c0a3aSHans de Goede padapter->fix_rate = 0xFF; 681554c0a3aSHans de Goede padapter->driver_ampdu_spacing = 0xFF; 682554c0a3aSHans de Goede padapter->driver_rx_ampdu_factor = 0xFF; 683554c0a3aSHans de Goede 684554c0a3aSHans de Goede return ret; 685554c0a3aSHans de Goede } 686554c0a3aSHans de Goede 687554c0a3aSHans de Goede struct dvobj_priv *devobj_init(void) 688554c0a3aSHans de Goede { 689554c0a3aSHans de Goede struct dvobj_priv *pdvobj = NULL; 690554c0a3aSHans de Goede 6912ef2b7c2SJoe Perches pdvobj = rtw_zmalloc(sizeof(*pdvobj)); 6922ef2b7c2SJoe Perches if (pdvobj == NULL) 693554c0a3aSHans de Goede return NULL; 694554c0a3aSHans de Goede 695554c0a3aSHans de Goede mutex_init(&pdvobj->hw_init_mutex); 696554c0a3aSHans de Goede mutex_init(&pdvobj->h2c_fwcmd_mutex); 697554c0a3aSHans de Goede mutex_init(&pdvobj->setch_mutex); 698554c0a3aSHans de Goede mutex_init(&pdvobj->setbw_mutex); 699554c0a3aSHans de Goede 700554c0a3aSHans de Goede spin_lock_init(&pdvobj->lock); 701554c0a3aSHans de Goede 702554c0a3aSHans de Goede pdvobj->macid[1] = true; /* macid = 1 for bc/mc stainfo */ 703554c0a3aSHans de Goede 704554c0a3aSHans de Goede pdvobj->processing_dev_remove = false; 705554c0a3aSHans de Goede 706554c0a3aSHans de Goede atomic_set(&pdvobj->disable_func, 0); 707554c0a3aSHans de Goede 708554c0a3aSHans de Goede spin_lock_init(&pdvobj->cam_ctl.lock); 709554c0a3aSHans de Goede 710554c0a3aSHans de Goede return pdvobj; 711554c0a3aSHans de Goede } 712554c0a3aSHans de Goede 713554c0a3aSHans de Goede void devobj_deinit(struct dvobj_priv *pdvobj) 714554c0a3aSHans de Goede { 715554c0a3aSHans de Goede if (!pdvobj) 716554c0a3aSHans de Goede return; 717554c0a3aSHans de Goede 718554c0a3aSHans de Goede mutex_destroy(&pdvobj->hw_init_mutex); 719554c0a3aSHans de Goede mutex_destroy(&pdvobj->h2c_fwcmd_mutex); 720554c0a3aSHans de Goede mutex_destroy(&pdvobj->setch_mutex); 721554c0a3aSHans de Goede mutex_destroy(&pdvobj->setbw_mutex); 722554c0a3aSHans de Goede 723554c0a3aSHans de Goede kfree((u8 *)pdvobj); 724554c0a3aSHans de Goede } 725554c0a3aSHans de Goede 726554c0a3aSHans de Goede u8 rtw_reset_drv_sw(struct adapter *padapter) 727554c0a3aSHans de Goede { 728554c0a3aSHans de Goede u8 ret8 = _SUCCESS; 729554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 730554c0a3aSHans de Goede struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); 731554c0a3aSHans de Goede 732554c0a3aSHans de Goede /* hal_priv */ 733554c0a3aSHans de Goede if (is_primary_adapter(padapter)) 734554c0a3aSHans de Goede rtw_hal_def_value_init(padapter); 735554c0a3aSHans de Goede 736554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_RX_BIT); 737554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_TX_BIT); 738554c0a3aSHans de Goede padapter->bLinkInfoDump = 0; 739554c0a3aSHans de Goede 740554c0a3aSHans de Goede padapter->xmitpriv.tx_pkts = 0; 741554c0a3aSHans de Goede padapter->recvpriv.rx_pkts = 0; 742554c0a3aSHans de Goede 743554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bBusyTraffic = false; 744554c0a3aSHans de Goede 745554c0a3aSHans de Goede /* pmlmepriv->LinkDetectInfo.TrafficBusyState = false; */ 746554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; 747554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; 748554c0a3aSHans de Goede 749554c0a3aSHans de Goede _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING); 750554c0a3aSHans de Goede 751554c0a3aSHans de Goede pwrctrlpriv->pwr_state_check_cnts = 0; 752554c0a3aSHans de Goede 753554c0a3aSHans de Goede /* mlmeextpriv */ 754554c0a3aSHans de Goede padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE; 755554c0a3aSHans de Goede 756554c0a3aSHans de Goede rtw_set_signal_stat_timer(&padapter->recvpriv); 757554c0a3aSHans de Goede 758554c0a3aSHans de Goede return ret8; 759554c0a3aSHans de Goede } 760554c0a3aSHans de Goede 761554c0a3aSHans de Goede 762554c0a3aSHans de Goede u8 rtw_init_drv_sw(struct adapter *padapter) 763554c0a3aSHans de Goede { 764554c0a3aSHans de Goede u8 ret8 = _SUCCESS; 765554c0a3aSHans de Goede 766554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_init_drv_sw\n")); 767554c0a3aSHans de Goede 768554c0a3aSHans de Goede ret8 = rtw_init_default_value(padapter); 769554c0a3aSHans de Goede 770554c0a3aSHans de Goede rtw_init_hal_com_default_value(padapter); 771554c0a3aSHans de Goede 772554c0a3aSHans de Goede if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) { 773554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init cmd_priv\n")); 774554c0a3aSHans de Goede ret8 = _FAIL; 775554c0a3aSHans de Goede goto exit; 776554c0a3aSHans de Goede } 777554c0a3aSHans de Goede 778554c0a3aSHans de Goede padapter->cmdpriv.padapter = padapter; 779554c0a3aSHans de Goede 780554c0a3aSHans de Goede if ((rtw_init_evt_priv(&padapter->evtpriv)) == _FAIL) { 781554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init evt_priv\n")); 782554c0a3aSHans de Goede ret8 = _FAIL; 783554c0a3aSHans de Goede goto exit; 784554c0a3aSHans de Goede } 785554c0a3aSHans de Goede 786554c0a3aSHans de Goede 787554c0a3aSHans de Goede if (rtw_init_mlme_priv(padapter) == _FAIL) { 788554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init mlme_priv\n")); 789554c0a3aSHans de Goede ret8 = _FAIL; 790554c0a3aSHans de Goede goto exit; 791554c0a3aSHans de Goede } 792554c0a3aSHans de Goede 793554c0a3aSHans de Goede if (init_mlme_ext_priv(padapter) == _FAIL) { 794554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init mlme_ext_priv\n")); 795554c0a3aSHans de Goede ret8 = _FAIL; 796554c0a3aSHans de Goede goto exit; 797554c0a3aSHans de Goede } 798554c0a3aSHans de Goede 799554c0a3aSHans de Goede if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { 800554c0a3aSHans de Goede DBG_871X("Can't _rtw_init_xmit_priv\n"); 801554c0a3aSHans de Goede ret8 = _FAIL; 802554c0a3aSHans de Goede goto exit; 803554c0a3aSHans de Goede } 804554c0a3aSHans de Goede 805554c0a3aSHans de Goede if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) { 806554c0a3aSHans de Goede DBG_871X("Can't _rtw_init_recv_priv\n"); 807554c0a3aSHans de Goede ret8 = _FAIL; 808554c0a3aSHans de Goede goto exit; 809554c0a3aSHans de Goede } 810554c0a3aSHans de Goede /* add for CONFIG_IEEE80211W, none 11w also can use */ 811554c0a3aSHans de Goede spin_lock_init(&padapter->security_key_mutex); 812554c0a3aSHans de Goede 813554c0a3aSHans de Goede /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ 814554c0a3aSHans de Goede /* memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); */ 815554c0a3aSHans de Goede 816554c0a3aSHans de Goede if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) { 817554c0a3aSHans de Goede DBG_871X("Can't _rtw_init_sta_priv\n"); 818554c0a3aSHans de Goede ret8 = _FAIL; 819554c0a3aSHans de Goede goto exit; 820554c0a3aSHans de Goede } 821554c0a3aSHans de Goede 822554c0a3aSHans de Goede padapter->stapriv.padapter = padapter; 823554c0a3aSHans de Goede padapter->setband = GHZ24_50; 824554c0a3aSHans de Goede padapter->fix_rate = 0xFF; 825554c0a3aSHans de Goede rtw_init_bcmc_stainfo(padapter); 826554c0a3aSHans de Goede 827554c0a3aSHans de Goede rtw_init_pwrctrl_priv(padapter); 828554c0a3aSHans de Goede 829554c0a3aSHans de Goede rtw_hal_dm_init(padapter); 830554c0a3aSHans de Goede 831554c0a3aSHans de Goede #ifdef CONFIG_INTEL_WIDI 832554c0a3aSHans de Goede if (rtw_init_intel_widi(padapter) == _FAIL) { 833554c0a3aSHans de Goede DBG_871X("Can't rtw_init_intel_widi\n"); 834554c0a3aSHans de Goede ret8 = _FAIL; 835554c0a3aSHans de Goede goto exit; 836554c0a3aSHans de Goede } 837554c0a3aSHans de Goede #endif /* CONFIG_INTEL_WIDI */ 838554c0a3aSHans de Goede 839554c0a3aSHans de Goede exit: 840554c0a3aSHans de Goede 841554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_init_drv_sw\n")); 842554c0a3aSHans de Goede 843554c0a3aSHans de Goede return ret8; 844554c0a3aSHans de Goede } 845554c0a3aSHans de Goede 846554c0a3aSHans de Goede void rtw_cancel_all_timer(struct adapter *padapter) 847554c0a3aSHans de Goede { 848554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_cancel_all_timer\n")); 849554c0a3aSHans de Goede 850554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.assoc_timer); 851554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel association timer complete!\n")); 852554c0a3aSHans de Goede 853554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.scan_to_timer); 854554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel scan_to_timer!\n")); 855554c0a3aSHans de Goede 856554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer); 857554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel dynamic_chk_timer!\n")); 858554c0a3aSHans de Goede 859554c0a3aSHans de Goede del_timer_sync(&(adapter_to_pwrctl(padapter)->pwr_state_check_timer)); 860554c0a3aSHans de Goede 861554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.set_scan_deny_timer); 862554c0a3aSHans de Goede rtw_clear_scan_deny(padapter); 863554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel set_scan_deny_timer!\n")); 864554c0a3aSHans de Goede 865554c0a3aSHans de Goede del_timer_sync(&padapter->recvpriv.signal_stat_timer); 866554c0a3aSHans de Goede 867554c0a3aSHans de Goede /* cancel dm timer */ 868554c0a3aSHans de Goede rtw_hal_dm_deinit(padapter); 869554c0a3aSHans de Goede } 870554c0a3aSHans de Goede 871554c0a3aSHans de Goede u8 rtw_free_drv_sw(struct adapter *padapter) 872554c0a3aSHans de Goede { 873554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>rtw_free_drv_sw")); 874554c0a3aSHans de Goede 875554c0a3aSHans de Goede #ifdef CONFIG_INTEL_WIDI 876554c0a3aSHans de Goede rtw_free_intel_widi(padapter); 877554c0a3aSHans de Goede #endif /* CONFIG_INTEL_WIDI */ 878554c0a3aSHans de Goede 879554c0a3aSHans de Goede free_mlme_ext_priv(&padapter->mlmeextpriv); 880554c0a3aSHans de Goede 881554c0a3aSHans de Goede rtw_free_cmd_priv(&padapter->cmdpriv); 882554c0a3aSHans de Goede 883554c0a3aSHans de Goede rtw_free_evt_priv(&padapter->evtpriv); 884554c0a3aSHans de Goede 885554c0a3aSHans de Goede rtw_free_mlme_priv(&padapter->mlmepriv); 886554c0a3aSHans de Goede 887554c0a3aSHans de Goede /* free_io_queue(padapter); */ 888554c0a3aSHans de Goede 889554c0a3aSHans de Goede _rtw_free_xmit_priv(&padapter->xmitpriv); 890554c0a3aSHans de Goede 891554c0a3aSHans de Goede _rtw_free_sta_priv(&padapter->stapriv); /* will free bcmc_stainfo here */ 892554c0a3aSHans de Goede 893554c0a3aSHans de Goede _rtw_free_recv_priv(&padapter->recvpriv); 894554c0a3aSHans de Goede 895554c0a3aSHans de Goede rtw_free_pwrctrl_priv(padapter); 896554c0a3aSHans de Goede 897554c0a3aSHans de Goede /* kfree((void *)padapter); */ 898554c0a3aSHans de Goede 899554c0a3aSHans de Goede rtw_hal_free_data(padapter); 900554c0a3aSHans de Goede 901554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<==rtw_free_drv_sw\n")); 902554c0a3aSHans de Goede 903554c0a3aSHans de Goede /* free the old_pnetdev */ 904554c0a3aSHans de Goede if (padapter->rereg_nd_name_priv.old_pnetdev) { 905554c0a3aSHans de Goede free_netdev(padapter->rereg_nd_name_priv.old_pnetdev); 906554c0a3aSHans de Goede padapter->rereg_nd_name_priv.old_pnetdev = NULL; 907554c0a3aSHans de Goede } 908554c0a3aSHans de Goede 909554c0a3aSHans de Goede /* clear pbuddystruct adapter to avoid access wrong pointer. */ 910554c0a3aSHans de Goede if (padapter->pbuddy_adapter != NULL) 911554c0a3aSHans de Goede padapter->pbuddy_adapter->pbuddy_adapter = NULL; 912554c0a3aSHans de Goede 913554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_free_drv_sw\n")); 914554c0a3aSHans de Goede 915554c0a3aSHans de Goede return _SUCCESS; 916554c0a3aSHans de Goede } 917554c0a3aSHans de Goede 918554c0a3aSHans de Goede static int _rtw_drv_register_netdev(struct adapter *padapter, char *name) 919554c0a3aSHans de Goede { 920554c0a3aSHans de Goede int ret = _SUCCESS; 921554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 922554c0a3aSHans de Goede 923554c0a3aSHans de Goede /* alloc netdev name */ 924554c0a3aSHans de Goede if (rtw_init_netdev_name(pnetdev, name)) 925554c0a3aSHans de Goede return _FAIL; 926554c0a3aSHans de Goede 927554c0a3aSHans de Goede memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); 928554c0a3aSHans de Goede 929554c0a3aSHans de Goede /* Tell the network stack we exist */ 930554c0a3aSHans de Goede if (register_netdev(pnetdev) != 0) { 931554c0a3aSHans de Goede DBG_871X(FUNC_NDEV_FMT "Failed!\n", FUNC_NDEV_ARG(pnetdev)); 932554c0a3aSHans de Goede ret = _FAIL; 933554c0a3aSHans de Goede goto error_register_netdev; 934554c0a3aSHans de Goede } 935554c0a3aSHans de Goede 936554c0a3aSHans de Goede DBG_871X("%s, MAC Address (if%d) = " MAC_FMT "\n", __func__, (padapter->iface_id + 1), MAC_ARG(pnetdev->dev_addr)); 937554c0a3aSHans de Goede 938554c0a3aSHans de Goede return ret; 939554c0a3aSHans de Goede 940554c0a3aSHans de Goede error_register_netdev: 941554c0a3aSHans de Goede 942554c0a3aSHans de Goede rtw_free_drv_sw(padapter); 943554c0a3aSHans de Goede 944554c0a3aSHans de Goede rtw_free_netdev(pnetdev); 945554c0a3aSHans de Goede 946554c0a3aSHans de Goede return ret; 947554c0a3aSHans de Goede } 948554c0a3aSHans de Goede 949554c0a3aSHans de Goede int rtw_drv_register_netdev(struct adapter *if1) 950554c0a3aSHans de Goede { 951554c0a3aSHans de Goede struct dvobj_priv *dvobj = if1->dvobj; 952554c0a3aSHans de Goede struct adapter *padapter = dvobj->padapters; 953554c0a3aSHans de Goede char *name = if1->registrypriv.ifname; 954554c0a3aSHans de Goede 955554c0a3aSHans de Goede return _rtw_drv_register_netdev(padapter, name); 956554c0a3aSHans de Goede } 957554c0a3aSHans de Goede 958554c0a3aSHans de Goede int _netdev_open(struct net_device *pnetdev) 959554c0a3aSHans de Goede { 960554c0a3aSHans de Goede uint status; 961554c0a3aSHans de Goede struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); 962554c0a3aSHans de Goede struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); 963554c0a3aSHans de Goede 964554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+871x_drv - dev_open\n")); 965554c0a3aSHans de Goede DBG_871X("+871x_drv - drv_open, bup =%d\n", padapter->bup); 966554c0a3aSHans de Goede 967554c0a3aSHans de Goede padapter->netif_up = true; 968554c0a3aSHans de Goede 969554c0a3aSHans de Goede if (pwrctrlpriv->ps_flag == true) { 970554c0a3aSHans de Goede padapter->net_closed = false; 971554c0a3aSHans de Goede goto netdev_open_normal_process; 972554c0a3aSHans de Goede } 973554c0a3aSHans de Goede 974554c0a3aSHans de Goede if (padapter->bup == false) { 975554c0a3aSHans de Goede padapter->bDriverStopped = false; 976554c0a3aSHans de Goede padapter->bSurpriseRemoved = false; 977554c0a3aSHans de Goede padapter->bCardDisableWOHSM = false; 978554c0a3aSHans de Goede 979554c0a3aSHans de Goede status = rtw_hal_init(padapter); 980554c0a3aSHans de Goede if (status == _FAIL) { 981554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_err_, ("rtl871x_hal_init(): Can't init h/w!\n")); 982554c0a3aSHans de Goede goto netdev_open_error; 983554c0a3aSHans de Goede } 984554c0a3aSHans de Goede 985554c0a3aSHans de Goede DBG_871X("MAC Address = " MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr)); 986554c0a3aSHans de Goede 987554c0a3aSHans de Goede status = rtw_start_drv_threads(padapter); 988554c0a3aSHans de Goede if (status == _FAIL) { 989554c0a3aSHans de Goede DBG_871X("Initialize driver software resource Failed!\n"); 990554c0a3aSHans de Goede goto netdev_open_error; 991554c0a3aSHans de Goede } 992554c0a3aSHans de Goede 993554c0a3aSHans de Goede if (padapter->intf_start) 994554c0a3aSHans de Goede padapter->intf_start(padapter); 995554c0a3aSHans de Goede 996554c0a3aSHans de Goede rtw_cfg80211_init_wiphy(padapter); 997554c0a3aSHans de Goede 998554c0a3aSHans de Goede padapter->bup = true; 999554c0a3aSHans de Goede pwrctrlpriv->bips_processing = false; 1000554c0a3aSHans de Goede } 1001554c0a3aSHans de Goede padapter->net_closed = false; 1002554c0a3aSHans de Goede 1003554c0a3aSHans de Goede _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); 1004554c0a3aSHans de Goede 1005554c0a3aSHans de Goede if (!rtw_netif_queue_stopped(pnetdev)) 1006554c0a3aSHans de Goede rtw_netif_start_queue(pnetdev); 1007554c0a3aSHans de Goede else 1008554c0a3aSHans de Goede rtw_netif_wake_queue(pnetdev); 1009554c0a3aSHans de Goede 1010554c0a3aSHans de Goede netdev_open_normal_process: 1011554c0a3aSHans de Goede 1012554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-871x_drv - dev_open\n")); 1013554c0a3aSHans de Goede DBG_871X("-871x_drv - drv_open, bup =%d\n", padapter->bup); 1014554c0a3aSHans de Goede 1015554c0a3aSHans de Goede return 0; 1016554c0a3aSHans de Goede 1017554c0a3aSHans de Goede netdev_open_error: 1018554c0a3aSHans de Goede 1019554c0a3aSHans de Goede padapter->bup = false; 1020554c0a3aSHans de Goede 1021554c0a3aSHans de Goede netif_carrier_off(pnetdev); 1022554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 1023554c0a3aSHans de Goede 1024554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_err_, ("-871x_drv - dev_open, fail!\n")); 1025554c0a3aSHans de Goede DBG_871X("-871x_drv - drv_open fail, bup =%d\n", padapter->bup); 1026554c0a3aSHans de Goede 1027554c0a3aSHans de Goede return (-1); 1028554c0a3aSHans de Goede 1029554c0a3aSHans de Goede } 1030554c0a3aSHans de Goede 1031554c0a3aSHans de Goede int netdev_open(struct net_device *pnetdev) 1032554c0a3aSHans de Goede { 1033554c0a3aSHans de Goede int ret; 1034554c0a3aSHans de Goede struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); 1035554c0a3aSHans de Goede struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); 1036554c0a3aSHans de Goede 1037ffd3c648SHarsha Sharma if (pwrctrlpriv->bInSuspend == true) { 1038554c0a3aSHans de Goede DBG_871X("+871x_drv - drv_open, bInSuspend =%d\n", pwrctrlpriv->bInSuspend); 1039554c0a3aSHans de Goede return 0; 1040554c0a3aSHans de Goede } 1041554c0a3aSHans de Goede 1042554c0a3aSHans de Goede if (mutex_lock_interruptible(&(adapter_to_dvobj(padapter)->hw_init_mutex))) 1043554c0a3aSHans de Goede return -1; 1044554c0a3aSHans de Goede 1045554c0a3aSHans de Goede ret = _netdev_open(pnetdev); 1046554c0a3aSHans de Goede mutex_unlock(&(adapter_to_dvobj(padapter)->hw_init_mutex)); 1047554c0a3aSHans de Goede 1048554c0a3aSHans de Goede return ret; 1049554c0a3aSHans de Goede } 1050554c0a3aSHans de Goede 1051554c0a3aSHans de Goede static int ips_netdrv_open(struct adapter *padapter) 1052554c0a3aSHans de Goede { 1053554c0a3aSHans de Goede int status = _SUCCESS; 1054554c0a3aSHans de Goede /* struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); */ 1055554c0a3aSHans de Goede 1056554c0a3aSHans de Goede padapter->net_closed = false; 1057554c0a3aSHans de Goede 1058554c0a3aSHans de Goede DBG_871X("===> %s.........\n", __func__); 1059554c0a3aSHans de Goede 1060554c0a3aSHans de Goede 1061554c0a3aSHans de Goede padapter->bDriverStopped = false; 1062554c0a3aSHans de Goede padapter->bCardDisableWOHSM = false; 1063554c0a3aSHans de Goede /* padapter->bup = true; */ 1064554c0a3aSHans de Goede 1065554c0a3aSHans de Goede status = rtw_hal_init(padapter); 1066ffd3c648SHarsha Sharma if (status == _FAIL) { 1067554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_err_, ("ips_netdrv_open(): Can't init h/w!\n")); 1068554c0a3aSHans de Goede goto netdev_open_error; 1069554c0a3aSHans de Goede } 1070554c0a3aSHans de Goede 1071554c0a3aSHans de Goede if (padapter->intf_start) 1072554c0a3aSHans de Goede padapter->intf_start(padapter); 1073554c0a3aSHans de Goede 1074554c0a3aSHans de Goede _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); 1075554c0a3aSHans de Goede 1076554c0a3aSHans de Goede return _SUCCESS; 1077554c0a3aSHans de Goede 1078554c0a3aSHans de Goede netdev_open_error: 1079554c0a3aSHans de Goede /* padapter->bup = false; */ 1080554c0a3aSHans de Goede DBG_871X("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup); 1081554c0a3aSHans de Goede 1082554c0a3aSHans de Goede return _FAIL; 1083554c0a3aSHans de Goede } 1084554c0a3aSHans de Goede 1085554c0a3aSHans de Goede 1086554c0a3aSHans de Goede int rtw_ips_pwr_up(struct adapter *padapter) 1087554c0a3aSHans de Goede { 1088554c0a3aSHans de Goede int result; 1089554c0a3aSHans de Goede DBG_871X("===> rtw_ips_pwr_up..............\n"); 1090554c0a3aSHans de Goede 1091554c0a3aSHans de Goede result = ips_netdrv_open(padapter); 1092554c0a3aSHans de Goede 1093554c0a3aSHans de Goede DBG_871X("<=== rtw_ips_pwr_up..............\n"); 1094554c0a3aSHans de Goede return result; 1095554c0a3aSHans de Goede 1096554c0a3aSHans de Goede } 1097554c0a3aSHans de Goede 1098554c0a3aSHans de Goede void rtw_ips_pwr_down(struct adapter *padapter) 1099554c0a3aSHans de Goede { 1100554c0a3aSHans de Goede DBG_871X("===> rtw_ips_pwr_down...................\n"); 1101554c0a3aSHans de Goede 1102554c0a3aSHans de Goede padapter->bCardDisableWOHSM = true; 1103554c0a3aSHans de Goede padapter->net_closed = true; 1104554c0a3aSHans de Goede 1105554c0a3aSHans de Goede rtw_ips_dev_unload(padapter); 1106554c0a3aSHans de Goede padapter->bCardDisableWOHSM = false; 1107554c0a3aSHans de Goede DBG_871X("<=== rtw_ips_pwr_down.....................\n"); 1108554c0a3aSHans de Goede } 1109554c0a3aSHans de Goede 1110554c0a3aSHans de Goede void rtw_ips_dev_unload(struct adapter *padapter) 1111554c0a3aSHans de Goede { 1112554c0a3aSHans de Goede DBG_871X("====> %s...\n", __func__); 1113554c0a3aSHans de Goede 1114554c0a3aSHans de Goede 1115554c0a3aSHans de Goede if (padapter->bSurpriseRemoved == false) 1116554c0a3aSHans de Goede rtw_hal_deinit(padapter); 1117554c0a3aSHans de Goede 1118554c0a3aSHans de Goede } 1119554c0a3aSHans de Goede 1120554c0a3aSHans de Goede 1121554c0a3aSHans de Goede static int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) 1122554c0a3aSHans de Goede { 1123554c0a3aSHans de Goede int status = -1; 1124554c0a3aSHans de Goede 1125554c0a3aSHans de Goede struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); 1126554c0a3aSHans de Goede 1127ffd3c648SHarsha Sharma if (true == bnormal) { 1128554c0a3aSHans de Goede if (mutex_lock_interruptible(&(adapter_to_dvobj(padapter)->hw_init_mutex)) == 0) { 1129554c0a3aSHans de Goede status = _netdev_open(pnetdev); 1130554c0a3aSHans de Goede mutex_unlock(&(adapter_to_dvobj(padapter)->hw_init_mutex)); 1131554c0a3aSHans de Goede } 1132554c0a3aSHans de Goede } 1133554c0a3aSHans de Goede else 1134554c0a3aSHans de Goede status = (_SUCCESS == ips_netdrv_open(padapter)) ? (0) : (-1); 1135554c0a3aSHans de Goede 1136554c0a3aSHans de Goede return status; 1137554c0a3aSHans de Goede } 1138554c0a3aSHans de Goede 1139554c0a3aSHans de Goede static int netdev_close(struct net_device *pnetdev) 1140554c0a3aSHans de Goede { 1141554c0a3aSHans de Goede struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); 1142554c0a3aSHans de Goede struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); 1143554c0a3aSHans de Goede 1144554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+871x_drv - drv_close\n")); 1145554c0a3aSHans de Goede 1146ffd3c648SHarsha Sharma if (pwrctl->bInternalAutoSuspend == true) { 1147554c0a3aSHans de Goede /* rtw_pwr_wakeup(padapter); */ 1148554c0a3aSHans de Goede if (pwrctl->rf_pwrstate == rf_off) 1149554c0a3aSHans de Goede pwrctl->ps_flag = true; 1150554c0a3aSHans de Goede } 1151554c0a3aSHans de Goede padapter->net_closed = true; 1152554c0a3aSHans de Goede padapter->netif_up = false; 1153554c0a3aSHans de Goede 1154554c0a3aSHans de Goede /*if (!padapter->hw_init_completed) 1155554c0a3aSHans de Goede { 1156554c0a3aSHans de Goede DBG_871X("(1)871x_drv - drv_close, bup =%d, hw_init_completed =%d\n", padapter->bup, padapter->hw_init_completed); 1157554c0a3aSHans de Goede 1158554c0a3aSHans de Goede padapter->bDriverStopped = true; 1159554c0a3aSHans de Goede 1160554c0a3aSHans de Goede rtw_dev_unload(padapter); 1161554c0a3aSHans de Goede } 1162554c0a3aSHans de Goede else*/ 1163554c0a3aSHans de Goede if (pwrctl->rf_pwrstate == rf_on) { 1164554c0a3aSHans de Goede DBG_871X("(2)871x_drv - drv_close, bup =%d, hw_init_completed =%d\n", padapter->bup, padapter->hw_init_completed); 1165554c0a3aSHans de Goede 1166554c0a3aSHans de Goede /* s1. */ 1167ffd3c648SHarsha Sharma if (pnetdev) { 1168554c0a3aSHans de Goede if (!rtw_netif_queue_stopped(pnetdev)) 1169554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 1170554c0a3aSHans de Goede } 1171554c0a3aSHans de Goede 1172554c0a3aSHans de Goede /* s2. */ 1173554c0a3aSHans de Goede LeaveAllPowerSaveMode(padapter); 1174554c0a3aSHans de Goede rtw_disassoc_cmd(padapter, 500, false); 1175554c0a3aSHans de Goede /* s2-2. indicate disconnect to os */ 1176554c0a3aSHans de Goede rtw_indicate_disconnect(padapter); 1177554c0a3aSHans de Goede /* s2-3. */ 1178554c0a3aSHans de Goede rtw_free_assoc_resources(padapter, 1); 1179554c0a3aSHans de Goede /* s2-4. */ 1180554c0a3aSHans de Goede rtw_free_network_queue(padapter, true); 1181554c0a3aSHans de Goede } 1182554c0a3aSHans de Goede 1183554c0a3aSHans de Goede rtw_scan_abort(padapter); 1184554c0a3aSHans de Goede adapter_wdev_data(padapter)->bandroid_scan = false; 1185554c0a3aSHans de Goede 1186554c0a3aSHans de Goede RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-871x_drv - drv_close\n")); 1187554c0a3aSHans de Goede DBG_871X("-871x_drv - drv_close, bup =%d\n", padapter->bup); 1188554c0a3aSHans de Goede 1189554c0a3aSHans de Goede return 0; 1190554c0a3aSHans de Goede 1191554c0a3aSHans de Goede } 1192554c0a3aSHans de Goede 1193554c0a3aSHans de Goede void rtw_ndev_destructor(struct net_device *ndev) 1194554c0a3aSHans de Goede { 1195554c0a3aSHans de Goede DBG_871X(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev)); 1196554c0a3aSHans de Goede 1197554c0a3aSHans de Goede if (ndev->ieee80211_ptr) 1198554c0a3aSHans de Goede kfree((u8 *)ndev->ieee80211_ptr); 1199554c0a3aSHans de Goede } 1200554c0a3aSHans de Goede 1201554c0a3aSHans de Goede void rtw_dev_unload(struct adapter *padapter) 1202554c0a3aSHans de Goede { 1203554c0a3aSHans de Goede struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); 1204554c0a3aSHans de Goede struct dvobj_priv *pobjpriv = padapter->dvobj; 1205554c0a3aSHans de Goede struct debug_priv *pdbgpriv = &pobjpriv->drv_dbg; 1206554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1207554c0a3aSHans de Goede u8 cnt = 0; 1208554c0a3aSHans de Goede 1209554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+%s\n", __func__)); 1210554c0a3aSHans de Goede 1211ffd3c648SHarsha Sharma if (padapter->bup == true) { 1212554c0a3aSHans de Goede DBG_871X("===> %s\n", __func__); 1213554c0a3aSHans de Goede 1214554c0a3aSHans de Goede padapter->bDriverStopped = true; 1215554c0a3aSHans de Goede if (padapter->xmitpriv.ack_tx) 1216554c0a3aSHans de Goede rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); 1217554c0a3aSHans de Goede 1218554c0a3aSHans de Goede if (padapter->intf_stop) 1219554c0a3aSHans de Goede padapter->intf_stop(padapter); 1220554c0a3aSHans de Goede 1221554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("@ rtw_dev_unload: stop intf complete!\n")); 1222554c0a3aSHans de Goede 1223554c0a3aSHans de Goede if (!pwrctl->bInternalAutoSuspend) 1224554c0a3aSHans de Goede rtw_stop_drv_threads(padapter); 1225554c0a3aSHans de Goede 1226554c0a3aSHans de Goede while (atomic_read(&(pcmdpriv->cmdthd_running)) == true) { 1227554c0a3aSHans de Goede if (cnt > 5) { 1228554c0a3aSHans de Goede DBG_871X("stop cmdthd timeout\n"); 1229554c0a3aSHans de Goede break; 1230554c0a3aSHans de Goede } else { 1231554c0a3aSHans de Goede cnt ++; 1232554c0a3aSHans de Goede DBG_871X("cmdthd is running(%d)\n", cnt); 1233554c0a3aSHans de Goede msleep(10); 1234554c0a3aSHans de Goede } 1235554c0a3aSHans de Goede } 1236554c0a3aSHans de Goede 1237554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("@ %s: stop thread complete!\n", __func__)); 1238554c0a3aSHans de Goede 1239554c0a3aSHans de Goede /* check the status of IPS */ 1240554c0a3aSHans de Goede if (rtw_hal_check_ips_status(padapter) == true || pwrctl->rf_pwrstate == rf_off) { /* check HW status and SW state */ 1241554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: driver in IPS-FWLPS\n", __func__); 1242554c0a3aSHans de Goede pdbgpriv->dbg_dev_unload_inIPS_cnt++; 1243554c0a3aSHans de Goede LeaveAllPowerSaveMode(padapter); 1244554c0a3aSHans de Goede } else { 1245554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: driver not in IPS\n", __func__); 1246554c0a3aSHans de Goede } 1247554c0a3aSHans de Goede 1248ffd3c648SHarsha Sharma if (padapter->bSurpriseRemoved == false) { 1249554c0a3aSHans de Goede rtw_btcoex_IpsNotify(padapter, pwrctl->ips_mode_req); 1250554c0a3aSHans de Goede #ifdef CONFIG_WOWLAN 1251554c0a3aSHans de Goede if (pwrctl->bSupportRemoteWakeup == true && 1252554c0a3aSHans de Goede pwrctl->wowlan_mode == true) { 1253554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s bSupportRemoteWakeup ==true do not run rtw_hal_deinit()\n", __func__); 1254554c0a3aSHans de Goede } 1255554c0a3aSHans de Goede else 1256554c0a3aSHans de Goede #endif 1257554c0a3aSHans de Goede { 1258554c0a3aSHans de Goede /* amy modify 20120221 for power seq is different between driver open and ips */ 1259554c0a3aSHans de Goede rtw_hal_deinit(padapter); 1260554c0a3aSHans de Goede } 1261554c0a3aSHans de Goede padapter->bSurpriseRemoved = true; 1262554c0a3aSHans de Goede } 1263103ab687SColin Ian King RT_TRACE(_module_hci_intfs_c_, _drv_notice_, 1264103ab687SColin Ian King ("@ %s: deinit hal complete!\n", __func__)); 1265554c0a3aSHans de Goede 1266554c0a3aSHans de Goede padapter->bup = false; 1267554c0a3aSHans de Goede 1268554c0a3aSHans de Goede DBG_871X("<=== %s\n", __func__); 1269554c0a3aSHans de Goede } 1270554c0a3aSHans de Goede else { 1271554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("%s: bup ==false\n", __func__)); 1272554c0a3aSHans de Goede DBG_871X("%s: bup ==false\n", __func__); 1273554c0a3aSHans de Goede } 1274554c0a3aSHans de Goede 1275554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-%s\n", __func__)); 1276554c0a3aSHans de Goede } 1277554c0a3aSHans de Goede 1278554c0a3aSHans de Goede static int rtw_suspend_free_assoc_resource(struct adapter *padapter) 1279554c0a3aSHans de Goede { 1280554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1281554c0a3aSHans de Goede 1282554c0a3aSHans de Goede DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); 1283554c0a3aSHans de Goede 1284554c0a3aSHans de Goede if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { 1285554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) 1286ffd3c648SHarsha Sharma && check_fwstate(pmlmepriv, _FW_LINKED)) { 1287554c0a3aSHans de Goede DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n", __func__, 1288554c0a3aSHans de Goede pmlmepriv->cur_network.network.Ssid.Ssid, 1289554c0a3aSHans de Goede MAC_ARG(pmlmepriv->cur_network.network.MacAddress), 1290554c0a3aSHans de Goede pmlmepriv->cur_network.network.Ssid.SsidLength, 1291554c0a3aSHans de Goede pmlmepriv->assoc_ssid.SsidLength); 1292554c0a3aSHans de Goede rtw_set_to_roam(padapter, 1); 1293554c0a3aSHans de Goede } 1294554c0a3aSHans de Goede } 1295554c0a3aSHans de Goede 1296ffd3c648SHarsha Sharma if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)) { 1297554c0a3aSHans de Goede rtw_disassoc_cmd(padapter, 0, false); 1298554c0a3aSHans de Goede /* s2-2. indicate disconnect to os */ 1299554c0a3aSHans de Goede rtw_indicate_disconnect(padapter); 1300554c0a3aSHans de Goede } 1301ffd3c648SHarsha Sharma else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1302554c0a3aSHans de Goede rtw_sta_flush(padapter); 1303554c0a3aSHans de Goede } 1304554c0a3aSHans de Goede 1305554c0a3aSHans de Goede /* s2-3. */ 1306554c0a3aSHans de Goede rtw_free_assoc_resources(padapter, 1); 1307554c0a3aSHans de Goede 1308554c0a3aSHans de Goede /* s2-4. */ 1309554c0a3aSHans de Goede rtw_free_network_queue(padapter, true); 1310554c0a3aSHans de Goede 1311554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 1312554c0a3aSHans de Goede rtw_indicate_scan_done(padapter, 1); 1313554c0a3aSHans de Goede 1314ffd3c648SHarsha Sharma if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) { 1315554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: fw_under_linking\n", __func__); 1316554c0a3aSHans de Goede rtw_indicate_disconnect(padapter); 1317554c0a3aSHans de Goede } 1318554c0a3aSHans de Goede 1319554c0a3aSHans de Goede DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); 1320554c0a3aSHans de Goede return _SUCCESS; 1321554c0a3aSHans de Goede } 1322554c0a3aSHans de Goede 1323554c0a3aSHans de Goede #ifdef CONFIG_WOWLAN 1324554c0a3aSHans de Goede int rtw_suspend_wow(struct adapter *padapter) 1325554c0a3aSHans de Goede { 1326554c0a3aSHans de Goede u8 ch, bw, offset; 1327554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1328554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 1329554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1330554c0a3aSHans de Goede struct wowlan_ioctl_param poidparam; 1331554c0a3aSHans de Goede int ret = _SUCCESS; 1332554c0a3aSHans de Goede 1333554c0a3aSHans de Goede DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); 1334554c0a3aSHans de Goede 1335554c0a3aSHans de Goede 1336554c0a3aSHans de Goede DBG_871X("wowlan_mode: %d\n", pwrpriv->wowlan_mode); 1337554c0a3aSHans de Goede DBG_871X("wowlan_pno_enable: %d\n", pwrpriv->wowlan_pno_enable); 1338554c0a3aSHans de Goede 1339554c0a3aSHans de Goede if (pwrpriv->wowlan_mode == true) { 1340554c0a3aSHans de Goede if (pnetdev) 1341554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 1342554c0a3aSHans de Goede /* 1. stop thread */ 1343554c0a3aSHans de Goede padapter->bDriverStopped = true; /* for stop thread */ 1344554c0a3aSHans de Goede rtw_stop_drv_threads(padapter); 1345554c0a3aSHans de Goede padapter->bDriverStopped = false; /* for 32k command */ 1346554c0a3aSHans de Goede 1347554c0a3aSHans de Goede /* 2. disable interrupt */ 1348554c0a3aSHans de Goede if (padapter->intf_stop) { 1349554c0a3aSHans de Goede padapter->intf_stop(padapter); 1350554c0a3aSHans de Goede } 1351554c0a3aSHans de Goede 1352554c0a3aSHans de Goede /* 2.1 clean interupt */ 1353554c0a3aSHans de Goede if (padapter->HalFunc.clear_interrupt) 1354554c0a3aSHans de Goede padapter->HalFunc.clear_interrupt(padapter); 1355554c0a3aSHans de Goede 1356554c0a3aSHans de Goede /* 2.2 free irq */ 1357554c0a3aSHans de Goede /* sdio_free_irq(adapter_to_dvobj(padapter)); */ 1358554c0a3aSHans de Goede if (padapter->intf_free_irq) 1359554c0a3aSHans de Goede padapter->intf_free_irq(adapter_to_dvobj(padapter)); 1360554c0a3aSHans de Goede 1361554c0a3aSHans de Goede poidparam.subcode = WOWLAN_ENABLE; 1362554c0a3aSHans de Goede padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); 1363554c0a3aSHans de Goede if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { 1364554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) 1365ffd3c648SHarsha Sharma && check_fwstate(pmlmepriv, _FW_LINKED)) { 1366554c0a3aSHans de Goede DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n", __func__, 1367554c0a3aSHans de Goede pmlmepriv->cur_network.network.Ssid.Ssid, 1368554c0a3aSHans de Goede MAC_ARG(pmlmepriv->cur_network.network.MacAddress), 1369554c0a3aSHans de Goede pmlmepriv->cur_network.network.Ssid.SsidLength, 1370554c0a3aSHans de Goede pmlmepriv->assoc_ssid.SsidLength); 1371554c0a3aSHans de Goede 1372554c0a3aSHans de Goede rtw_set_to_roam(padapter, 0); 1373554c0a3aSHans de Goede } 1374554c0a3aSHans de Goede } 1375554c0a3aSHans de Goede 1376554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: wowmode suspending\n", __func__); 1377554c0a3aSHans de Goede 1378ffd3c648SHarsha Sharma if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { 1379554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: fw_under_survey\n", __func__); 1380554c0a3aSHans de Goede rtw_indicate_scan_done(padapter, 1); 1381554c0a3aSHans de Goede clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY); 1382554c0a3aSHans de Goede } 1383554c0a3aSHans de Goede 1384554c0a3aSHans de Goede if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { 1385554c0a3aSHans de Goede DBG_871X(FUNC_ADPT_FMT " back to linked/linking union - ch:%u, bw:%u, offset:%u\n", 1386554c0a3aSHans de Goede FUNC_ADPT_ARG(padapter), ch, bw, offset); 1387554c0a3aSHans de Goede set_channel_bwmode(padapter, ch, offset, bw); 1388554c0a3aSHans de Goede } 1389554c0a3aSHans de Goede 1390554c0a3aSHans de Goede if (pwrpriv->wowlan_pno_enable) 1391554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: pno: %d\n", __func__, pwrpriv->wowlan_pno_enable); 1392554c0a3aSHans de Goede else 1393554c0a3aSHans de Goede rtw_set_ps_mode(padapter, PS_MODE_DTIM, 0, 0, "WOWLAN"); 1394554c0a3aSHans de Goede 1395554c0a3aSHans de Goede } 1396ffd3c648SHarsha Sharma else { 1397554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR ### wowlan_mode =%d\n", __func__, pwrpriv->wowlan_mode); 1398554c0a3aSHans de Goede } 1399554c0a3aSHans de Goede DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); 1400554c0a3aSHans de Goede return ret; 1401554c0a3aSHans de Goede } 1402554c0a3aSHans de Goede #endif /* ifdef CONFIG_WOWLAN */ 1403554c0a3aSHans de Goede 1404554c0a3aSHans de Goede #ifdef CONFIG_AP_WOWLAN 1405554c0a3aSHans de Goede int rtw_suspend_ap_wow(struct adapter *padapter) 1406554c0a3aSHans de Goede { 1407554c0a3aSHans de Goede u8 ch, bw, offset; 1408554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 1409554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1410554c0a3aSHans de Goede struct wowlan_ioctl_param poidparam; 1411554c0a3aSHans de Goede int ret = _SUCCESS; 1412554c0a3aSHans de Goede 1413554c0a3aSHans de Goede DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); 1414554c0a3aSHans de Goede 1415554c0a3aSHans de Goede pwrpriv->wowlan_ap_mode = true; 1416554c0a3aSHans de Goede 1417554c0a3aSHans de Goede DBG_871X("wowlan_ap_mode: %d\n", pwrpriv->wowlan_ap_mode); 1418554c0a3aSHans de Goede 1419554c0a3aSHans de Goede if (pnetdev) 1420554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 1421554c0a3aSHans de Goede /* 1. stop thread */ 1422554c0a3aSHans de Goede padapter->bDriverStopped = true; /* for stop thread */ 1423554c0a3aSHans de Goede rtw_stop_drv_threads(padapter); 1424554c0a3aSHans de Goede padapter->bDriverStopped = false; /* for 32k command */ 1425554c0a3aSHans de Goede 1426554c0a3aSHans de Goede /* 2. disable interrupt */ 1427554c0a3aSHans de Goede rtw_hal_disable_interrupt(padapter); /* It need wait for leaving 32K. */ 1428554c0a3aSHans de Goede 1429554c0a3aSHans de Goede /* 2.1 clean interupt */ 1430554c0a3aSHans de Goede if (padapter->HalFunc.clear_interrupt) 1431554c0a3aSHans de Goede padapter->HalFunc.clear_interrupt(padapter); 1432554c0a3aSHans de Goede 1433554c0a3aSHans de Goede /* 2.2 free irq */ 1434554c0a3aSHans de Goede /* sdio_free_irq(adapter_to_dvobj(padapter)); */ 1435554c0a3aSHans de Goede if (padapter->intf_free_irq) 1436554c0a3aSHans de Goede padapter->intf_free_irq(adapter_to_dvobj(padapter)); 1437554c0a3aSHans de Goede 1438554c0a3aSHans de Goede poidparam.subcode = WOWLAN_AP_ENABLE; 1439554c0a3aSHans de Goede padapter->HalFunc.SetHwRegHandler(padapter, 1440554c0a3aSHans de Goede HW_VAR_AP_WOWLAN, (u8 *)&poidparam); 1441554c0a3aSHans de Goede 1442554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: wowmode suspending\n", __func__); 1443554c0a3aSHans de Goede 1444554c0a3aSHans de Goede if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { 1445554c0a3aSHans de Goede DBG_871X(FUNC_ADPT_FMT " back to linked/linking union - ch:%u, bw:%u, offset:%u\n", 1446554c0a3aSHans de Goede FUNC_ADPT_ARG(padapter), ch, bw, offset); 1447554c0a3aSHans de Goede set_channel_bwmode(padapter, ch, offset, bw); 1448554c0a3aSHans de Goede } 1449554c0a3aSHans de Goede 1450554c0a3aSHans de Goede rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, 0, "AP-WOWLAN"); 1451554c0a3aSHans de Goede 1452554c0a3aSHans de Goede DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); 1453554c0a3aSHans de Goede return ret; 1454554c0a3aSHans de Goede } 1455554c0a3aSHans de Goede #endif /* ifdef CONFIG_AP_WOWLAN */ 1456554c0a3aSHans de Goede 1457554c0a3aSHans de Goede 1458554c0a3aSHans de Goede static int rtw_suspend_normal(struct adapter *padapter) 1459554c0a3aSHans de Goede { 1460554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 1461554c0a3aSHans de Goede int ret = _SUCCESS; 1462554c0a3aSHans de Goede 1463554c0a3aSHans de Goede DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); 1464554c0a3aSHans de Goede if (pnetdev) { 1465554c0a3aSHans de Goede netif_carrier_off(pnetdev); 1466554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 1467554c0a3aSHans de Goede } 1468554c0a3aSHans de Goede 1469554c0a3aSHans de Goede rtw_suspend_free_assoc_resource(padapter); 1470554c0a3aSHans de Goede 1471554c0a3aSHans de Goede if ((rtw_hal_check_ips_status(padapter) == true) 1472ffd3c648SHarsha Sharma || (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off)) { 1473554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR #### driver in IPS ####ERROR###!!!\n", __func__); 1474554c0a3aSHans de Goede 1475554c0a3aSHans de Goede } 1476554c0a3aSHans de Goede 1477554c0a3aSHans de Goede rtw_dev_unload(padapter); 1478554c0a3aSHans de Goede 1479554c0a3aSHans de Goede /* sdio_deinit(adapter_to_dvobj(padapter)); */ 1480554c0a3aSHans de Goede if (padapter->intf_deinit) 1481554c0a3aSHans de Goede padapter->intf_deinit(adapter_to_dvobj(padapter)); 1482554c0a3aSHans de Goede 1483554c0a3aSHans de Goede DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); 1484554c0a3aSHans de Goede return ret; 1485554c0a3aSHans de Goede } 1486554c0a3aSHans de Goede 1487554c0a3aSHans de Goede int rtw_suspend_common(struct adapter *padapter) 1488554c0a3aSHans de Goede { 1489554c0a3aSHans de Goede struct dvobj_priv *psdpriv = padapter->dvobj; 1490554c0a3aSHans de Goede struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 1491554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); 1492554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1493554c0a3aSHans de Goede 1494554c0a3aSHans de Goede int ret = 0; 1495554c0a3aSHans de Goede unsigned long start_time = jiffies; 1496554c0a3aSHans de Goede 1497554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, " suspend start\n"); 1498554c0a3aSHans de Goede DBG_871X("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 1499554c0a3aSHans de Goede pdbgpriv->dbg_suspend_cnt++; 1500554c0a3aSHans de Goede 1501554c0a3aSHans de Goede pwrpriv->bInSuspend = true; 1502554c0a3aSHans de Goede 1503554c0a3aSHans de Goede while (pwrpriv->bips_processing == true) 1504554c0a3aSHans de Goede msleep(1); 1505554c0a3aSHans de Goede 1506ffd3c648SHarsha Sharma if ((!padapter->bup) || (padapter->bDriverStopped) || (padapter->bSurpriseRemoved)) { 1507554c0a3aSHans de Goede DBG_871X("%s bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n", __func__ 1508554c0a3aSHans de Goede , padapter->bup, padapter->bDriverStopped, padapter->bSurpriseRemoved); 1509554c0a3aSHans de Goede pdbgpriv->dbg_suspend_error_cnt++; 1510554c0a3aSHans de Goede goto exit; 1511554c0a3aSHans de Goede } 1512554c0a3aSHans de Goede rtw_ps_deny(padapter, PS_DENY_SUSPEND); 1513554c0a3aSHans de Goede 1514554c0a3aSHans de Goede rtw_cancel_all_timer(padapter); 1515554c0a3aSHans de Goede 1516554c0a3aSHans de Goede LeaveAllPowerSaveModeDirect(padapter); 1517554c0a3aSHans de Goede 1518554c0a3aSHans de Goede rtw_stop_cmd_thread(padapter); 1519554c0a3aSHans de Goede 1520554c0a3aSHans de Goede /* wait for the latest FW to remove this condition. */ 1521554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 1522554c0a3aSHans de Goede rtw_btcoex_SuspendNotify(padapter, 0); 1523554c0a3aSHans de Goede DBG_871X("WIFI_AP_STATE\n"); 1524554c0a3aSHans de Goede } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { 1525554c0a3aSHans de Goede rtw_btcoex_SuspendNotify(padapter, 1); 1526554c0a3aSHans de Goede DBG_871X("STATION\n"); 1527554c0a3aSHans de Goede } 1528554c0a3aSHans de Goede 1529554c0a3aSHans de Goede rtw_ps_deny_cancel(padapter, PS_DENY_SUSPEND); 1530554c0a3aSHans de Goede 1531554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { 1532554c0a3aSHans de Goede #ifdef CONFIG_WOWLAN 1533554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1534554c0a3aSHans de Goede pwrpriv->wowlan_mode = true; 1535554c0a3aSHans de Goede } else if (pwrpriv->wowlan_pno_enable == true) { 1536554c0a3aSHans de Goede pwrpriv->wowlan_mode |= pwrpriv->wowlan_pno_enable; 1537554c0a3aSHans de Goede } 1538554c0a3aSHans de Goede 1539554c0a3aSHans de Goede if (pwrpriv->wowlan_mode == true) 1540554c0a3aSHans de Goede rtw_suspend_wow(padapter); 1541554c0a3aSHans de Goede else 1542554c0a3aSHans de Goede rtw_suspend_normal(padapter); 1543554c0a3aSHans de Goede 1544554c0a3aSHans de Goede #else /* CONFIG_WOWLAN */ 1545554c0a3aSHans de Goede rtw_suspend_normal(padapter); 1546554c0a3aSHans de Goede #endif /* CONFIG_WOWLAN */ 1547554c0a3aSHans de Goede } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 1548554c0a3aSHans de Goede #ifdef CONFIG_AP_WOWLAN 1549554c0a3aSHans de Goede rtw_suspend_ap_wow(padapter); 1550554c0a3aSHans de Goede #else 1551554c0a3aSHans de Goede rtw_suspend_normal(padapter); 1552554c0a3aSHans de Goede #endif /* CONFIG_AP_WOWLAN */ 1553554c0a3aSHans de Goede } else { 1554554c0a3aSHans de Goede rtw_suspend_normal(padapter); 1555554c0a3aSHans de Goede } 1556554c0a3aSHans de Goede 1557554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "rtw suspend success in %d ms\n", 1558554c0a3aSHans de Goede jiffies_to_msecs(jiffies - start_time)); 1559554c0a3aSHans de Goede 1560554c0a3aSHans de Goede exit: 1561554c0a3aSHans de Goede DBG_871X("<=== %s return %d.............. in %dms\n", __func__ 1562554c0a3aSHans de Goede , ret, jiffies_to_msecs(jiffies - start_time)); 1563554c0a3aSHans de Goede 1564554c0a3aSHans de Goede return ret; 1565554c0a3aSHans de Goede } 1566554c0a3aSHans de Goede 1567554c0a3aSHans de Goede #ifdef CONFIG_WOWLAN 1568554c0a3aSHans de Goede int rtw_resume_process_wow(struct adapter *padapter) 1569554c0a3aSHans de Goede { 1570554c0a3aSHans de Goede struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1571554c0a3aSHans de Goede struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1572554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 1573554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1574554c0a3aSHans de Goede struct dvobj_priv *psdpriv = padapter->dvobj; 1575554c0a3aSHans de Goede struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 1576554c0a3aSHans de Goede struct wowlan_ioctl_param poidparam; 1577554c0a3aSHans de Goede struct sta_info *psta = NULL; 1578554c0a3aSHans de Goede int ret = _SUCCESS; 1579554c0a3aSHans de Goede 1580554c0a3aSHans de Goede DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); 1581554c0a3aSHans de Goede 1582554c0a3aSHans de Goede if (padapter) { 1583554c0a3aSHans de Goede pnetdev = padapter->pnetdev; 1584554c0a3aSHans de Goede pwrpriv = adapter_to_pwrctl(padapter); 1585554c0a3aSHans de Goede } else { 1586554c0a3aSHans de Goede pdbgpriv->dbg_resume_error_cnt++; 1587554c0a3aSHans de Goede ret = -1; 1588554c0a3aSHans de Goede goto exit; 1589554c0a3aSHans de Goede } 1590554c0a3aSHans de Goede 1591554c0a3aSHans de Goede if (padapter->bDriverStopped || padapter->bSurpriseRemoved) { 1592554c0a3aSHans de Goede DBG_871X("%s pdapter %p bDriverStopped %d bSurpriseRemoved %d\n", 1593554c0a3aSHans de Goede __func__, padapter, padapter->bDriverStopped, 1594554c0a3aSHans de Goede padapter->bSurpriseRemoved); 1595554c0a3aSHans de Goede goto exit; 1596554c0a3aSHans de Goede } 1597554c0a3aSHans de Goede 1598554c0a3aSHans de Goede #ifdef CONFIG_PNO_SUPPORT 1599554c0a3aSHans de Goede pwrpriv->pno_in_resume = true; 1600554c0a3aSHans de Goede #endif 1601554c0a3aSHans de Goede 1602554c0a3aSHans de Goede if (pwrpriv->wowlan_mode == true) { 1603554c0a3aSHans de Goede rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "WOWLAN"); 1604554c0a3aSHans de Goede 1605554c0a3aSHans de Goede pwrpriv->bFwCurrentInPSMode = false; 1606554c0a3aSHans de Goede 1607554c0a3aSHans de Goede if (padapter->intf_stop) { 1608554c0a3aSHans de Goede padapter->intf_stop(padapter); 1609554c0a3aSHans de Goede } 1610554c0a3aSHans de Goede 1611554c0a3aSHans de Goede if (padapter->HalFunc.clear_interrupt) 1612554c0a3aSHans de Goede padapter->HalFunc.clear_interrupt(padapter); 1613554c0a3aSHans de Goede 1614554c0a3aSHans de Goede /* if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) { */ 1615554c0a3aSHans de Goede if ((padapter->intf_alloc_irq) && (padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)) { 1616554c0a3aSHans de Goede ret = -1; 1617554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __func__)); 1618554c0a3aSHans de Goede goto exit; 1619554c0a3aSHans de Goede } 1620554c0a3aSHans de Goede 1621554c0a3aSHans de Goede /* Disable WOW, set H2C command */ 1622554c0a3aSHans de Goede poidparam.subcode = WOWLAN_DISABLE; 1623554c0a3aSHans de Goede padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); 1624554c0a3aSHans de Goede 1625554c0a3aSHans de Goede psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); 1626554c0a3aSHans de Goede if (psta) { 1627554c0a3aSHans de Goede set_sta_rate(padapter, psta); 1628554c0a3aSHans de Goede } 1629554c0a3aSHans de Goede 1630554c0a3aSHans de Goede 1631554c0a3aSHans de Goede padapter->bDriverStopped = false; 1632554c0a3aSHans de Goede DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped); 1633554c0a3aSHans de Goede rtw_start_drv_threads(padapter); 1634554c0a3aSHans de Goede 1635554c0a3aSHans de Goede if (padapter->intf_start) { 1636554c0a3aSHans de Goede padapter->intf_start(padapter); 1637554c0a3aSHans de Goede } 1638554c0a3aSHans de Goede 1639554c0a3aSHans de Goede /* start netif queue */ 1640554c0a3aSHans de Goede if (pnetdev) { 1641554c0a3aSHans de Goede if (!rtw_netif_queue_stopped(pnetdev)) 1642554c0a3aSHans de Goede rtw_netif_start_queue(pnetdev); 1643554c0a3aSHans de Goede else 1644554c0a3aSHans de Goede rtw_netif_wake_queue(pnetdev); 1645554c0a3aSHans de Goede } 1646554c0a3aSHans de Goede } 1647554c0a3aSHans de Goede else { 1648554c0a3aSHans de Goede 1649554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR ### wowlan_mode =%d\n", __func__, pwrpriv->wowlan_mode); 1650554c0a3aSHans de Goede } 1651554c0a3aSHans de Goede 1652554c0a3aSHans de Goede if (padapter->pid[1] != 0) { 1653554c0a3aSHans de Goede DBG_871X("pid[1]:%d\n", padapter->pid[1]); 1654554c0a3aSHans de Goede rtw_signal_process(padapter->pid[1], SIGUSR2); 1655554c0a3aSHans de Goede } 1656554c0a3aSHans de Goede 1657554c0a3aSHans de Goede if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { 1658554c0a3aSHans de Goede if (pwrpriv->wowlan_wake_reason == FWDecisionDisconnect || 1659554c0a3aSHans de Goede pwrpriv->wowlan_wake_reason == Rx_DisAssoc || 1660554c0a3aSHans de Goede pwrpriv->wowlan_wake_reason == Rx_DeAuth) { 1661554c0a3aSHans de Goede 1662554c0a3aSHans de Goede DBG_871X("%s: disconnect reason: %02x\n", __func__, 1663554c0a3aSHans de Goede pwrpriv->wowlan_wake_reason); 1664554c0a3aSHans de Goede rtw_indicate_disconnect(padapter); 1665554c0a3aSHans de Goede 1666554c0a3aSHans de Goede rtw_sta_media_status_rpt(padapter, 1667554c0a3aSHans de Goede rtw_get_stainfo(&padapter->stapriv, 1668554c0a3aSHans de Goede get_bssid(&padapter->mlmepriv)), 0); 1669554c0a3aSHans de Goede 1670554c0a3aSHans de Goede rtw_free_assoc_resources(padapter, 1); 1671554c0a3aSHans de Goede pmlmeinfo->state = WIFI_FW_NULL_STATE; 1672554c0a3aSHans de Goede 1673554c0a3aSHans de Goede } else { 1674554c0a3aSHans de Goede DBG_871X("%s: do roaming\n", __func__); 1675554c0a3aSHans de Goede rtw_roaming(padapter, NULL); 1676554c0a3aSHans de Goede } 1677554c0a3aSHans de Goede } 1678554c0a3aSHans de Goede 1679554c0a3aSHans de Goede if (pwrpriv->wowlan_mode == true) { 1680554c0a3aSHans de Goede pwrpriv->bips_processing = false; 1681554c0a3aSHans de Goede _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); 1682554c0a3aSHans de Goede } else { 1683554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "do not reset timer\n"); 1684554c0a3aSHans de Goede } 1685554c0a3aSHans de Goede 1686554c0a3aSHans de Goede pwrpriv->wowlan_mode = false; 1687554c0a3aSHans de Goede 1688554c0a3aSHans de Goede /* clean driver side wake up reason. */ 1689554c0a3aSHans de Goede pwrpriv->wowlan_wake_reason = 0; 1690554c0a3aSHans de Goede exit: 1691554c0a3aSHans de Goede DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); 1692554c0a3aSHans de Goede return ret; 1693554c0a3aSHans de Goede } 1694554c0a3aSHans de Goede #endif /* ifdef CONFIG_WOWLAN */ 1695554c0a3aSHans de Goede 1696554c0a3aSHans de Goede #ifdef CONFIG_AP_WOWLAN 1697554c0a3aSHans de Goede int rtw_resume_process_ap_wow(struct adapter *padapter) 1698554c0a3aSHans de Goede { 1699554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 1700554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1701554c0a3aSHans de Goede struct dvobj_priv *psdpriv = padapter->dvobj; 1702554c0a3aSHans de Goede struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 1703554c0a3aSHans de Goede struct wowlan_ioctl_param poidparam; 1704554c0a3aSHans de Goede int ret = _SUCCESS; 1705554c0a3aSHans de Goede 1706554c0a3aSHans de Goede DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); 1707554c0a3aSHans de Goede 1708554c0a3aSHans de Goede if (padapter) { 1709554c0a3aSHans de Goede pnetdev = padapter->pnetdev; 1710554c0a3aSHans de Goede pwrpriv = adapter_to_pwrctl(padapter); 1711554c0a3aSHans de Goede } else { 1712554c0a3aSHans de Goede pdbgpriv->dbg_resume_error_cnt++; 1713554c0a3aSHans de Goede ret = -1; 1714554c0a3aSHans de Goede goto exit; 1715554c0a3aSHans de Goede } 1716554c0a3aSHans de Goede 1717554c0a3aSHans de Goede rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "AP-WOWLAN"); 1718554c0a3aSHans de Goede 1719554c0a3aSHans de Goede pwrpriv->bFwCurrentInPSMode = false; 1720554c0a3aSHans de Goede 1721554c0a3aSHans de Goede rtw_hal_disable_interrupt(padapter); 1722554c0a3aSHans de Goede 1723554c0a3aSHans de Goede if (padapter->HalFunc.clear_interrupt) 1724554c0a3aSHans de Goede padapter->HalFunc.clear_interrupt(padapter); 1725554c0a3aSHans de Goede 1726554c0a3aSHans de Goede /* if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) { */ 1727554c0a3aSHans de Goede if ((padapter->intf_alloc_irq) && (padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)) { 1728554c0a3aSHans de Goede ret = -1; 1729554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __func__)); 1730554c0a3aSHans de Goede goto exit; 1731554c0a3aSHans de Goede } 1732554c0a3aSHans de Goede 1733554c0a3aSHans de Goede /* Disable WOW, set H2C command */ 1734554c0a3aSHans de Goede poidparam.subcode = WOWLAN_AP_DISABLE; 1735554c0a3aSHans de Goede padapter->HalFunc.SetHwRegHandler(padapter, 1736554c0a3aSHans de Goede HW_VAR_AP_WOWLAN, (u8 *)&poidparam); 1737554c0a3aSHans de Goede pwrpriv->wowlan_ap_mode = false; 1738554c0a3aSHans de Goede 1739554c0a3aSHans de Goede padapter->bDriverStopped = false; 1740554c0a3aSHans de Goede DBG_871X("%s: wowmode resuming, DriverStopped:%d\n", __func__, padapter->bDriverStopped); 1741554c0a3aSHans de Goede rtw_start_drv_threads(padapter); 1742554c0a3aSHans de Goede 1743554c0a3aSHans de Goede if (padapter->intf_start) { 1744554c0a3aSHans de Goede padapter->intf_start(padapter); 1745554c0a3aSHans de Goede } 1746554c0a3aSHans de Goede 1747554c0a3aSHans de Goede /* start netif queue */ 1748554c0a3aSHans de Goede if (pnetdev) { 1749554c0a3aSHans de Goede if (!rtw_netif_queue_stopped(pnetdev)) 1750554c0a3aSHans de Goede rtw_netif_start_queue(pnetdev); 1751554c0a3aSHans de Goede else 1752554c0a3aSHans de Goede rtw_netif_wake_queue(pnetdev); 1753554c0a3aSHans de Goede } 1754554c0a3aSHans de Goede 1755554c0a3aSHans de Goede if (padapter->pid[1] != 0) { 1756554c0a3aSHans de Goede DBG_871X("pid[1]:%d\n", padapter->pid[1]); 1757554c0a3aSHans de Goede rtw_signal_process(padapter->pid[1], SIGUSR2); 1758554c0a3aSHans de Goede } 1759554c0a3aSHans de Goede 1760554c0a3aSHans de Goede pwrpriv->bips_processing = false; 1761554c0a3aSHans de Goede _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); 1762554c0a3aSHans de Goede 1763554c0a3aSHans de Goede /* clean driver side wake up reason. */ 1764554c0a3aSHans de Goede pwrpriv->wowlan_wake_reason = 0; 1765554c0a3aSHans de Goede exit: 1766554c0a3aSHans de Goede DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); 1767554c0a3aSHans de Goede return ret; 1768554c0a3aSHans de Goede } 1769554c0a3aSHans de Goede #endif /* ifdef CONFIG_APWOWLAN */ 1770554c0a3aSHans de Goede 1771554c0a3aSHans de Goede static int rtw_resume_process_normal(struct adapter *padapter) 1772554c0a3aSHans de Goede { 1773554c0a3aSHans de Goede struct net_device *pnetdev; 1774554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv; 1775554c0a3aSHans de Goede struct mlme_priv *pmlmepriv; 1776554c0a3aSHans de Goede struct dvobj_priv *psdpriv; 1777554c0a3aSHans de Goede struct debug_priv *pdbgpriv; 1778554c0a3aSHans de Goede 1779554c0a3aSHans de Goede int ret = _SUCCESS; 1780554c0a3aSHans de Goede 1781554c0a3aSHans de Goede if (!padapter) { 1782554c0a3aSHans de Goede ret = -1; 1783554c0a3aSHans de Goede goto exit; 1784554c0a3aSHans de Goede } 1785554c0a3aSHans de Goede 1786554c0a3aSHans de Goede pnetdev = padapter->pnetdev; 1787554c0a3aSHans de Goede pwrpriv = adapter_to_pwrctl(padapter); 1788554c0a3aSHans de Goede pmlmepriv = &padapter->mlmepriv; 1789554c0a3aSHans de Goede psdpriv = padapter->dvobj; 1790554c0a3aSHans de Goede pdbgpriv = &psdpriv->drv_dbg; 1791554c0a3aSHans de Goede 1792554c0a3aSHans de Goede DBG_871X("==> " FUNC_ADPT_FMT " entry....\n", FUNC_ADPT_ARG(padapter)); 1793554c0a3aSHans de Goede /* interface init */ 1794554c0a3aSHans de Goede /* if (sdio_init(adapter_to_dvobj(padapter)) != _SUCCESS) */ 1795ffd3c648SHarsha Sharma if ((padapter->intf_init) && (padapter->intf_init(adapter_to_dvobj(padapter)) != _SUCCESS)) { 1796554c0a3aSHans de Goede ret = -1; 1797554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!!\n", __func__)); 1798554c0a3aSHans de Goede goto exit; 1799554c0a3aSHans de Goede } 1800554c0a3aSHans de Goede rtw_hal_disable_interrupt(padapter); 1801554c0a3aSHans de Goede /* if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) */ 1802ffd3c648SHarsha Sharma if ((padapter->intf_alloc_irq) && (padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)) { 1803554c0a3aSHans de Goede ret = -1; 1804554c0a3aSHans de Goede RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __func__)); 1805554c0a3aSHans de Goede goto exit; 1806554c0a3aSHans de Goede } 1807554c0a3aSHans de Goede 1808554c0a3aSHans de Goede rtw_reset_drv_sw(padapter); 1809554c0a3aSHans de Goede pwrpriv->bkeepfwalive = false; 1810554c0a3aSHans de Goede 1811554c0a3aSHans de Goede DBG_871X("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive); 1812554c0a3aSHans de Goede if (pm_netdev_open(pnetdev, true) != 0) { 1813554c0a3aSHans de Goede ret = -1; 1814554c0a3aSHans de Goede pdbgpriv->dbg_resume_error_cnt++; 1815554c0a3aSHans de Goede goto exit; 1816554c0a3aSHans de Goede } 1817554c0a3aSHans de Goede 1818554c0a3aSHans de Goede netif_device_attach(pnetdev); 1819554c0a3aSHans de Goede netif_carrier_on(pnetdev); 1820554c0a3aSHans de Goede 1821554c0a3aSHans de Goede if (padapter->pid[1] != 0) { 1822554c0a3aSHans de Goede DBG_871X("pid[1]:%d\n", padapter->pid[1]); 1823554c0a3aSHans de Goede rtw_signal_process(padapter->pid[1], SIGUSR2); 1824554c0a3aSHans de Goede } 1825554c0a3aSHans de Goede 1826554c0a3aSHans de Goede 1827554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1828554c0a3aSHans de Goede DBG_871X(FUNC_ADPT_FMT " fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); 1829554c0a3aSHans de Goede 1830554c0a3aSHans de Goede if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) 1831554c0a3aSHans de Goede rtw_roaming(padapter, NULL); 1832554c0a3aSHans de Goede 1833554c0a3aSHans de Goede } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1834554c0a3aSHans de Goede DBG_871X(FUNC_ADPT_FMT " fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); 1835554c0a3aSHans de Goede rtw_ap_restore_network(padapter); 1836554c0a3aSHans de Goede } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 1837554c0a3aSHans de Goede DBG_871X(FUNC_ADPT_FMT " fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); 1838554c0a3aSHans de Goede } else { 1839554c0a3aSHans de Goede DBG_871X(FUNC_ADPT_FMT " fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); 1840554c0a3aSHans de Goede } 1841554c0a3aSHans de Goede 1842554c0a3aSHans de Goede DBG_871X("<== " FUNC_ADPT_FMT " exit....\n", FUNC_ADPT_ARG(padapter)); 1843554c0a3aSHans de Goede 1844554c0a3aSHans de Goede exit: 1845554c0a3aSHans de Goede return ret; 1846554c0a3aSHans de Goede } 1847554c0a3aSHans de Goede 1848554c0a3aSHans de Goede int rtw_resume_common(struct adapter *padapter) 1849554c0a3aSHans de Goede { 1850554c0a3aSHans de Goede int ret = 0; 1851554c0a3aSHans de Goede unsigned long start_time = jiffies; 1852554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1853554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1854554c0a3aSHans de Goede 1855554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "resume start\n"); 1856554c0a3aSHans de Goede DBG_871X("==> %s (%s:%d)\n", __func__, current->comm, current->pid); 1857554c0a3aSHans de Goede 1858554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { 1859554c0a3aSHans de Goede #ifdef CONFIG_WOWLAN 1860554c0a3aSHans de Goede if (pwrpriv->wowlan_mode == true) 1861554c0a3aSHans de Goede rtw_resume_process_wow(padapter); 1862554c0a3aSHans de Goede else 1863554c0a3aSHans de Goede rtw_resume_process_normal(padapter); 1864554c0a3aSHans de Goede #else 1865554c0a3aSHans de Goede rtw_resume_process_normal(padapter); 1866554c0a3aSHans de Goede #endif 1867554c0a3aSHans de Goede 1868554c0a3aSHans de Goede } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 1869554c0a3aSHans de Goede #ifdef CONFIG_AP_WOWLAN 1870554c0a3aSHans de Goede rtw_resume_process_ap_wow(padapter); 1871554c0a3aSHans de Goede #else 1872554c0a3aSHans de Goede rtw_resume_process_normal(padapter); 1873554c0a3aSHans de Goede #endif /* CONFIG_AP_WOWLAN */ 1874554c0a3aSHans de Goede } else { 1875554c0a3aSHans de Goede rtw_resume_process_normal(padapter); 1876554c0a3aSHans de Goede } 1877554c0a3aSHans de Goede 1878554c0a3aSHans de Goede rtw_btcoex_SuspendNotify(padapter, 0); 1879554c0a3aSHans de Goede 1880554c0a3aSHans de Goede if (pwrpriv) { 1881554c0a3aSHans de Goede pwrpriv->bInSuspend = false; 1882554c0a3aSHans de Goede #ifdef CONFIG_PNO_SUPPORT 1883554c0a3aSHans de Goede pwrpriv->pno_in_resume = false; 1884554c0a3aSHans de Goede #endif 1885554c0a3aSHans de Goede } 1886554c0a3aSHans de Goede DBG_871X_LEVEL(_drv_always_, "%s:%d in %d ms\n", __func__ , ret, 1887554c0a3aSHans de Goede jiffies_to_msecs(jiffies - start_time)); 1888554c0a3aSHans de Goede 1889554c0a3aSHans de Goede return ret; 1890554c0a3aSHans de Goede } 1891