158391efdSNathan Chancellor // SPDX-License-Identifier: GPL-2.0 2554c0a3aSHans de Goede /****************************************************************************** 3554c0a3aSHans de Goede * 4554c0a3aSHans de Goede * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5554c0a3aSHans de Goede * 6554c0a3aSHans de Goede ******************************************************************************/ 7554c0a3aSHans de Goede #include <drv_types.h> 8554c0a3aSHans de Goede #include <rtw_debug.h> 9554c0a3aSHans de Goede #include <hal_data.h> 10554c0a3aSHans de Goede 11554c0a3aSHans de Goede MODULE_LICENSE("GPL"); 12554c0a3aSHans de Goede MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); 13554c0a3aSHans de Goede MODULE_AUTHOR("Realtek Semiconductor Corp."); 14554c0a3aSHans de Goede MODULE_VERSION(DRIVERVERSION); 15554c0a3aSHans de Goede 16554c0a3aSHans de Goede /* module param defaults */ 17322e7049SHarsha Sharma static int rtw_chip_version; 18554c0a3aSHans de Goede static int rtw_rfintfs = HWPI; 19322e7049SHarsha Sharma static int rtw_lbkmode;/* RTL8712_AIR_TRX; */ 20554c0a3aSHans de Goede 21554c0a3aSHans de Goede 22554c0a3aSHans de Goede static int rtw_network_mode = Ndis802_11IBSS;/* Ndis802_11Infrastructure;infra, ad-hoc, auto */ 23554c0a3aSHans de Goede /* struct ndis_802_11_ssid ssid; */ 24554c0a3aSHans de Goede static int rtw_channel = 1;/* ad-hoc support requirement */ 25708180a9SFabio Aiuto static int rtw_wireless_mode = WIRELESS_11BG_24N; 26554c0a3aSHans de Goede static int rtw_vrtl_carrier_sense = AUTO_VCS; 27554c0a3aSHans de Goede static int rtw_vcs_type = RTS_CTS;/* */ 28554c0a3aSHans de Goede static int rtw_rts_thresh = 2347;/* */ 29554c0a3aSHans de Goede static int rtw_frag_thresh = 2346;/* */ 30554c0a3aSHans de Goede static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */ 31554c0a3aSHans de Goede static int rtw_scan_mode = 1;/* active, passive */ 32554c0a3aSHans de Goede static int rtw_adhoc_tx_pwr = 1; 33322e7049SHarsha Sharma static int rtw_soft_ap; 34554c0a3aSHans de Goede /* int smart_ps = 1; */ 35554c0a3aSHans de Goede static int rtw_power_mgnt = 1; 36554c0a3aSHans de Goede static int rtw_ips_mode = IPS_NORMAL; 37554c0a3aSHans de Goede module_param(rtw_ips_mode, int, 0644); 38554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_ips_mode, "The default IPS mode"); 39554c0a3aSHans de Goede 40554c0a3aSHans de Goede static int rtw_smart_ps = 2; 41554c0a3aSHans de Goede 42554c0a3aSHans de Goede static int rtw_check_fw_ps = 1; 43554c0a3aSHans de Goede 44554c0a3aSHans de Goede static int rtw_usb_rxagg_mode = 2;/* USB_RX_AGG_DMA = 1, USB_RX_AGG_USB =2 */ 45554c0a3aSHans de Goede module_param(rtw_usb_rxagg_mode, int, 0644); 46554c0a3aSHans de Goede 47554c0a3aSHans de Goede static int rtw_radio_enable = 1; 48554c0a3aSHans de Goede static int rtw_long_retry_lmt = 7; 49554c0a3aSHans de Goede static int rtw_short_retry_lmt = 7; 50554c0a3aSHans de Goede static int rtw_busy_thresh = 40; 51554c0a3aSHans de Goede /* int qos_enable = 0; */ 52554c0a3aSHans de Goede static int rtw_ack_policy = NORMAL_ACK; 53554c0a3aSHans de Goede 54322e7049SHarsha Sharma static int rtw_software_encrypt; 55322e7049SHarsha Sharma static int rtw_software_decrypt; 56554c0a3aSHans de Goede 57322e7049SHarsha Sharma static int rtw_acm_method;/* 0:By SW 1:By HW. */ 58554c0a3aSHans de Goede 59554c0a3aSHans de Goede static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */ 60322e7049SHarsha Sharma static int rtw_uapsd_enable; 61554c0a3aSHans de Goede static int rtw_uapsd_max_sp = NO_LIMIT; 62322e7049SHarsha Sharma static int rtw_uapsd_acbk_en; 63322e7049SHarsha Sharma static int rtw_uapsd_acbe_en; 64322e7049SHarsha Sharma static int rtw_uapsd_acvi_en; 65322e7049SHarsha Sharma static int rtw_uapsd_acvo_en; 66554c0a3aSHans de Goede 67554c0a3aSHans de Goede int rtw_ht_enable = 1; 6833137187SFabio Aiuto /* 6933137187SFabio Aiuto * 0: 20 MHz, 1: 40 MHz 7033137187SFabio Aiuto * 2.4G use bit 0 ~ 3 7133137187SFabio Aiuto * 0x01 means enable 2.4G 40MHz 7233137187SFabio Aiuto */ 7333137187SFabio Aiuto static int rtw_bw_mode = 0x01; 74554c0a3aSHans 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) */ 75554c0a3aSHans de Goede static int rtw_rx_stbc = 1;/* 0: disable, 1:enable 2.4g */ 76322e7049SHarsha 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 */ 77554c0a3aSHans de Goede /* Short GI support Bit Map */ 78554c0a3aSHans de Goede /* BIT0 - 20MHz, 0: non-support, 1: support */ 79554c0a3aSHans de Goede /* BIT1 - 40MHz, 0: non-support, 1: support */ 80554c0a3aSHans de Goede /* BIT2 - 80MHz, 0: non-support, 1: support */ 81554c0a3aSHans de Goede /* BIT3 - 160MHz, 0: non-support, 1: support */ 82554c0a3aSHans de Goede static int rtw_short_gi = 0xf; 83554c0a3aSHans de Goede /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */ 84554c0a3aSHans de Goede static int rtw_ldpc_cap = 0x33; 85554c0a3aSHans de Goede /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */ 86554c0a3aSHans de Goede static int rtw_stbc_cap = 0x13; 87554c0a3aSHans de Goede /* BIT0: Enable VHT Beamformer, BIT1: Enable VHT Beamformee, BIT4: Enable HT Beamformer, BIT5: Enable HT Beamformee */ 88554c0a3aSHans de Goede static int rtw_beamform_cap = 0x2; 89554c0a3aSHans de Goede 90554c0a3aSHans de Goede static int rtw_lowrate_two_xmit = 1;/* Use 2 path Tx to transmit MCS0~7 and legacy mode */ 91554c0a3aSHans de Goede 92554c0a3aSHans de Goede /* int rf_config = RF_1T2R; 1T2R */ 93554c0a3aSHans de Goede static int rtw_rf_config = RF_MAX_TYPE; /* auto */ 94322e7049SHarsha Sharma static int rtw_low_power; 95322e7049SHarsha Sharma static int rtw_wifi_spec; 96554c0a3aSHans de Goede static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX; 97554c0a3aSHans de Goede 98554c0a3aSHans de Goede static int rtw_ant_num = -1; /* <0: undefined, >0: Antenna number */ 99554c0a3aSHans de Goede module_param(rtw_ant_num, int, 0644); 100554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_ant_num, "Antenna number setting"); 101554c0a3aSHans de Goede 102554c0a3aSHans de Goede static int rtw_antdiv_cfg = 1; /* 0:OFF , 1:ON, 2:decide by Efuse config */ 103322e7049SHarsha 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) */ 104554c0a3aSHans de Goede 105554c0a3aSHans de Goede 106322e7049SHarsha Sharma static int rtw_enusbss;/* 0:disable, 1:enable */ 107554c0a3aSHans de Goede 108554c0a3aSHans de Goede static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */ 109554c0a3aSHans de Goede 110322e7049SHarsha Sharma static int rtw_hwpwrp_detect; /* HW power ping detect 0:disable , 1:enable */ 111554c0a3aSHans de Goede 112322e7049SHarsha Sharma static int rtw_hw_wps_pbc; 113554c0a3aSHans de Goede 114*04e42451SScott J. Crouch int rtw_mc2u_disable; 115554c0a3aSHans de Goede 116322e7049SHarsha Sharma static int rtw_80211d; 117554c0a3aSHans de Goede 118322e7049SHarsha Sharma static int rtw_qos_opt_enable;/* 0: disable, 1:enable */ 119554c0a3aSHans de Goede module_param(rtw_qos_opt_enable, int, 0644); 120554c0a3aSHans de Goede 121554c0a3aSHans de Goede static char *ifname = "wlan%d"; 122554c0a3aSHans de Goede module_param(ifname, charp, 0644); 123554c0a3aSHans de Goede MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); 124554c0a3aSHans de Goede 125*04e42451SScott J. Crouch char *rtw_initmac; /* temp mac address if users want to use instead of the mac address in Efuse */ 126554c0a3aSHans de Goede 127554c0a3aSHans de Goede module_param(rtw_initmac, charp, 0644); 128554c0a3aSHans de Goede module_param(rtw_channel_plan, int, 0644); 129554c0a3aSHans de Goede module_param(rtw_chip_version, int, 0644); 130554c0a3aSHans de Goede module_param(rtw_rfintfs, int, 0644); 131554c0a3aSHans de Goede module_param(rtw_lbkmode, int, 0644); 132554c0a3aSHans de Goede module_param(rtw_network_mode, int, 0644); 133554c0a3aSHans de Goede module_param(rtw_channel, int, 0644); 134554c0a3aSHans de Goede module_param(rtw_wmm_enable, int, 0644); 135554c0a3aSHans de Goede module_param(rtw_vrtl_carrier_sense, int, 0644); 136554c0a3aSHans de Goede module_param(rtw_vcs_type, int, 0644); 137554c0a3aSHans de Goede module_param(rtw_busy_thresh, int, 0644); 138554c0a3aSHans de Goede 139554c0a3aSHans de Goede module_param(rtw_ht_enable, int, 0644); 140554c0a3aSHans de Goede module_param(rtw_bw_mode, int, 0644); 141554c0a3aSHans de Goede module_param(rtw_ampdu_enable, int, 0644); 142554c0a3aSHans de Goede module_param(rtw_rx_stbc, int, 0644); 143554c0a3aSHans de Goede module_param(rtw_ampdu_amsdu, int, 0644); 144554c0a3aSHans de Goede 145554c0a3aSHans de Goede module_param(rtw_lowrate_two_xmit, int, 0644); 146554c0a3aSHans de Goede 147554c0a3aSHans de Goede module_param(rtw_rf_config, int, 0644); 148554c0a3aSHans de Goede module_param(rtw_power_mgnt, int, 0644); 149554c0a3aSHans de Goede module_param(rtw_smart_ps, int, 0644); 150554c0a3aSHans de Goede module_param(rtw_low_power, int, 0644); 151554c0a3aSHans de Goede module_param(rtw_wifi_spec, int, 0644); 152554c0a3aSHans de Goede 153554c0a3aSHans de Goede module_param(rtw_antdiv_cfg, int, 0644); 154554c0a3aSHans de Goede module_param(rtw_antdiv_type, int, 0644); 155554c0a3aSHans de Goede 156554c0a3aSHans de Goede module_param(rtw_enusbss, int, 0644); 157554c0a3aSHans de Goede module_param(rtw_hwpdn_mode, int, 0644); 158554c0a3aSHans de Goede module_param(rtw_hwpwrp_detect, int, 0644); 159554c0a3aSHans de Goede 160554c0a3aSHans de Goede module_param(rtw_hw_wps_pbc, int, 0644); 161554c0a3aSHans de Goede 162554c0a3aSHans de Goede static uint rtw_max_roaming_times = 2; 163554c0a3aSHans de Goede module_param(rtw_max_roaming_times, uint, 0644); 164554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_max_roaming_times, "The max roaming times to try"); 165554c0a3aSHans de Goede 166554c0a3aSHans de Goede module_param(rtw_mc2u_disable, int, 0644); 167554c0a3aSHans de Goede 168554c0a3aSHans de Goede module_param(rtw_80211d, int, 0644); 169554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); 170554c0a3aSHans de Goede 171322e7049SHarsha Sharma static uint rtw_notch_filter; 172554c0a3aSHans de Goede module_param(rtw_notch_filter, uint, 0644); 173554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P"); 174554c0a3aSHans de Goede 175554c0a3aSHans de Goede #define CONFIG_RTW_HIQ_FILTER 1 176554c0a3aSHans de Goede 177554c0a3aSHans de Goede static uint rtw_hiq_filter = CONFIG_RTW_HIQ_FILTER; 178554c0a3aSHans de Goede module_param(rtw_hiq_filter, uint, 0644); 179554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_hiq_filter, "0:allow all, 1:allow special, 2:deny all"); 180554c0a3aSHans de Goede 181322e7049SHarsha Sharma static int rtw_tx_pwr_lmt_enable; 182322e7049SHarsha Sharma static int rtw_tx_pwr_by_rate; 183554c0a3aSHans de Goede 184554c0a3aSHans de Goede module_param(rtw_tx_pwr_lmt_enable, int, 0644); 185554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_tx_pwr_lmt_enable, "0:Disable, 1:Enable, 2: Depend on efuse"); 186554c0a3aSHans de Goede 187554c0a3aSHans de Goede module_param(rtw_tx_pwr_by_rate, int, 0644); 188554c0a3aSHans de Goede MODULE_PARM_DESC(rtw_tx_pwr_by_rate, "0:Disable, 1:Enable, 2: Depend on efuse"); 189554c0a3aSHans de Goede 190554c0a3aSHans de Goede static int netdev_close(struct net_device *pnetdev); 191554c0a3aSHans de Goede 19200d5865cSMarco Cesati static void loadparam(struct adapter *padapter, struct net_device *pnetdev) 193554c0a3aSHans de Goede { 194554c0a3aSHans de Goede struct registry_priv *registry_par = &padapter->registrypriv; 195554c0a3aSHans de Goede 196554c0a3aSHans de Goede registry_par->chip_version = (u8)rtw_chip_version; 197554c0a3aSHans de Goede registry_par->rfintfs = (u8)rtw_rfintfs; 198554c0a3aSHans de Goede registry_par->lbkmode = (u8)rtw_lbkmode; 199554c0a3aSHans de Goede /* registry_par->hci = (u8)hci; */ 200554c0a3aSHans de Goede registry_par->network_mode = (u8)rtw_network_mode; 201554c0a3aSHans de Goede 2026994aa43SFabio Aiuto memcpy(registry_par->ssid.ssid, "ANY", 3); 2036994aa43SFabio Aiuto registry_par->ssid.ssid_length = 3; 204554c0a3aSHans de Goede 205554c0a3aSHans de Goede registry_par->channel = (u8)rtw_channel; 206554c0a3aSHans de Goede registry_par->wireless_mode = (u8)rtw_wireless_mode; 207554c0a3aSHans de Goede 208554c0a3aSHans de Goede registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense; 209554c0a3aSHans de Goede registry_par->vcs_type = (u8)rtw_vcs_type; 210554c0a3aSHans de Goede registry_par->rts_thresh = (u16)rtw_rts_thresh; 211554c0a3aSHans de Goede registry_par->frag_thresh = (u16)rtw_frag_thresh; 212554c0a3aSHans de Goede registry_par->preamble = (u8)rtw_preamble; 213554c0a3aSHans de Goede registry_par->scan_mode = (u8)rtw_scan_mode; 214554c0a3aSHans de Goede registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr; 215554c0a3aSHans de Goede registry_par->soft_ap = (u8)rtw_soft_ap; 216554c0a3aSHans de Goede registry_par->smart_ps = (u8)rtw_smart_ps; 217554c0a3aSHans de Goede registry_par->check_fw_ps = (u8)rtw_check_fw_ps; 218554c0a3aSHans de Goede registry_par->power_mgnt = (u8)rtw_power_mgnt; 219554c0a3aSHans de Goede registry_par->ips_mode = (u8)rtw_ips_mode; 220554c0a3aSHans de Goede registry_par->radio_enable = (u8)rtw_radio_enable; 221554c0a3aSHans de Goede registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt; 222554c0a3aSHans de Goede registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt; 223554c0a3aSHans de Goede registry_par->busy_thresh = (u16)rtw_busy_thresh; 224554c0a3aSHans de Goede /* registry_par->qos_enable = (u8)rtw_qos_enable; */ 225554c0a3aSHans de Goede registry_par->ack_policy = (u8)rtw_ack_policy; 226554c0a3aSHans de Goede registry_par->software_encrypt = (u8)rtw_software_encrypt; 227554c0a3aSHans de Goede registry_par->software_decrypt = (u8)rtw_software_decrypt; 228554c0a3aSHans de Goede 229554c0a3aSHans de Goede registry_par->acm_method = (u8)rtw_acm_method; 230554c0a3aSHans de Goede registry_par->usb_rxagg_mode = (u8)rtw_usb_rxagg_mode; 231554c0a3aSHans de Goede 232554c0a3aSHans de Goede /* UAPSD */ 233554c0a3aSHans de Goede registry_par->wmm_enable = (u8)rtw_wmm_enable; 234554c0a3aSHans de Goede registry_par->uapsd_enable = (u8)rtw_uapsd_enable; 235554c0a3aSHans de Goede registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp; 236554c0a3aSHans de Goede registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en; 237554c0a3aSHans de Goede registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en; 238554c0a3aSHans de Goede registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en; 239554c0a3aSHans de Goede registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en; 240554c0a3aSHans de Goede 241554c0a3aSHans de Goede registry_par->ht_enable = (u8)rtw_ht_enable; 242554c0a3aSHans de Goede registry_par->bw_mode = (u8)rtw_bw_mode; 243554c0a3aSHans de Goede registry_par->ampdu_enable = (u8)rtw_ampdu_enable; 244554c0a3aSHans de Goede registry_par->rx_stbc = (u8)rtw_rx_stbc; 245554c0a3aSHans de Goede registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu; 246554c0a3aSHans de Goede registry_par->short_gi = (u8)rtw_short_gi; 247554c0a3aSHans de Goede registry_par->ldpc_cap = (u8)rtw_ldpc_cap; 248554c0a3aSHans de Goede registry_par->stbc_cap = (u8)rtw_stbc_cap; 249554c0a3aSHans de Goede registry_par->beamform_cap = (u8)rtw_beamform_cap; 250554c0a3aSHans de Goede 251554c0a3aSHans de Goede registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; 252554c0a3aSHans de Goede registry_par->rf_config = (u8)rtw_rf_config; 253554c0a3aSHans de Goede registry_par->low_power = (u8)rtw_low_power; 254554c0a3aSHans de Goede 255554c0a3aSHans de Goede 256554c0a3aSHans de Goede registry_par->wifi_spec = (u8)rtw_wifi_spec; 257554c0a3aSHans de Goede 258554c0a3aSHans de Goede registry_par->channel_plan = (u8)rtw_channel_plan; 259554c0a3aSHans de Goede 260554c0a3aSHans de Goede registry_par->ant_num = (s8)rtw_ant_num; 261554c0a3aSHans de Goede 262b739ea41SAastha Gupta registry_par->accept_addba_req = true; 263554c0a3aSHans de Goede 264554c0a3aSHans de Goede registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg; 265554c0a3aSHans de Goede registry_par->antdiv_type = (u8)rtw_antdiv_type; 266554c0a3aSHans de Goede 267554c0a3aSHans de Goede registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc; 268554c0a3aSHans de Goede 269554c0a3aSHans de Goede registry_par->max_roaming_times = (u8)rtw_max_roaming_times; 270554c0a3aSHans de Goede 271554c0a3aSHans de Goede registry_par->enable80211d = (u8)rtw_80211d; 272554c0a3aSHans de Goede 273554c0a3aSHans de Goede snprintf(registry_par->ifname, 16, "%s", ifname); 274554c0a3aSHans de Goede 275554c0a3aSHans de Goede registry_par->notch_filter = (u8)rtw_notch_filter; 276554c0a3aSHans de Goede 277554c0a3aSHans de Goede registry_par->RegEnableTxPowerLimit = (u8)rtw_tx_pwr_lmt_enable; 278554c0a3aSHans de Goede registry_par->RegEnableTxPowerByRate = (u8)rtw_tx_pwr_by_rate; 279554c0a3aSHans de Goede 280554c0a3aSHans de Goede registry_par->RegPowerBase = 14; 281554c0a3aSHans de Goede registry_par->TxBBSwing_2G = 0xFF; 282554c0a3aSHans de Goede registry_par->bEn_RFE = 1; 283554c0a3aSHans de Goede registry_par->RFE_Type = 64; 284554c0a3aSHans de Goede 285554c0a3aSHans de Goede registry_par->qos_opt_enable = (u8)rtw_qos_opt_enable; 286554c0a3aSHans de Goede 287554c0a3aSHans de Goede registry_par->hiq_filter = (u8)rtw_hiq_filter; 288554c0a3aSHans de Goede } 289554c0a3aSHans de Goede 290554c0a3aSHans de Goede static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) 291554c0a3aSHans de Goede { 29242a18f09SIvan Safonov struct adapter *padapter = rtw_netdev_priv(pnetdev); 293554c0a3aSHans de Goede struct sockaddr *addr = p; 294554c0a3aSHans de Goede 295e49fa0b7SJohn Oldman if (!padapter->bup) { 296554c0a3aSHans de Goede /* addr->sa_data[4], addr->sa_data[5]); */ 297554c0a3aSHans de Goede memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN); 298554c0a3aSHans de Goede /* memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN); */ 299554c0a3aSHans de Goede /* padapter->bset_hwaddr = true; */ 300554c0a3aSHans de Goede } 301554c0a3aSHans de Goede 302554c0a3aSHans de Goede return 0; 303554c0a3aSHans de Goede } 304554c0a3aSHans de Goede 305554c0a3aSHans de Goede static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) 306554c0a3aSHans de Goede { 30742a18f09SIvan Safonov struct adapter *padapter = rtw_netdev_priv(pnetdev); 308554c0a3aSHans de Goede struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 309554c0a3aSHans de Goede struct recv_priv *precvpriv = &(padapter->recvpriv); 310554c0a3aSHans de Goede 311554c0a3aSHans de Goede padapter->stats.tx_packets = pxmitpriv->tx_pkts;/* pxmitpriv->tx_pkts++; */ 312554c0a3aSHans de Goede padapter->stats.rx_packets = precvpriv->rx_pkts;/* precvpriv->rx_pkts++; */ 313554c0a3aSHans de Goede padapter->stats.tx_dropped = pxmitpriv->tx_drop; 314554c0a3aSHans de Goede padapter->stats.rx_dropped = precvpriv->rx_drop; 315554c0a3aSHans de Goede padapter->stats.tx_bytes = pxmitpriv->tx_bytes; 316554c0a3aSHans de Goede padapter->stats.rx_bytes = precvpriv->rx_bytes; 317554c0a3aSHans de Goede 318554c0a3aSHans de Goede return &padapter->stats; 319554c0a3aSHans de Goede } 320554c0a3aSHans de Goede 321554c0a3aSHans de Goede /* 322554c0a3aSHans de Goede * AC to queue mapping 323554c0a3aSHans de Goede * 324554c0a3aSHans de Goede * AC_VO -> queue 0 325554c0a3aSHans de Goede * AC_VI -> queue 1 326554c0a3aSHans de Goede * AC_BE -> queue 2 327554c0a3aSHans de Goede * AC_BK -> queue 3 328554c0a3aSHans de Goede */ 329554c0a3aSHans de Goede static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; 330554c0a3aSHans de Goede 331554c0a3aSHans de Goede /* Given a data frame determine the 802.1p/1d tag to use. */ 332554c0a3aSHans de Goede static unsigned int rtw_classify8021d(struct sk_buff *skb) 333554c0a3aSHans de Goede { 334554c0a3aSHans de Goede unsigned int dscp; 335554c0a3aSHans de Goede 336554c0a3aSHans de Goede /* skb->priority values from 256->263 are magic values to 337554c0a3aSHans de Goede * directly indicate a specific 802.1d priority. This is used 338554c0a3aSHans de Goede * to allow 802.1d priority to be passed directly in from VLAN 339554c0a3aSHans de Goede * tags, etc. 340554c0a3aSHans de Goede */ 341554c0a3aSHans de Goede if (skb->priority >= 256 && skb->priority <= 263) 342554c0a3aSHans de Goede return skb->priority - 256; 343554c0a3aSHans de Goede 344554c0a3aSHans de Goede switch (skb->protocol) { 345554c0a3aSHans de Goede case htons(ETH_P_IP): 346554c0a3aSHans de Goede dscp = ip_hdr(skb)->tos & 0xfc; 347554c0a3aSHans de Goede break; 348554c0a3aSHans de Goede default: 349554c0a3aSHans de Goede return 0; 350554c0a3aSHans de Goede } 351554c0a3aSHans de Goede 352554c0a3aSHans de Goede return dscp >> 5; 353554c0a3aSHans de Goede } 354554c0a3aSHans de Goede 355554c0a3aSHans de Goede 3564f49dec9SAlexander Duyck static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, 357a350ecceSPaolo Abeni struct net_device *sb_dev) 358554c0a3aSHans de Goede { 359554c0a3aSHans de Goede struct adapter *padapter = rtw_netdev_priv(dev); 360554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 361554c0a3aSHans de Goede 362554c0a3aSHans de Goede skb->priority = rtw_classify8021d(skb); 363554c0a3aSHans de Goede 364554c0a3aSHans de Goede if (pmlmepriv->acm_mask != 0) 365554c0a3aSHans de Goede skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority); 366554c0a3aSHans de Goede 367554c0a3aSHans de Goede return rtw_1d_to_queue[skb->priority]; 368554c0a3aSHans de Goede } 369554c0a3aSHans de Goede 370554c0a3aSHans de Goede u16 rtw_recv_select_queue(struct sk_buff *skb) 371554c0a3aSHans de Goede { 372554c0a3aSHans de Goede struct iphdr *piphdr; 373554c0a3aSHans de Goede unsigned int dscp; 374554c0a3aSHans de Goede __be16 eth_type; 375554c0a3aSHans de Goede u32 priority; 376554c0a3aSHans de Goede u8 *pdata = skb->data; 377554c0a3aSHans de Goede 378554c0a3aSHans de Goede memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); 379554c0a3aSHans de Goede 380554c0a3aSHans de Goede switch (be16_to_cpu(eth_type)) { 381554c0a3aSHans de Goede case ETH_P_IP: 382554c0a3aSHans de Goede 383554c0a3aSHans de Goede piphdr = (struct iphdr *)(pdata + ETH_HLEN); 384554c0a3aSHans de Goede 385554c0a3aSHans de Goede dscp = piphdr->tos & 0xfc; 386554c0a3aSHans de Goede 387554c0a3aSHans de Goede priority = dscp >> 5; 388554c0a3aSHans de Goede 389554c0a3aSHans de Goede break; 390554c0a3aSHans de Goede default: 391554c0a3aSHans de Goede priority = 0; 392554c0a3aSHans de Goede } 393554c0a3aSHans de Goede 394554c0a3aSHans de Goede return rtw_1d_to_queue[priority]; 395554c0a3aSHans de Goede } 396554c0a3aSHans de Goede 397554c0a3aSHans de Goede static int rtw_ndev_notifier_call(struct notifier_block *nb, unsigned long state, void *ptr) 398554c0a3aSHans de Goede { 399554c0a3aSHans de Goede struct net_device *dev = netdev_notifier_info_to_dev(ptr); 400554c0a3aSHans de Goede 401554c0a3aSHans de Goede if (dev->netdev_ops->ndo_do_ioctl != rtw_ioctl) 402554c0a3aSHans de Goede return NOTIFY_DONE; 403554c0a3aSHans de Goede 40479df841bSFabio Aiuto netdev_info(dev, FUNC_NDEV_FMT " state:%lu\n", FUNC_NDEV_ARG(dev), 40579df841bSFabio Aiuto state); 406554c0a3aSHans de Goede 407554c0a3aSHans de Goede return NOTIFY_DONE; 408554c0a3aSHans de Goede } 409554c0a3aSHans de Goede 410554c0a3aSHans de Goede static struct notifier_block rtw_ndev_notifier = { 411554c0a3aSHans de Goede .notifier_call = rtw_ndev_notifier_call, 412554c0a3aSHans de Goede }; 413554c0a3aSHans de Goede 414554c0a3aSHans de Goede int rtw_ndev_notifier_register(void) 415554c0a3aSHans de Goede { 416554c0a3aSHans de Goede return register_netdevice_notifier(&rtw_ndev_notifier); 417554c0a3aSHans de Goede } 418554c0a3aSHans de Goede 419554c0a3aSHans de Goede void rtw_ndev_notifier_unregister(void) 420554c0a3aSHans de Goede { 421554c0a3aSHans de Goede unregister_netdevice_notifier(&rtw_ndev_notifier); 422554c0a3aSHans de Goede } 423554c0a3aSHans de Goede 424554c0a3aSHans de Goede 425554c0a3aSHans de Goede static int rtw_ndev_init(struct net_device *dev) 426554c0a3aSHans de Goede { 427554c0a3aSHans de Goede struct adapter *adapter = rtw_netdev_priv(dev); 428554c0a3aSHans de Goede 42979df841bSFabio Aiuto netdev_dbg(dev, FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter)); 430554c0a3aSHans de Goede strncpy(adapter->old_ifname, dev->name, IFNAMSIZ); 431554c0a3aSHans de Goede 432554c0a3aSHans de Goede return 0; 433554c0a3aSHans de Goede } 434554c0a3aSHans de Goede 435554c0a3aSHans de Goede static void rtw_ndev_uninit(struct net_device *dev) 436554c0a3aSHans de Goede { 437554c0a3aSHans de Goede struct adapter *adapter = rtw_netdev_priv(dev); 438554c0a3aSHans de Goede 43979df841bSFabio Aiuto netdev_dbg(dev, FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter)); 440554c0a3aSHans de Goede } 441554c0a3aSHans de Goede 442554c0a3aSHans de Goede static const struct net_device_ops rtw_netdev_ops = { 443554c0a3aSHans de Goede .ndo_init = rtw_ndev_init, 444554c0a3aSHans de Goede .ndo_uninit = rtw_ndev_uninit, 445554c0a3aSHans de Goede .ndo_open = netdev_open, 446554c0a3aSHans de Goede .ndo_stop = netdev_close, 447554c0a3aSHans de Goede .ndo_start_xmit = rtw_xmit_entry, 448554c0a3aSHans de Goede .ndo_select_queue = rtw_select_queue, 449554c0a3aSHans de Goede .ndo_set_mac_address = rtw_net_set_mac_address, 450554c0a3aSHans de Goede .ndo_get_stats = rtw_net_get_stats, 451554c0a3aSHans de Goede .ndo_do_ioctl = rtw_ioctl, 452554c0a3aSHans de Goede }; 453554c0a3aSHans de Goede 454554c0a3aSHans de Goede int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) 455554c0a3aSHans de Goede { 456554c0a3aSHans de Goede if (dev_alloc_name(pnetdev, ifname) < 0) { 457554c0a3aSHans de Goede pr_err("dev_alloc_name, fail for %s\n", ifname); 458554c0a3aSHans de Goede return 1; 459554c0a3aSHans de Goede } 460554c0a3aSHans de Goede netif_carrier_off(pnetdev); 461554c0a3aSHans de Goede /* rtw_netif_stop_queue(pnetdev); */ 462554c0a3aSHans de Goede 463554c0a3aSHans de Goede return 0; 464554c0a3aSHans de Goede } 465554c0a3aSHans de Goede 466554c0a3aSHans de Goede struct net_device *rtw_init_netdev(struct adapter *old_padapter) 467554c0a3aSHans de Goede { 468554c0a3aSHans de Goede struct adapter *padapter; 469554c0a3aSHans de Goede struct net_device *pnetdev; 470554c0a3aSHans de Goede 47134557e23SIzabela Bakollari if (old_padapter) 472554c0a3aSHans de Goede pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter); 473554c0a3aSHans de Goede else 474554c0a3aSHans de Goede pnetdev = rtw_alloc_etherdev(sizeof(struct adapter)); 475554c0a3aSHans de Goede 476554c0a3aSHans de Goede pr_info("pnetdev = %p\n", pnetdev); 477554c0a3aSHans de Goede if (!pnetdev) 478554c0a3aSHans de Goede return NULL; 479554c0a3aSHans de Goede 480554c0a3aSHans de Goede padapter = rtw_netdev_priv(pnetdev); 481554c0a3aSHans de Goede padapter->pnetdev = pnetdev; 482554c0a3aSHans de Goede 483554c0a3aSHans de Goede /* pnetdev->init = NULL; */ 484554c0a3aSHans de Goede 485554c0a3aSHans de Goede pnetdev->netdev_ops = &rtw_netdev_ops; 486554c0a3aSHans de Goede 487554c0a3aSHans de Goede /* pnetdev->tx_timeout = NULL; */ 488554c0a3aSHans de Goede pnetdev->watchdog_timeo = HZ * 3; /* 3 second timeout */ 489554c0a3aSHans de Goede pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; 490554c0a3aSHans de Goede 491554c0a3aSHans de Goede /* step 2. */ 492554c0a3aSHans de Goede loadparam(padapter, pnetdev); 493554c0a3aSHans de Goede 494554c0a3aSHans de Goede return pnetdev; 495554c0a3aSHans de Goede } 496554c0a3aSHans de Goede 497554c0a3aSHans de Goede void rtw_unregister_netdevs(struct dvobj_priv *dvobj) 498554c0a3aSHans de Goede { 499554c0a3aSHans de Goede struct adapter *padapter = NULL; 500554c0a3aSHans de Goede struct net_device *pnetdev = NULL; 501554c0a3aSHans de Goede 502554c0a3aSHans de Goede padapter = dvobj->padapters; 503554c0a3aSHans de Goede 504554c0a3aSHans de Goede if (padapter == NULL) 505554c0a3aSHans de Goede return; 506554c0a3aSHans de Goede 507554c0a3aSHans de Goede pnetdev = padapter->pnetdev; 508554c0a3aSHans de Goede 509554c0a3aSHans de Goede if ((padapter->DriverState != DRIVER_DISAPPEAR) && pnetdev) 510554c0a3aSHans de Goede unregister_netdev(pnetdev); /* will call netdev_close() */ 511554c0a3aSHans de Goede rtw_wdev_unregister(padapter->rtw_wdev); 512554c0a3aSHans de Goede } 513554c0a3aSHans de Goede 514554c0a3aSHans de Goede u32 rtw_start_drv_threads(struct adapter *padapter) 515554c0a3aSHans de Goede { 516554c0a3aSHans de Goede u32 _status = _SUCCESS; 517554c0a3aSHans de Goede 518554c0a3aSHans de Goede padapter->xmitThread = kthread_run(rtw_xmit_thread, padapter, "RTW_XMIT_THREAD"); 519554c0a3aSHans de Goede if (IS_ERR(padapter->xmitThread)) 520554c0a3aSHans de Goede _status = _FAIL; 521554c0a3aSHans de Goede 522554c0a3aSHans de Goede padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); 523554c0a3aSHans de Goede if (IS_ERR(padapter->cmdThread)) 524554c0a3aSHans de Goede _status = _FAIL; 525554c0a3aSHans de Goede else 52609a8ea34SArnd Bergmann wait_for_completion(&padapter->cmdpriv.terminate_cmdthread_comp); /* wait for cmd_thread to run */ 527554c0a3aSHans de Goede 528554c0a3aSHans de Goede rtw_hal_start_thread(padapter); 529554c0a3aSHans de Goede return _status; 530554c0a3aSHans de Goede } 531554c0a3aSHans de Goede 532554c0a3aSHans de Goede void rtw_stop_drv_threads(struct adapter *padapter) 533554c0a3aSHans de Goede { 534554c0a3aSHans de Goede rtw_stop_cmd_thread(padapter); 535554c0a3aSHans de Goede 536554c0a3aSHans de Goede /* Below is to termindate tx_thread... */ 53709a8ea34SArnd Bergmann complete(&padapter->xmitpriv.xmit_comp); 53809a8ea34SArnd Bergmann wait_for_completion(&padapter->xmitpriv.terminate_xmitthread_comp); 539554c0a3aSHans de Goede 540554c0a3aSHans de Goede rtw_hal_stop_thread(padapter); 541554c0a3aSHans de Goede } 542554c0a3aSHans de Goede 54347c48c9eSShobhit Kukreti static void rtw_init_default_value(struct adapter *padapter) 544554c0a3aSHans de Goede { 545554c0a3aSHans de Goede struct registry_priv *pregistrypriv = &padapter->registrypriv; 546554c0a3aSHans de Goede struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 547554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 548554c0a3aSHans de Goede struct security_priv *psecuritypriv = &padapter->securitypriv; 549554c0a3aSHans de Goede 550554c0a3aSHans de Goede /* xmit_priv */ 551554c0a3aSHans de Goede pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; 552554c0a3aSHans de Goede pxmitpriv->vcs = pregistrypriv->vcs_type; 553554c0a3aSHans de Goede pxmitpriv->vcs_type = pregistrypriv->vcs_type; 554554c0a3aSHans de Goede /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */ 555554c0a3aSHans de Goede pxmitpriv->frag_len = pregistrypriv->frag_thresh; 556554c0a3aSHans de Goede 557554c0a3aSHans de Goede /* recv_priv */ 558554c0a3aSHans de Goede 559554c0a3aSHans de Goede /* mlme_priv */ 560554c0a3aSHans de Goede pmlmepriv->scan_mode = SCAN_ACTIVE; 561554c0a3aSHans de Goede 562554c0a3aSHans de Goede /* qos_priv */ 563554c0a3aSHans de Goede /* pmlmepriv->qospriv.qos_option = pregistrypriv->wmm_enable; */ 564554c0a3aSHans de Goede 565554c0a3aSHans de Goede /* ht_priv */ 566554c0a3aSHans de Goede pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */ 567554c0a3aSHans de Goede 568554c0a3aSHans de Goede /* security_priv */ 569554c0a3aSHans de Goede /* rtw_get_encrypt_decrypt_from_registrypriv(padapter); */ 570554c0a3aSHans de Goede psecuritypriv->binstallGrpkey = _FAIL; 571554c0a3aSHans de Goede psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; 572554c0a3aSHans de Goede psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; 573554c0a3aSHans de Goede 574554c0a3aSHans de Goede psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */ 575554c0a3aSHans de Goede psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; 576554c0a3aSHans de Goede 577554c0a3aSHans de Goede psecuritypriv->dot11PrivacyKeyIndex = 0; 578554c0a3aSHans de Goede 579554c0a3aSHans de Goede psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; 580554c0a3aSHans de Goede psecuritypriv->dot118021XGrpKeyid = 1; 581554c0a3aSHans de Goede 582554c0a3aSHans de Goede psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; 583554c0a3aSHans de Goede psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; 584554c0a3aSHans de Goede 585554c0a3aSHans de Goede /* registry_priv */ 586554c0a3aSHans de Goede rtw_init_registrypriv_dev_network(padapter); 587554c0a3aSHans de Goede rtw_update_registrypriv_dev_network(padapter); 588554c0a3aSHans de Goede 589554c0a3aSHans de Goede /* hal_priv */ 590554c0a3aSHans de Goede rtw_hal_def_value_init(padapter); 591554c0a3aSHans de Goede 592554c0a3aSHans de Goede /* misc. */ 593554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_RX_BIT); 594554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_TX_BIT); 595554c0a3aSHans de Goede padapter->bLinkInfoDump = 0; 596554c0a3aSHans de Goede padapter->bNotifyChannelChange = 0; 597554c0a3aSHans de Goede 598554c0a3aSHans de Goede /* for debug purpose */ 599554c0a3aSHans de Goede padapter->fix_rate = 0xFF; 600554c0a3aSHans de Goede padapter->driver_ampdu_spacing = 0xFF; 601554c0a3aSHans de Goede padapter->driver_rx_ampdu_factor = 0xFF; 602554c0a3aSHans de Goede 603554c0a3aSHans de Goede } 604554c0a3aSHans de Goede 605554c0a3aSHans de Goede struct dvobj_priv *devobj_init(void) 606554c0a3aSHans de Goede { 607554c0a3aSHans de Goede struct dvobj_priv *pdvobj = NULL; 608554c0a3aSHans de Goede 6092ef2b7c2SJoe Perches pdvobj = rtw_zmalloc(sizeof(*pdvobj)); 6102ef2b7c2SJoe Perches if (pdvobj == NULL) 611554c0a3aSHans de Goede return NULL; 612554c0a3aSHans de Goede 613554c0a3aSHans de Goede mutex_init(&pdvobj->hw_init_mutex); 614554c0a3aSHans de Goede mutex_init(&pdvobj->h2c_fwcmd_mutex); 615554c0a3aSHans de Goede mutex_init(&pdvobj->setch_mutex); 616554c0a3aSHans de Goede mutex_init(&pdvobj->setbw_mutex); 617554c0a3aSHans de Goede 618554c0a3aSHans de Goede spin_lock_init(&pdvobj->lock); 619554c0a3aSHans de Goede 620554c0a3aSHans de Goede pdvobj->macid[1] = true; /* macid = 1 for bc/mc stainfo */ 621554c0a3aSHans de Goede 622554c0a3aSHans de Goede pdvobj->processing_dev_remove = false; 623554c0a3aSHans de Goede 624554c0a3aSHans de Goede atomic_set(&pdvobj->disable_func, 0); 625554c0a3aSHans de Goede 626554c0a3aSHans de Goede spin_lock_init(&pdvobj->cam_ctl.lock); 627554c0a3aSHans de Goede 628554c0a3aSHans de Goede return pdvobj; 629554c0a3aSHans de Goede } 630554c0a3aSHans de Goede 631554c0a3aSHans de Goede void devobj_deinit(struct dvobj_priv *pdvobj) 632554c0a3aSHans de Goede { 633554c0a3aSHans de Goede if (!pdvobj) 634554c0a3aSHans de Goede return; 635554c0a3aSHans de Goede 636554c0a3aSHans de Goede mutex_destroy(&pdvobj->hw_init_mutex); 637554c0a3aSHans de Goede mutex_destroy(&pdvobj->h2c_fwcmd_mutex); 638554c0a3aSHans de Goede mutex_destroy(&pdvobj->setch_mutex); 639554c0a3aSHans de Goede mutex_destroy(&pdvobj->setbw_mutex); 640554c0a3aSHans de Goede 641c8d5fa75SMeghana Madhyastha kfree(pdvobj); 642554c0a3aSHans de Goede } 643554c0a3aSHans de Goede 644864e69d0SShobhit Kukreti void rtw_reset_drv_sw(struct adapter *padapter) 645554c0a3aSHans de Goede { 646554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 647554c0a3aSHans de Goede struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); 648554c0a3aSHans de Goede 649554c0a3aSHans de Goede /* hal_priv */ 650554c0a3aSHans de Goede if (is_primary_adapter(padapter)) 651554c0a3aSHans de Goede rtw_hal_def_value_init(padapter); 652554c0a3aSHans de Goede 653554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_RX_BIT); 654554c0a3aSHans de Goede RTW_ENABLE_FUNC(padapter, DF_TX_BIT); 655554c0a3aSHans de Goede padapter->bLinkInfoDump = 0; 656554c0a3aSHans de Goede 657554c0a3aSHans de Goede padapter->xmitpriv.tx_pkts = 0; 658554c0a3aSHans de Goede padapter->recvpriv.rx_pkts = 0; 659554c0a3aSHans de Goede 660554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bBusyTraffic = false; 661554c0a3aSHans de Goede 662554c0a3aSHans de Goede /* pmlmepriv->LinkDetectInfo.TrafficBusyState = false; */ 663554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; 664554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; 665554c0a3aSHans de Goede 666554c0a3aSHans de Goede _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING); 667554c0a3aSHans de Goede 668554c0a3aSHans de Goede pwrctrlpriv->pwr_state_check_cnts = 0; 669554c0a3aSHans de Goede 670554c0a3aSHans de Goede /* mlmeextpriv */ 671554c0a3aSHans de Goede padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE; 672554c0a3aSHans de Goede 673554c0a3aSHans de Goede rtw_set_signal_stat_timer(&padapter->recvpriv); 674554c0a3aSHans de Goede 675554c0a3aSHans de Goede } 676554c0a3aSHans de Goede 677554c0a3aSHans de Goede 678554c0a3aSHans de Goede u8 rtw_init_drv_sw(struct adapter *padapter) 679554c0a3aSHans de Goede { 680554c0a3aSHans de Goede u8 ret8 = _SUCCESS; 681554c0a3aSHans de Goede 68247c48c9eSShobhit Kukreti rtw_init_default_value(padapter); 683554c0a3aSHans de Goede 684554c0a3aSHans de Goede rtw_init_hal_com_default_value(padapter); 685554c0a3aSHans de Goede 686cfd587d6SMadhumitha Prabakaran if (rtw_init_cmd_priv(&padapter->cmdpriv)) { 687554c0a3aSHans de Goede ret8 = _FAIL; 688554c0a3aSHans de Goede goto exit; 689554c0a3aSHans de Goede } 690554c0a3aSHans de Goede 691554c0a3aSHans de Goede padapter->cmdpriv.padapter = padapter; 692554c0a3aSHans de Goede 693cfd587d6SMadhumitha Prabakaran if (rtw_init_evt_priv(&padapter->evtpriv)) { 694554c0a3aSHans de Goede ret8 = _FAIL; 695554c0a3aSHans de Goede goto exit; 696554c0a3aSHans de Goede } 697554c0a3aSHans de Goede 698554c0a3aSHans de Goede 699554c0a3aSHans de Goede if (rtw_init_mlme_priv(padapter) == _FAIL) { 700554c0a3aSHans de Goede ret8 = _FAIL; 701554c0a3aSHans de Goede goto exit; 702554c0a3aSHans de Goede } 703554c0a3aSHans de Goede 704067756acSHariprasad Kelam init_mlme_ext_priv(padapter); 705554c0a3aSHans de Goede 706554c0a3aSHans de Goede if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { 707554c0a3aSHans de Goede ret8 = _FAIL; 708554c0a3aSHans de Goede goto exit; 709554c0a3aSHans de Goede } 710554c0a3aSHans de Goede 711554c0a3aSHans de Goede if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) { 712554c0a3aSHans de Goede ret8 = _FAIL; 713554c0a3aSHans de Goede goto exit; 714554c0a3aSHans de Goede } 715554c0a3aSHans de Goede /* add for CONFIG_IEEE80211W, none 11w also can use */ 716554c0a3aSHans de Goede spin_lock_init(&padapter->security_key_mutex); 717554c0a3aSHans de Goede 718554c0a3aSHans de Goede /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ 719554c0a3aSHans de Goede /* memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); */ 720554c0a3aSHans de Goede 721554c0a3aSHans de Goede if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) { 722554c0a3aSHans de Goede ret8 = _FAIL; 723554c0a3aSHans de Goede goto exit; 724554c0a3aSHans de Goede } 725554c0a3aSHans de Goede 726554c0a3aSHans de Goede padapter->stapriv.padapter = padapter; 727554c0a3aSHans de Goede padapter->setband = GHZ24_50; 728554c0a3aSHans de Goede padapter->fix_rate = 0xFF; 729554c0a3aSHans de Goede rtw_init_bcmc_stainfo(padapter); 730554c0a3aSHans de Goede 731554c0a3aSHans de Goede rtw_init_pwrctrl_priv(padapter); 732554c0a3aSHans de Goede 733554c0a3aSHans de Goede rtw_hal_dm_init(padapter); 734554c0a3aSHans de Goede 735554c0a3aSHans de Goede exit: 736554c0a3aSHans de Goede 737554c0a3aSHans de Goede return ret8; 738554c0a3aSHans de Goede } 739554c0a3aSHans de Goede 740554c0a3aSHans de Goede void rtw_cancel_all_timer(struct adapter *padapter) 741554c0a3aSHans de Goede { 742554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.assoc_timer); 743554c0a3aSHans de Goede 744554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.scan_to_timer); 745554c0a3aSHans de Goede 746554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer); 747554c0a3aSHans de Goede 748554c0a3aSHans de Goede del_timer_sync(&(adapter_to_pwrctl(padapter)->pwr_state_check_timer)); 749554c0a3aSHans de Goede 750554c0a3aSHans de Goede del_timer_sync(&padapter->mlmepriv.set_scan_deny_timer); 751554c0a3aSHans de Goede rtw_clear_scan_deny(padapter); 752554c0a3aSHans de Goede 753554c0a3aSHans de Goede del_timer_sync(&padapter->recvpriv.signal_stat_timer); 754554c0a3aSHans de Goede 755554c0a3aSHans de Goede /* cancel dm timer */ 756554c0a3aSHans de Goede rtw_hal_dm_deinit(padapter); 757554c0a3aSHans de Goede } 758554c0a3aSHans de Goede 759554c0a3aSHans de Goede u8 rtw_free_drv_sw(struct adapter *padapter) 760554c0a3aSHans de Goede { 761554c0a3aSHans de Goede free_mlme_ext_priv(&padapter->mlmeextpriv); 762554c0a3aSHans de Goede 763554c0a3aSHans de Goede rtw_free_cmd_priv(&padapter->cmdpriv); 764554c0a3aSHans de Goede 765554c0a3aSHans de Goede rtw_free_evt_priv(&padapter->evtpriv); 766554c0a3aSHans de Goede 767554c0a3aSHans de Goede rtw_free_mlme_priv(&padapter->mlmepriv); 768554c0a3aSHans de Goede 769554c0a3aSHans de Goede /* free_io_queue(padapter); */ 770554c0a3aSHans de Goede 771554c0a3aSHans de Goede _rtw_free_xmit_priv(&padapter->xmitpriv); 772554c0a3aSHans de Goede 773554c0a3aSHans de Goede _rtw_free_sta_priv(&padapter->stapriv); /* will free bcmc_stainfo here */ 774554c0a3aSHans de Goede 775554c0a3aSHans de Goede _rtw_free_recv_priv(&padapter->recvpriv); 776554c0a3aSHans de Goede 777554c0a3aSHans de Goede rtw_free_pwrctrl_priv(padapter); 778554c0a3aSHans de Goede 779554c0a3aSHans de Goede /* kfree((void *)padapter); */ 780554c0a3aSHans de Goede 781554c0a3aSHans de Goede rtw_hal_free_data(padapter); 782554c0a3aSHans de Goede 783554c0a3aSHans de Goede /* free the old_pnetdev */ 784554c0a3aSHans de Goede if (padapter->rereg_nd_name_priv.old_pnetdev) { 785554c0a3aSHans de Goede free_netdev(padapter->rereg_nd_name_priv.old_pnetdev); 786554c0a3aSHans de Goede padapter->rereg_nd_name_priv.old_pnetdev = NULL; 787554c0a3aSHans de Goede } 788554c0a3aSHans de Goede 789554c0a3aSHans de Goede /* clear pbuddystruct adapter to avoid access wrong pointer. */ 79034557e23SIzabela Bakollari if (padapter->pbuddy_adapter) 791554c0a3aSHans de Goede padapter->pbuddy_adapter->pbuddy_adapter = NULL; 792554c0a3aSHans de Goede 793554c0a3aSHans de Goede return _SUCCESS; 794554c0a3aSHans de Goede } 795554c0a3aSHans de Goede 796554c0a3aSHans de Goede static int _rtw_drv_register_netdev(struct adapter *padapter, char *name) 797554c0a3aSHans de Goede { 798554c0a3aSHans de Goede int ret = _SUCCESS; 799554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 800554c0a3aSHans de Goede 801554c0a3aSHans de Goede /* alloc netdev name */ 802554c0a3aSHans de Goede if (rtw_init_netdev_name(pnetdev, name)) 803554c0a3aSHans de Goede return _FAIL; 804554c0a3aSHans de Goede 805554c0a3aSHans de Goede memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); 806554c0a3aSHans de Goede 807554c0a3aSHans de Goede /* Tell the network stack we exist */ 808554c0a3aSHans de Goede if (register_netdev(pnetdev) != 0) { 809554c0a3aSHans de Goede ret = _FAIL; 810554c0a3aSHans de Goede goto error_register_netdev; 811554c0a3aSHans de Goede } 812554c0a3aSHans de Goede 813554c0a3aSHans de Goede return ret; 814554c0a3aSHans de Goede 815554c0a3aSHans de Goede error_register_netdev: 816554c0a3aSHans de Goede 817554c0a3aSHans de Goede rtw_free_drv_sw(padapter); 818554c0a3aSHans de Goede 819554c0a3aSHans de Goede rtw_free_netdev(pnetdev); 820554c0a3aSHans de Goede 821554c0a3aSHans de Goede return ret; 822554c0a3aSHans de Goede } 823554c0a3aSHans de Goede 824554c0a3aSHans de Goede int rtw_drv_register_netdev(struct adapter *if1) 825554c0a3aSHans de Goede { 826554c0a3aSHans de Goede struct dvobj_priv *dvobj = if1->dvobj; 827554c0a3aSHans de Goede struct adapter *padapter = dvobj->padapters; 828554c0a3aSHans de Goede char *name = if1->registrypriv.ifname; 829554c0a3aSHans de Goede 830554c0a3aSHans de Goede return _rtw_drv_register_netdev(padapter, name); 831554c0a3aSHans de Goede } 832554c0a3aSHans de Goede 833d5e5f6d3SFabio Aiuto static int _netdev_open(struct net_device *pnetdev) 834554c0a3aSHans de Goede { 835554c0a3aSHans de Goede uint status; 83642a18f09SIvan Safonov struct adapter *padapter = rtw_netdev_priv(pnetdev); 837554c0a3aSHans de Goede struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); 838554c0a3aSHans de Goede 839554c0a3aSHans de Goede padapter->netif_up = true; 840554c0a3aSHans de Goede 841e49fa0b7SJohn Oldman if (pwrctrlpriv->ps_flag) { 842554c0a3aSHans de Goede padapter->net_closed = false; 843554c0a3aSHans de Goede goto netdev_open_normal_process; 844554c0a3aSHans de Goede } 845554c0a3aSHans de Goede 846e49fa0b7SJohn Oldman if (!padapter->bup) { 847554c0a3aSHans de Goede padapter->bDriverStopped = false; 848554c0a3aSHans de Goede padapter->bSurpriseRemoved = false; 849554c0a3aSHans de Goede padapter->bCardDisableWOHSM = false; 850554c0a3aSHans de Goede 851554c0a3aSHans de Goede status = rtw_hal_init(padapter); 8520b0029edSFabio Aiuto if (status == _FAIL) 853554c0a3aSHans de Goede goto netdev_open_error; 854554c0a3aSHans de Goede 855554c0a3aSHans de Goede status = rtw_start_drv_threads(padapter); 856709c8e49SFabio Aiuto if (status == _FAIL) 857554c0a3aSHans de Goede goto netdev_open_error; 858554c0a3aSHans de Goede 859554c0a3aSHans de Goede if (padapter->intf_start) 860554c0a3aSHans de Goede padapter->intf_start(padapter); 861554c0a3aSHans de Goede 862554c0a3aSHans de Goede rtw_cfg80211_init_wiphy(padapter); 863554c0a3aSHans de Goede 864554c0a3aSHans de Goede padapter->bup = true; 865554c0a3aSHans de Goede pwrctrlpriv->bips_processing = false; 866554c0a3aSHans de Goede } 867554c0a3aSHans de Goede padapter->net_closed = false; 868554c0a3aSHans de Goede 869554c0a3aSHans de Goede _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); 870554c0a3aSHans de Goede 871554c0a3aSHans de Goede if (!rtw_netif_queue_stopped(pnetdev)) 872554c0a3aSHans de Goede rtw_netif_start_queue(pnetdev); 873554c0a3aSHans de Goede else 874554c0a3aSHans de Goede rtw_netif_wake_queue(pnetdev); 875554c0a3aSHans de Goede 876554c0a3aSHans de Goede netdev_open_normal_process: 877554c0a3aSHans de Goede 878554c0a3aSHans de Goede return 0; 879554c0a3aSHans de Goede 880554c0a3aSHans de Goede netdev_open_error: 881554c0a3aSHans de Goede 882554c0a3aSHans de Goede padapter->bup = false; 883554c0a3aSHans de Goede 884554c0a3aSHans de Goede netif_carrier_off(pnetdev); 885554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 886554c0a3aSHans de Goede 887554c0a3aSHans de Goede return (-1); 888554c0a3aSHans de Goede } 889554c0a3aSHans de Goede 890554c0a3aSHans de Goede int netdev_open(struct net_device *pnetdev) 891554c0a3aSHans de Goede { 892554c0a3aSHans de Goede int ret; 89342a18f09SIvan Safonov struct adapter *padapter = rtw_netdev_priv(pnetdev); 894554c0a3aSHans de Goede struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); 895554c0a3aSHans de Goede 896709c8e49SFabio Aiuto if (pwrctrlpriv->bInSuspend) 897554c0a3aSHans de Goede return 0; 898554c0a3aSHans de Goede 899554c0a3aSHans de Goede if (mutex_lock_interruptible(&(adapter_to_dvobj(padapter)->hw_init_mutex))) 900554c0a3aSHans de Goede return -1; 901554c0a3aSHans de Goede 902554c0a3aSHans de Goede ret = _netdev_open(pnetdev); 903554c0a3aSHans de Goede mutex_unlock(&(adapter_to_dvobj(padapter)->hw_init_mutex)); 904554c0a3aSHans de Goede 905554c0a3aSHans de Goede return ret; 906554c0a3aSHans de Goede } 907554c0a3aSHans de Goede 908554c0a3aSHans de Goede static int ips_netdrv_open(struct adapter *padapter) 909554c0a3aSHans de Goede { 910554c0a3aSHans de Goede int status = _SUCCESS; 911554c0a3aSHans de Goede /* struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); */ 912554c0a3aSHans de Goede 913554c0a3aSHans de Goede padapter->net_closed = false; 914554c0a3aSHans de Goede 915554c0a3aSHans de Goede padapter->bDriverStopped = false; 916554c0a3aSHans de Goede padapter->bCardDisableWOHSM = false; 917554c0a3aSHans de Goede /* padapter->bup = true; */ 918554c0a3aSHans de Goede 919554c0a3aSHans de Goede status = rtw_hal_init(padapter); 9200b0029edSFabio Aiuto if (status == _FAIL) 921554c0a3aSHans de Goede goto netdev_open_error; 922554c0a3aSHans de Goede 923554c0a3aSHans de Goede if (padapter->intf_start) 924554c0a3aSHans de Goede padapter->intf_start(padapter); 925554c0a3aSHans de Goede 926554c0a3aSHans de Goede _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); 927554c0a3aSHans de Goede 928554c0a3aSHans de Goede return _SUCCESS; 929554c0a3aSHans de Goede 930554c0a3aSHans de Goede netdev_open_error: 931554c0a3aSHans de Goede 932554c0a3aSHans de Goede return _FAIL; 933554c0a3aSHans de Goede } 934554c0a3aSHans de Goede 935554c0a3aSHans de Goede 936554c0a3aSHans de Goede int rtw_ips_pwr_up(struct adapter *padapter) 937554c0a3aSHans de Goede { 938554c0a3aSHans de Goede int result; 939554c0a3aSHans de Goede 940554c0a3aSHans de Goede result = ips_netdrv_open(padapter); 941554c0a3aSHans de Goede 942554c0a3aSHans de Goede return result; 943554c0a3aSHans de Goede } 944554c0a3aSHans de Goede 945554c0a3aSHans de Goede void rtw_ips_pwr_down(struct adapter *padapter) 946554c0a3aSHans de Goede { 947554c0a3aSHans de Goede padapter->bCardDisableWOHSM = true; 948554c0a3aSHans de Goede padapter->net_closed = true; 949554c0a3aSHans de Goede 950554c0a3aSHans de Goede rtw_ips_dev_unload(padapter); 951554c0a3aSHans de Goede padapter->bCardDisableWOHSM = false; 952554c0a3aSHans de Goede } 953554c0a3aSHans de Goede 954554c0a3aSHans de Goede void rtw_ips_dev_unload(struct adapter *padapter) 955554c0a3aSHans de Goede { 956554c0a3aSHans de Goede 957e49fa0b7SJohn Oldman if (!padapter->bSurpriseRemoved) 958554c0a3aSHans de Goede rtw_hal_deinit(padapter); 959554c0a3aSHans de Goede } 960554c0a3aSHans de Goede 961554c0a3aSHans de Goede static int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) 962554c0a3aSHans de Goede { 963554c0a3aSHans de Goede int status = -1; 964554c0a3aSHans de Goede 96542a18f09SIvan Safonov struct adapter *padapter = rtw_netdev_priv(pnetdev); 966554c0a3aSHans de Goede 967e49fa0b7SJohn Oldman if (bnormal) { 968554c0a3aSHans de Goede if (mutex_lock_interruptible(&(adapter_to_dvobj(padapter)->hw_init_mutex)) == 0) { 969554c0a3aSHans de Goede status = _netdev_open(pnetdev); 970554c0a3aSHans de Goede mutex_unlock(&(adapter_to_dvobj(padapter)->hw_init_mutex)); 971554c0a3aSHans de Goede } 972addf21eaSJohn Oldman } else { 973554c0a3aSHans de Goede status = (_SUCCESS == ips_netdrv_open(padapter)) ? (0) : (-1); 974addf21eaSJohn Oldman } 975554c0a3aSHans de Goede 976554c0a3aSHans de Goede return status; 977554c0a3aSHans de Goede } 978554c0a3aSHans de Goede 979554c0a3aSHans de Goede static int netdev_close(struct net_device *pnetdev) 980554c0a3aSHans de Goede { 98142a18f09SIvan Safonov struct adapter *padapter = rtw_netdev_priv(pnetdev); 982554c0a3aSHans de Goede struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); 983554c0a3aSHans de Goede 984e49fa0b7SJohn Oldman if (pwrctl->bInternalAutoSuspend) { 985554c0a3aSHans de Goede /* rtw_pwr_wakeup(padapter); */ 986554c0a3aSHans de Goede if (pwrctl->rf_pwrstate == rf_off) 987554c0a3aSHans de Goede pwrctl->ps_flag = true; 988554c0a3aSHans de Goede } 989554c0a3aSHans de Goede padapter->net_closed = true; 990554c0a3aSHans de Goede padapter->netif_up = false; 991554c0a3aSHans de Goede 992554c0a3aSHans de Goede /*if (!padapter->hw_init_completed) 993554c0a3aSHans de Goede { 994554c0a3aSHans de Goede 995554c0a3aSHans de Goede padapter->bDriverStopped = true; 996554c0a3aSHans de Goede 997554c0a3aSHans de Goede rtw_dev_unload(padapter); 998554c0a3aSHans de Goede } 999554c0a3aSHans de Goede else*/ 1000554c0a3aSHans de Goede if (pwrctl->rf_pwrstate == rf_on) { 1001554c0a3aSHans de Goede /* s1. */ 1002ffd3c648SHarsha Sharma if (pnetdev) { 1003554c0a3aSHans de Goede if (!rtw_netif_queue_stopped(pnetdev)) 1004554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 1005554c0a3aSHans de Goede } 1006554c0a3aSHans de Goede 1007554c0a3aSHans de Goede /* s2. */ 1008554c0a3aSHans de Goede LeaveAllPowerSaveMode(padapter); 1009554c0a3aSHans de Goede rtw_disassoc_cmd(padapter, 500, false); 1010554c0a3aSHans de Goede /* s2-2. indicate disconnect to os */ 1011554c0a3aSHans de Goede rtw_indicate_disconnect(padapter); 1012554c0a3aSHans de Goede /* s2-3. */ 1013554c0a3aSHans de Goede rtw_free_assoc_resources(padapter, 1); 1014554c0a3aSHans de Goede /* s2-4. */ 1015554c0a3aSHans de Goede rtw_free_network_queue(padapter, true); 1016554c0a3aSHans de Goede } 1017554c0a3aSHans de Goede 1018554c0a3aSHans de Goede rtw_scan_abort(padapter); 1019554c0a3aSHans de Goede adapter_wdev_data(padapter)->bandroid_scan = false; 1020554c0a3aSHans de Goede 1021554c0a3aSHans de Goede return 0; 1022554c0a3aSHans de Goede } 1023554c0a3aSHans de Goede 1024554c0a3aSHans de Goede void rtw_ndev_destructor(struct net_device *ndev) 1025554c0a3aSHans de Goede { 1026a30b30f0SNachammai Karuppiah kfree(ndev->ieee80211_ptr); 1027554c0a3aSHans de Goede } 1028554c0a3aSHans de Goede 1029554c0a3aSHans de Goede void rtw_dev_unload(struct adapter *padapter) 1030554c0a3aSHans de Goede { 1031554c0a3aSHans de Goede struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); 1032554c0a3aSHans de Goede struct dvobj_priv *pobjpriv = padapter->dvobj; 1033554c0a3aSHans de Goede struct debug_priv *pdbgpriv = &pobjpriv->drv_dbg; 1034554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1035554c0a3aSHans de Goede u8 cnt = 0; 1036554c0a3aSHans de Goede 1037e49fa0b7SJohn Oldman if (padapter->bup) { 1038554c0a3aSHans de Goede 1039554c0a3aSHans de Goede padapter->bDriverStopped = true; 1040554c0a3aSHans de Goede if (padapter->xmitpriv.ack_tx) 1041554c0a3aSHans de Goede rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); 1042554c0a3aSHans de Goede 1043554c0a3aSHans de Goede if (padapter->intf_stop) 1044554c0a3aSHans de Goede padapter->intf_stop(padapter); 1045554c0a3aSHans de Goede 1046554c0a3aSHans de Goede if (!pwrctl->bInternalAutoSuspend) 1047554c0a3aSHans de Goede rtw_stop_drv_threads(padapter); 1048554c0a3aSHans de Goede 1049e49fa0b7SJohn Oldman while (atomic_read(&pcmdpriv->cmdthd_running)) { 1050554c0a3aSHans de Goede if (cnt > 5) { 1051554c0a3aSHans de Goede break; 1052554c0a3aSHans de Goede } else { 1053554c0a3aSHans de Goede cnt++; 1054554c0a3aSHans de Goede msleep(10); 1055554c0a3aSHans de Goede } 1056554c0a3aSHans de Goede } 1057554c0a3aSHans de Goede 1058554c0a3aSHans de Goede /* check the status of IPS */ 1059e49fa0b7SJohn Oldman if (rtw_hal_check_ips_status(padapter) || pwrctl->rf_pwrstate == rf_off) { 1060e49fa0b7SJohn Oldman /* check HW status and SW state */ 106179df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 106279df841bSFabio Aiuto "%s: driver in IPS-FWLPS\n", __func__); 1063554c0a3aSHans de Goede pdbgpriv->dbg_dev_unload_inIPS_cnt++; 1064554c0a3aSHans de Goede LeaveAllPowerSaveMode(padapter); 1065554c0a3aSHans de Goede } else { 106679df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 106779df841bSFabio Aiuto "%s: driver not in IPS\n", __func__); 1068554c0a3aSHans de Goede } 1069554c0a3aSHans de Goede 1070e49fa0b7SJohn Oldman if (!padapter->bSurpriseRemoved) { 10714c1bcb0eSNishka Dasgupta hal_btcoex_IpsNotify(padapter, pwrctl->ips_mode_req); 1072ada3334fSFabio Aiuto 1073554c0a3aSHans de Goede /* amy modify 20120221 for power seq is different between driver open and ips */ 1074554c0a3aSHans de Goede rtw_hal_deinit(padapter); 1075ada3334fSFabio Aiuto 1076554c0a3aSHans de Goede padapter->bSurpriseRemoved = true; 1077554c0a3aSHans de Goede } 1078554c0a3aSHans de Goede 1079554c0a3aSHans de Goede padapter->bup = false; 1080554c0a3aSHans de Goede 1081554c0a3aSHans de Goede } 1082554c0a3aSHans de Goede } 1083554c0a3aSHans de Goede 1084554c0a3aSHans de Goede static int rtw_suspend_free_assoc_resource(struct adapter *padapter) 1085554c0a3aSHans de Goede { 1086554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1087554c0a3aSHans de Goede 1088554c0a3aSHans de Goede if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { 1089554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) 1090ffd3c648SHarsha Sharma && check_fwstate(pmlmepriv, _FW_LINKED)) { 1091554c0a3aSHans de Goede rtw_set_to_roam(padapter, 1); 1092554c0a3aSHans de Goede } 1093554c0a3aSHans de Goede } 1094554c0a3aSHans de Goede 1095ffd3c648SHarsha Sharma if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)) { 1096554c0a3aSHans de Goede rtw_disassoc_cmd(padapter, 0, false); 1097554c0a3aSHans de Goede /* s2-2. indicate disconnect to os */ 1098554c0a3aSHans de Goede rtw_indicate_disconnect(padapter); 1099addf21eaSJohn Oldman } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1100554c0a3aSHans de Goede rtw_sta_flush(padapter); 1101554c0a3aSHans de Goede } 1102554c0a3aSHans de Goede 1103554c0a3aSHans de Goede /* s2-3. */ 1104554c0a3aSHans de Goede rtw_free_assoc_resources(padapter, 1); 1105554c0a3aSHans de Goede 1106554c0a3aSHans de Goede /* s2-4. */ 1107554c0a3aSHans de Goede rtw_free_network_queue(padapter, true); 1108554c0a3aSHans de Goede 1109554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 1110554c0a3aSHans de Goede rtw_indicate_scan_done(padapter, 1); 1111554c0a3aSHans de Goede 1112e49fa0b7SJohn Oldman if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 111379df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, "%s: fw_under_linking\n", 111479df841bSFabio Aiuto __func__); 1115554c0a3aSHans de Goede rtw_indicate_disconnect(padapter); 1116554c0a3aSHans de Goede } 1117554c0a3aSHans de Goede 1118554c0a3aSHans de Goede return _SUCCESS; 1119554c0a3aSHans de Goede } 1120554c0a3aSHans de Goede 1121aa0d54dbSShobhit Kukreti static void rtw_suspend_normal(struct adapter *padapter) 1122554c0a3aSHans de Goede { 1123554c0a3aSHans de Goede struct net_device *pnetdev = padapter->pnetdev; 1124554c0a3aSHans de Goede 1125554c0a3aSHans de Goede if (pnetdev) { 1126554c0a3aSHans de Goede netif_carrier_off(pnetdev); 1127554c0a3aSHans de Goede rtw_netif_stop_queue(pnetdev); 1128554c0a3aSHans de Goede } 1129554c0a3aSHans de Goede 1130554c0a3aSHans de Goede rtw_suspend_free_assoc_resource(padapter); 1131554c0a3aSHans de Goede 1132e49fa0b7SJohn Oldman if ((rtw_hal_check_ips_status(padapter)) || (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off)) 113379df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 113479df841bSFabio Aiuto "%s: ### ERROR #### driver in IPS ####ERROR###!!!\n", 113579df841bSFabio Aiuto __func__); 1136554c0a3aSHans de Goede 1137554c0a3aSHans de Goede rtw_dev_unload(padapter); 1138554c0a3aSHans de Goede 1139554c0a3aSHans de Goede /* sdio_deinit(adapter_to_dvobj(padapter)); */ 1140554c0a3aSHans de Goede if (padapter->intf_deinit) 1141554c0a3aSHans de Goede padapter->intf_deinit(adapter_to_dvobj(padapter)); 1142554c0a3aSHans de Goede } 1143554c0a3aSHans de Goede 1144a616d121SSaurav Girepunje void rtw_suspend_common(struct adapter *padapter) 1145554c0a3aSHans de Goede { 1146554c0a3aSHans de Goede struct dvobj_priv *psdpriv = padapter->dvobj; 1147554c0a3aSHans de Goede struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 1148554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); 1149554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1150554c0a3aSHans de Goede 1151554c0a3aSHans de Goede unsigned long start_time = jiffies; 1152554c0a3aSHans de Goede 115379df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, " suspend start\n"); 1154554c0a3aSHans de Goede pdbgpriv->dbg_suspend_cnt++; 1155554c0a3aSHans de Goede 1156554c0a3aSHans de Goede pwrpriv->bInSuspend = true; 1157554c0a3aSHans de Goede 1158e49fa0b7SJohn Oldman while (pwrpriv->bips_processing) 1159554c0a3aSHans de Goede msleep(1); 1160554c0a3aSHans de Goede 1161ffd3c648SHarsha Sharma if ((!padapter->bup) || (padapter->bDriverStopped) || (padapter->bSurpriseRemoved)) { 1162554c0a3aSHans de Goede pdbgpriv->dbg_suspend_error_cnt++; 1163554c0a3aSHans de Goede goto exit; 1164554c0a3aSHans de Goede } 1165554c0a3aSHans de Goede rtw_ps_deny(padapter, PS_DENY_SUSPEND); 1166554c0a3aSHans de Goede 1167554c0a3aSHans de Goede rtw_cancel_all_timer(padapter); 1168554c0a3aSHans de Goede 1169554c0a3aSHans de Goede LeaveAllPowerSaveModeDirect(padapter); 1170554c0a3aSHans de Goede 1171554c0a3aSHans de Goede rtw_stop_cmd_thread(padapter); 1172554c0a3aSHans de Goede 1173554c0a3aSHans de Goede /* wait for the latest FW to remove this condition. */ 1174709c8e49SFabio Aiuto if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 1175b9c1def2SNishka Dasgupta hal_btcoex_SuspendNotify(padapter, 0); 1176709c8e49SFabio Aiuto else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 1177b9c1def2SNishka Dasgupta hal_btcoex_SuspendNotify(padapter, 1); 1178554c0a3aSHans de Goede 1179554c0a3aSHans de Goede rtw_ps_deny_cancel(padapter, PS_DENY_SUSPEND); 1180554c0a3aSHans de Goede 1181554c0a3aSHans de Goede rtw_suspend_normal(padapter); 1182554c0a3aSHans de Goede 118379df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, "rtw suspend success in %d ms\n", 1184554c0a3aSHans de Goede jiffies_to_msecs(jiffies - start_time)); 1185554c0a3aSHans de Goede 1186554c0a3aSHans de Goede exit: 1187554c0a3aSHans de Goede 1188a616d121SSaurav Girepunje return; 1189554c0a3aSHans de Goede } 1190554c0a3aSHans de Goede 1191554c0a3aSHans de Goede static int rtw_resume_process_normal(struct adapter *padapter) 1192554c0a3aSHans de Goede { 1193554c0a3aSHans de Goede struct net_device *pnetdev; 1194554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv; 1195554c0a3aSHans de Goede struct mlme_priv *pmlmepriv; 1196554c0a3aSHans de Goede struct dvobj_priv *psdpriv; 1197554c0a3aSHans de Goede struct debug_priv *pdbgpriv; 1198554c0a3aSHans de Goede 1199554c0a3aSHans de Goede int ret = _SUCCESS; 1200554c0a3aSHans de Goede 1201554c0a3aSHans de Goede if (!padapter) { 1202554c0a3aSHans de Goede ret = -1; 1203554c0a3aSHans de Goede goto exit; 1204554c0a3aSHans de Goede } 1205554c0a3aSHans de Goede 1206554c0a3aSHans de Goede pnetdev = padapter->pnetdev; 1207554c0a3aSHans de Goede pwrpriv = adapter_to_pwrctl(padapter); 1208554c0a3aSHans de Goede pmlmepriv = &padapter->mlmepriv; 1209554c0a3aSHans de Goede psdpriv = padapter->dvobj; 1210554c0a3aSHans de Goede pdbgpriv = &psdpriv->drv_dbg; 1211554c0a3aSHans de Goede /* interface init */ 1212554c0a3aSHans de Goede /* if (sdio_init(adapter_to_dvobj(padapter)) != _SUCCESS) */ 1213ffd3c648SHarsha Sharma if ((padapter->intf_init) && (padapter->intf_init(adapter_to_dvobj(padapter)) != _SUCCESS)) { 1214554c0a3aSHans de Goede ret = -1; 1215554c0a3aSHans de Goede goto exit; 1216554c0a3aSHans de Goede } 1217554c0a3aSHans de Goede rtw_hal_disable_interrupt(padapter); 1218554c0a3aSHans de Goede /* if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) */ 1219ffd3c648SHarsha Sharma if ((padapter->intf_alloc_irq) && (padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)) { 1220554c0a3aSHans de Goede ret = -1; 1221554c0a3aSHans de Goede goto exit; 1222554c0a3aSHans de Goede } 1223554c0a3aSHans de Goede 1224554c0a3aSHans de Goede rtw_reset_drv_sw(padapter); 1225554c0a3aSHans de Goede pwrpriv->bkeepfwalive = false; 1226554c0a3aSHans de Goede 1227554c0a3aSHans de Goede if (pm_netdev_open(pnetdev, true) != 0) { 1228554c0a3aSHans de Goede ret = -1; 1229554c0a3aSHans de Goede pdbgpriv->dbg_resume_error_cnt++; 1230554c0a3aSHans de Goede goto exit; 1231554c0a3aSHans de Goede } 1232554c0a3aSHans de Goede 1233554c0a3aSHans de Goede netif_device_attach(pnetdev); 1234554c0a3aSHans de Goede netif_carrier_on(pnetdev); 1235554c0a3aSHans de Goede 1236709c8e49SFabio Aiuto if (padapter->pid[1] != 0) 1237554c0a3aSHans de Goede rtw_signal_process(padapter->pid[1], SIGUSR2); 1238554c0a3aSHans de Goede 1239554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1240554c0a3aSHans de Goede if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) 1241554c0a3aSHans de Goede rtw_roaming(padapter, NULL); 1242554c0a3aSHans de Goede } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1243554c0a3aSHans de Goede rtw_ap_restore_network(padapter); 1244554c0a3aSHans de Goede } 1245554c0a3aSHans de Goede 1246554c0a3aSHans de Goede exit: 1247554c0a3aSHans de Goede return ret; 1248554c0a3aSHans de Goede } 1249554c0a3aSHans de Goede 1250554c0a3aSHans de Goede int rtw_resume_common(struct adapter *padapter) 1251554c0a3aSHans de Goede { 1252554c0a3aSHans de Goede int ret = 0; 1253554c0a3aSHans de Goede unsigned long start_time = jiffies; 1254554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1255554c0a3aSHans de Goede 125679df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, "resume start\n"); 1257554c0a3aSHans de Goede 1258554c0a3aSHans de Goede rtw_resume_process_normal(padapter); 1259554c0a3aSHans de Goede 1260b9c1def2SNishka Dasgupta hal_btcoex_SuspendNotify(padapter, 0); 1261554c0a3aSHans de Goede 1262554c0a3aSHans de Goede if (pwrpriv) { 1263554c0a3aSHans de Goede pwrpriv->bInSuspend = false; 1264554c0a3aSHans de Goede } 126579df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, "%s:%d in %d ms\n", __func__, ret, 1266554c0a3aSHans de Goede jiffies_to_msecs(jiffies - start_time)); 1267554c0a3aSHans de Goede 1268554c0a3aSHans de Goede return ret; 1269554c0a3aSHans de Goede } 1270