[go: nahoru, domu]

1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010  Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../core.h"
28#include "../pci.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "dm.h"
33#include "hw.h"
34#include "fw.h"
35#include "sw.h"
36#include "trx.h"
37#include "led.h"
38#include "table.h"
39#include "../btcoexist/rtl_btc.h"
40
41#include <linux/vmalloc.h>
42#include <linux/module.h>
43
44static void rtl8821ae_init_aspm_vars(struct ieee80211_hw *hw)
45{
46	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
47
48	/*close ASPM for AMD defaultly */
49	rtlpci->const_amdpci_aspm = 0;
50
51	/**
52	 * ASPM PS mode.
53	 * 0 - Disable ASPM,
54	 * 1 - Enable ASPM without Clock Req,
55	 * 2 - Enable ASPM with Clock Req,
56	 * 3 - Alwyas Enable ASPM with Clock Req,
57	 * 4 - Always Enable ASPM without Clock Req.
58	 * set defult to RTL8192CE:3 RTL8192E:2
59	 */
60	rtlpci->const_pci_aspm = 3;
61
62	/*Setting for PCI-E device */
63	rtlpci->const_devicepci_aspm_setting = 0x03;
64
65	/*Setting for PCI-E bridge */
66	rtlpci->const_hostpci_aspm_setting = 0x02;
67
68	/**
69	 * In Hw/Sw Radio Off situation.
70	 * 0 - Default,
71	 * 1 - From ASPM setting without low Mac Pwr,
72	 * 2 - From ASPM setting with low Mac Pwr,
73	 * 3 - Bus D3
74	 * set default to RTL8192CE:0 RTL8192SE:2
75	 */
76	rtlpci->const_hwsw_rfoff_d3 = 0;
77
78	/**
79	 * This setting works for those device with
80	 * backdoor ASPM setting such as EPHY setting.
81	 * 0 - Not support ASPM,
82	 * 1 - Support ASPM,
83	 * 2 - According to chipset.
84	 */
85	rtlpci->const_support_pciaspm = 1;
86}
87
88static void load_wowlan_fw(struct rtl_priv *rtlpriv)
89{
90	/* callback routine to load wowlan firmware after main fw has
91	 * been loaded
92	 */
93	const struct firmware *wowlan_firmware;
94	char *fw_name = NULL;
95	int err;
96
97	/* for wowlan firmware buf */
98	rtlpriv->rtlhal.wowlan_firmware = vzalloc(0x8000);
99	if (!rtlpriv->rtlhal.wowlan_firmware) {
100		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
101			 "Can't alloc buffer for wowlan fw.\n");
102		return;
103	}
104
105	if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8821AE)
106		fw_name = "rtlwifi/rtl8821aefw_wowlan.bin";
107	else
108		fw_name = "rtlwifi/rtl8812aefw_wowlan.bin";
109	err = request_firmware(&wowlan_firmware, fw_name, rtlpriv->io.dev);
110	if (err) {
111		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
112			 "Failed to request wowlan firmware!\n");
113		goto error;
114	}
115
116	if (wowlan_firmware->size > 0x8000) {
117		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
118			 "Wowlan Firmware is too big!\n");
119		goto error;
120	}
121
122	memcpy(rtlpriv->rtlhal.wowlan_firmware, wowlan_firmware->data,
123	       wowlan_firmware->size);
124	rtlpriv->rtlhal.wowlan_fwsize = wowlan_firmware->size;
125	release_firmware(wowlan_firmware);
126
127	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "WOWLAN FirmwareDownload OK\n");
128	return;
129error:
130	release_firmware(wowlan_firmware);
131	vfree(rtlpriv->rtlhal.wowlan_firmware);
132}
133
134/*InitializeVariables8812E*/
135int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
136{
137	int err = 0;
138	struct rtl_priv *rtlpriv = rtl_priv(hw);
139	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
140	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
141	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
142
143	rtl8821ae_bt_reg_init(hw);
144	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
145	rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
146
147	rtlpriv->dm.dm_initialgain_enable = 1;
148	rtlpriv->dm.dm_flag = 0;
149	rtlpriv->dm.disable_framebursting = 0;
150	rtlpriv->dm.thermalvalue = 0;
151	rtlpci->transmit_config = CFENDFORM | BIT(15) | BIT(24) | BIT(25);
152
153	mac->ht_enable = true;
154	mac->ht_cur_stbc = 0;
155	mac->ht_stbc_cap = 0;
156	mac->vht_cur_ldpc = 0;
157	mac->vht_ldpc_cap = 0;
158	mac->vht_cur_stbc = 0;
159	mac->vht_stbc_cap = 0;
160
161	rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
162	/*following 2 is for register 5G band, refer to _rtl_init_mac80211()*/
163	rtlpriv->rtlhal.bandset = BAND_ON_BOTH;
164	rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
165
166	rtlpci->receive_config = (RCR_APPFCS	|
167				RCR_APP_MIC		|
168				RCR_APP_ICV		|
169				RCR_APP_PHYST_RXFF	|
170				RCR_NONQOS_VHT		|
171				RCR_HTC_LOC_CTRL	|
172				RCR_AMF			|
173				RCR_ACF			|
174			/*This bit controls the PS-Poll packet filter.*/
175				RCR_ADF			|
176				RCR_AICV		|
177				RCR_ACRC32		|
178				RCR_AB			|
179				RCR_AM			|
180				RCR_APM			|
181				0);
182
183	rtlpci->irq_mask[0] =
184	     (u32)(IMR_PSTIMEOUT			|
185				IMR_GTINT3		|
186				IMR_HSISR_IND_ON_INT	|
187				IMR_C2HCMD		|
188				IMR_HIGHDOK		|
189				IMR_MGNTDOK		|
190				IMR_BKDOK		|
191				IMR_BEDOK		|
192				IMR_VIDOK		|
193				IMR_VODOK		|
194				IMR_RDU			|
195				IMR_ROK			|
196				0);
197
198	rtlpci->irq_mask[1]	=
199		 (u32)(IMR_RXFOVW |
200				IMR_TXFOVW |
201				0);
202	rtlpci->sys_irq_mask = (u32)(HSIMR_PDN_INT_EN	|
203				      HSIMR_RON_INT_EN	|
204				      0);
205	/* for WOWLAN */
206	rtlpriv->psc.wo_wlan_mode = WAKE_ON_MAGIC_PACKET |
207				    WAKE_ON_PATTERN_MATCH;
208
209	/* for debug level */
210	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
211	/* for LPS & IPS */
212	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
213	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
214	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
215	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
216	if (rtlpriv->cfg->mod_params->disable_watchdog)
217		pr_info("watchdog disabled\n");
218	rtlpriv->psc.reg_fwctrl_lps = 3;
219	rtlpriv->psc.reg_max_lps_awakeintvl = 5;
220	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
221
222	/* for ASPM, you can close aspm through
223	 * set const_support_pciaspm = 0
224	 */
225	rtl8821ae_init_aspm_vars(hw);
226
227	if (rtlpriv->psc.reg_fwctrl_lps == 1)
228		rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
229	else if (rtlpriv->psc.reg_fwctrl_lps == 2)
230		rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
231	else if (rtlpriv->psc.reg_fwctrl_lps == 3)
232		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
233
234	rtlpriv->rtl_fw_second_cb = load_wowlan_fw;
235	/* for firmware buf */
236	rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
237	if (!rtlpriv->rtlhal.pfirmware) {
238		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
239			 "Can't alloc buffer for fw.\n");
240		return 1;
241	}
242
243	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
244		rtlpriv->cfg->fw_name = "rtlwifi/rtl8812aefw.bin";
245	else
246		rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin";
247
248	rtlpriv->max_fw_size = 0x8000;
249	pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
250	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
251				      rtlpriv->io.dev, GFP_KERNEL, hw,
252				      rtl_fw_cb);
253	if (err) {
254		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
255			 "Failed to request firmware!\n");
256		return 1;
257	}
258	return 0;
259}
260
261void rtl8821ae_deinit_sw_vars(struct ieee80211_hw *hw)
262{
263	struct rtl_priv *rtlpriv = rtl_priv(hw);
264
265	if (rtlpriv->rtlhal.pfirmware) {
266		vfree(rtlpriv->rtlhal.pfirmware);
267		rtlpriv->rtlhal.pfirmware = NULL;
268	}
269#if (USE_SPECIFIC_FW_TO_SUPPORT_WOWLAN == 1)
270	if (rtlpriv->rtlhal.wowlan_firmware) {
271		vfree(rtlpriv->rtlhal.wowlan_firmware);
272		rtlpriv->rtlhal.wowlan_firmware = NULL;
273	}
274#endif
275}
276
277/* get bt coexist status */
278bool rtl8821ae_get_btc_status(void)
279{
280	return true;
281}
282
283static struct rtl_hal_ops rtl8821ae_hal_ops = {
284	.init_sw_vars = rtl8821ae_init_sw_vars,
285	.deinit_sw_vars = rtl8821ae_deinit_sw_vars,
286	.read_eeprom_info = rtl8821ae_read_eeprom_info,
287	.interrupt_recognized = rtl8821ae_interrupt_recognized,
288	.hw_init = rtl8821ae_hw_init,
289	.hw_disable = rtl8821ae_card_disable,
290	.hw_suspend = rtl8821ae_suspend,
291	.hw_resume = rtl8821ae_resume,
292	.enable_interrupt = rtl8821ae_enable_interrupt,
293	.disable_interrupt = rtl8821ae_disable_interrupt,
294	.set_network_type = rtl8821ae_set_network_type,
295	.set_chk_bssid = rtl8821ae_set_check_bssid,
296	.set_qos = rtl8821ae_set_qos,
297	.set_bcn_reg = rtl8821ae_set_beacon_related_registers,
298	.set_bcn_intv = rtl8821ae_set_beacon_interval,
299	.update_interrupt_mask = rtl8821ae_update_interrupt_mask,
300	.get_hw_reg = rtl8821ae_get_hw_reg,
301	.set_hw_reg = rtl8821ae_set_hw_reg,
302	.update_rate_tbl = rtl8821ae_update_hal_rate_tbl,
303	.fill_tx_desc = rtl8821ae_tx_fill_desc,
304	.fill_tx_cmddesc = rtl8821ae_tx_fill_cmddesc,
305	.query_rx_desc = rtl8821ae_rx_query_desc,
306	.set_channel_access = rtl8821ae_update_channel_access_setting,
307	.radio_onoff_checking = rtl8821ae_gpio_radio_on_off_checking,
308	.set_bw_mode = rtl8821ae_phy_set_bw_mode,
309	.switch_channel = rtl8821ae_phy_sw_chnl,
310	.dm_watchdog = rtl8821ae_dm_watchdog,
311	.scan_operation_backup = rtl8821ae_phy_scan_operation_backup,
312	.set_rf_power_state = rtl8821ae_phy_set_rf_power_state,
313	.led_control = rtl8821ae_led_control,
314	.set_desc = rtl8821ae_set_desc,
315	.get_desc = rtl8821ae_get_desc,
316	.is_tx_desc_closed = rtl8821ae_is_tx_desc_closed,
317	.tx_polling = rtl8821ae_tx_polling,
318	.enable_hw_sec = rtl8821ae_enable_hw_security_config,
319	.set_key = rtl8821ae_set_key,
320	.init_sw_leds = rtl8821ae_init_sw_leds,
321	.get_bbreg = rtl8821ae_phy_query_bb_reg,
322	.set_bbreg = rtl8821ae_phy_set_bb_reg,
323	.get_rfreg = rtl8821ae_phy_query_rf_reg,
324	.set_rfreg = rtl8821ae_phy_set_rf_reg,
325	.fill_h2c_cmd = rtl8821ae_fill_h2c_cmd,
326	.get_btc_status = rtl8821ae_get_btc_status,
327	.rx_command_packet = rtl8821ae_rx_command_packet,
328	.add_wowlan_pattern = rtl8821ae_add_wowlan_pattern,
329};
330
331static struct rtl_mod_params rtl8821ae_mod_params = {
332	.sw_crypto = false,
333	.inactiveps = true,
334	.swctrl_lps = false,
335	.fwctrl_lps = true,
336	.msi_support = true,
337	.debug = DBG_EMERG,
338	.disable_watchdog = 0,
339};
340
341static struct rtl_hal_cfg rtl8821ae_hal_cfg = {
342	.bar_id = 2,
343	.write_readback = true,
344	.name = "rtl8821ae_pci",
345	.fw_name = "rtlwifi/rtl8821aefw.bin",
346	.ops = &rtl8821ae_hal_ops,
347	.mod_params = &rtl8821ae_mod_params,
348	.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
349	.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
350	.maps[SYS_CLK] = REG_SYS_CLKR,
351	.maps[MAC_RCR_AM] = AM,
352	.maps[MAC_RCR_AB] = AB,
353	.maps[MAC_RCR_ACRC32] = ACRC32,
354	.maps[MAC_RCR_ACF] = ACF,
355	.maps[MAC_RCR_AAP] = AAP,
356	.maps[MAC_HIMR] = REG_HIMR,
357	.maps[MAC_HIMRE] = REG_HIMRE,
358
359	.maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS,
360
361	.maps[EFUSE_TEST] = REG_EFUSE_TEST,
362	.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
363	.maps[EFUSE_CLK] = 0,
364	.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
365	.maps[EFUSE_PWC_EV12V] = PWC_EV12V,
366	.maps[EFUSE_FEN_ELDR] = FEN_ELDR,
367	.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
368	.maps[EFUSE_ANA8M] = ANA8M,
369	.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
370	.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
371	.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
372	.maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
373
374	.maps[RWCAM] = REG_CAMCMD,
375	.maps[WCAMI] = REG_CAMWRITE,
376	.maps[RCAMO] = REG_CAMREAD,
377	.maps[CAMDBG] = REG_CAMDBG,
378	.maps[SECR] = REG_SECCFG,
379	.maps[SEC_CAM_NONE] = CAM_NONE,
380	.maps[SEC_CAM_WEP40] = CAM_WEP40,
381	.maps[SEC_CAM_TKIP] = CAM_TKIP,
382	.maps[SEC_CAM_AES] = CAM_AES,
383	.maps[SEC_CAM_WEP104] = CAM_WEP104,
384
385	.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
386	.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
387	.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
388	.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
389	.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
390	.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
391/*	.maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,     */   /*need check*/
392	.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
393	.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
394	.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
395	.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
396	.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
397	.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
398	.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
399/*	.maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/
400/*	.maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/
401
402	.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
403	.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
404	.maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0,
405	.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
406	.maps[RTL_IMR_RDU] = IMR_RDU,
407	.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
408	.maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
409	.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
410	.maps[RTL_IMR_TBDER] = IMR_TBDER,
411	.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
412	.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
413	.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
414	.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
415	.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
416	.maps[RTL_IMR_VODOK] = IMR_VODOK,
417	.maps[RTL_IMR_ROK] = IMR_ROK,
418	.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
419
420	.maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
421	.maps[RTL_RC_CCK_RATE2M] =  DESC_RATE2M,
422	.maps[RTL_RC_CCK_RATE5_5M] =  DESC_RATE5_5M,
423	.maps[RTL_RC_CCK_RATE11M] =  DESC_RATE11M,
424	.maps[RTL_RC_OFDM_RATE6M] =  DESC_RATE6M,
425	.maps[RTL_RC_OFDM_RATE9M] =  DESC_RATE9M,
426	.maps[RTL_RC_OFDM_RATE12M] =  DESC_RATE12M,
427	.maps[RTL_RC_OFDM_RATE18M] =  DESC_RATE18M,
428	.maps[RTL_RC_OFDM_RATE24M] =  DESC_RATE24M,
429	.maps[RTL_RC_OFDM_RATE36M] =  DESC_RATE36M,
430	.maps[RTL_RC_OFDM_RATE48M] =  DESC_RATE48M,
431	.maps[RTL_RC_OFDM_RATE54M] =  DESC_RATE54M,
432
433	.maps[RTL_RC_HT_RATEMCS7] =  DESC_RATEMCS7,
434	.maps[RTL_RC_HT_RATEMCS15] =  DESC_RATEMCS15,
435
436	/*VHT hightest rate*/
437	.maps[RTL_RC_VHT_RATE_1SS_MCS7] = DESC_RATEVHT1SS_MCS7,
438	.maps[RTL_RC_VHT_RATE_1SS_MCS8] = DESC_RATEVHT1SS_MCS8,
439	.maps[RTL_RC_VHT_RATE_1SS_MCS9] = DESC_RATEVHT1SS_MCS9,
440	.maps[RTL_RC_VHT_RATE_2SS_MCS7] = DESC_RATEVHT2SS_MCS7,
441	.maps[RTL_RC_VHT_RATE_2SS_MCS8] = DESC_RATEVHT2SS_MCS8,
442	.maps[RTL_RC_VHT_RATE_2SS_MCS9] = DESC_RATEVHT2SS_MCS9,
443};
444
445static struct pci_device_id rtl8821ae_pci_ids[] = {
446	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8812, rtl8821ae_hal_cfg)},
447	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8821, rtl8821ae_hal_cfg)},
448	{},
449};
450
451MODULE_DEVICE_TABLE(pci, rtl8821ae_pci_ids);
452
453MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>");
454MODULE_LICENSE("GPL");
455MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless");
456MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
457
458module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444);
459module_param_named(debug, rtl8821ae_mod_params.debug, int, 0444);
460module_param_named(ips, rtl8821ae_mod_params.inactiveps, bool, 0444);
461module_param_named(swlps, rtl8821ae_mod_params.swctrl_lps, bool, 0444);
462module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
463module_param_named(msi, rtl8821ae_mod_params.msi_support, bool, 0444);
464module_param_named(disable_watchdog, rtl8821ae_mod_params.disable_watchdog,
465		   bool, 0444);
466MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
467MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
468MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
469MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
470MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
471MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
472MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
473
474static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
475
476static struct pci_driver rtl8821ae_driver = {
477	.name = KBUILD_MODNAME,
478	.id_table = rtl8821ae_pci_ids,
479	.probe = rtl_pci_probe,
480	.remove = rtl_pci_disconnect,
481	.driver.pm = &rtlwifi_pm_ops,
482};
483
484module_pci_driver(rtl8821ae_driver);
485