Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1 | /****************************************************************************** |
| 2 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
| 3 | * |
| 4 | * Based on the r8180 driver, which is: |
Andrea Merello | 559a4c3 | 2013-08-26 13:53:30 +0200 | [diff] [blame] | 5 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of version 2 of the GNU General Public License as |
| 8 | * published by the Free Software Foundation. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, but WITHOUT |
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 13 | * more details. |
| 14 | * |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 15 | * The full GNU General Public License is included in this distribution in the |
| 16 | * file called LICENSE. |
| 17 | * |
| 18 | * Contact Information: |
| 19 | * wlanfae <wlanfae@realtek.com> |
| 20 | ******************************************************************************/ |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 21 | #include <linux/uaccess.h> |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 22 | #include <linux/pci.h> |
Stephen Rothwell | 09ebd6f | 2011-08-25 16:17:06 +1000 | [diff] [blame] | 23 | #include <linux/vmalloc.h> |
Paul Gortmaker | acd442d | 2015-04-27 01:25:41 -0400 | [diff] [blame] | 24 | #include <linux/ieee80211.h> |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 25 | #include "rtl_core.h" |
| 26 | #include "r8192E_phy.h" |
| 27 | #include "r8192E_phyreg.h" |
| 28 | #include "r8190P_rtl8256.h" |
| 29 | #include "r8192E_cmdpkt.h" |
| 30 | |
| 31 | #include "rtl_wx.h" |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 32 | #include "rtl_dm.h" |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 33 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 34 | #include "rtl_pm.h" |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 35 | |
| 36 | int hwwep = 1; |
| 37 | static int channels = 0x3fff; |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 38 | static char *ifname = "wlan%d"; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 39 | |
| 40 | |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 41 | static struct rtl819x_ops rtl819xp_ops = { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 42 | .nic_type = NIC_8192E, |
Mateusz Kulikowski | b095be3 | 2015-07-19 19:27:28 +0200 | [diff] [blame] | 43 | .get_eeprom_size = rtl92e_get_eeprom_size, |
Mateusz Kulikowski | df85a13 | 2015-07-19 19:27:34 +0200 | [diff] [blame] | 44 | .init_adapter_variable = rtl92e_init_variables, |
Mateusz Kulikowski | 4602662 | 2015-07-19 19:27:19 +0200 | [diff] [blame] | 45 | .initialize_adapter = rtl92e_start_adapter, |
Mateusz Kulikowski | b974b28 | 2015-07-19 19:27:36 +0200 | [diff] [blame] | 46 | .link_change = rtl92e_link_change, |
Mateusz Kulikowski | 072b394 | 2015-07-19 19:27:39 +0200 | [diff] [blame] | 47 | .tx_fill_descriptor = rtl92e_fill_tx_desc, |
Mateusz Kulikowski | 63b544a | 2015-07-19 19:27:38 +0200 | [diff] [blame] | 48 | .tx_fill_cmd_descriptor = rtl92e_fill_tx_cmd_desc, |
Mateusz Kulikowski | 7897285 | 2015-07-19 19:27:37 +0200 | [diff] [blame] | 49 | .rx_query_status_descriptor = rtl92e_get_rx_stats, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 50 | .rx_command_packet_handler = NULL, |
Mateusz Kulikowski | fe99c77 | 2015-07-19 19:27:32 +0200 | [diff] [blame] | 51 | .stop_adapter = rtl92e_stop_adapter, |
Mateusz Kulikowski | 575d48c | 2015-07-19 19:27:40 +0200 | [diff] [blame] | 52 | .update_ratr_table = rtl92e_update_ratr_table, |
Mateusz Kulikowski | 6d99c68 | 2015-07-19 19:27:23 +0200 | [diff] [blame] | 53 | .irq_enable = rtl92e_enable_irq, |
Mateusz Kulikowski | baadea5 | 2015-07-19 19:27:22 +0200 | [diff] [blame] | 54 | .irq_disable = rtl92e_disable_irq, |
Mateusz Kulikowski | dc578b4 | 2015-07-19 19:27:21 +0200 | [diff] [blame] | 55 | .irq_clear = rtl92e_clear_irq, |
Mateusz Kulikowski | 78c352b | 2015-07-19 19:27:24 +0200 | [diff] [blame] | 56 | .rx_enable = rtl92e_enable_rx, |
Mateusz Kulikowski | 6af7a8b | 2015-07-19 19:27:25 +0200 | [diff] [blame] | 57 | .tx_enable = rtl92e_enable_tx, |
Mateusz Kulikowski | a57165d | 2015-07-19 19:27:35 +0200 | [diff] [blame] | 58 | .interrupt_recognized = rtl92e_ack_irq, |
Mateusz Kulikowski | c9cf5e7 | 2015-07-19 19:27:33 +0200 | [diff] [blame] | 59 | .TxCheckStuckHandler = rtl92e_is_tx_stuck, |
Mateusz Kulikowski | 4d73bd2 | 2015-07-19 19:27:31 +0200 | [diff] [blame] | 60 | .RxCheckStuckHandler = rtl92e_is_rx_stuck, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 61 | }; |
| 62 | |
Bill Pemberton | 83f5789 | 2012-11-19 13:24:45 -0500 | [diff] [blame] | 63 | static struct pci_device_id rtl8192_pci_id_tbl[] = { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 64 | {RTL_PCI_DEVICE(0x10ec, 0x8192, rtl819xp_ops)}, |
| 65 | {RTL_PCI_DEVICE(0x07aa, 0x0044, rtl819xp_ops)}, |
| 66 | {RTL_PCI_DEVICE(0x07aa, 0x0047, rtl819xp_ops)}, |
| 67 | {} |
| 68 | }; |
| 69 | |
| 70 | MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); |
| 71 | |
Mateusz Kulikowski | 93cc57b | 2015-09-20 10:12:59 +0200 | [diff] [blame] | 72 | static int _rtl92e_pci_probe(struct pci_dev *pdev, |
| 73 | const struct pci_device_id *id); |
Mateusz Kulikowski | 4a85182 | 2015-09-20 10:12:55 +0200 | [diff] [blame] | 74 | static void _rtl92e_pci_disconnect(struct pci_dev *pdev); |
Mateusz Kulikowski | 87e01f2 | 2015-09-20 10:09:28 +0200 | [diff] [blame] | 75 | static irqreturn_t _rtl92e_irq(int irq, void *netdev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 76 | |
| 77 | static struct pci_driver rtl8192_pci_driver = { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 78 | .name = DRV_NAME, /* Driver name */ |
| 79 | .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */ |
Mateusz Kulikowski | 93cc57b | 2015-09-20 10:12:59 +0200 | [diff] [blame] | 80 | .probe = _rtl92e_pci_probe, /* probe fn */ |
Mateusz Kulikowski | 4a85182 | 2015-09-20 10:12:55 +0200 | [diff] [blame] | 81 | .remove = _rtl92e_pci_disconnect, /* remove fn */ |
Mateusz Kulikowski | 3683dc1 | 2015-07-19 19:28:42 +0200 | [diff] [blame] | 82 | .suspend = rtl92e_suspend, /* PM suspend fn */ |
Mateusz Kulikowski | 0ba6623 | 2015-07-19 19:28:41 +0200 | [diff] [blame] | 83 | .resume = rtl92e_resume, /* PM resume fn */ |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 84 | }; |
| 85 | |
Mateusz Kulikowski | 6f8d4a7 | 2015-09-20 10:13:09 +0200 | [diff] [blame] | 86 | static short _rtl92e_is_tx_queue_empty(struct net_device *dev); |
Mateusz Kulikowski | 7e2d598 | 2015-09-20 10:13:42 +0200 | [diff] [blame] | 87 | static void _rtl92e_watchdog_wq_cb(void *data); |
Mateusz Kulikowski | 2cfc375 | 2015-09-20 10:13:43 +0200 | [diff] [blame] | 88 | static void _rtl92e_watchdog_timer_cb(unsigned long data); |
Mateusz Kulikowski | 52a7404 | 2015-09-20 10:13:48 +0200 | [diff] [blame] | 89 | static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, |
Mateusz Kulikowski | 235a86c | 2015-07-14 22:04:21 +0200 | [diff] [blame] | 90 | int rate); |
Mateusz Kulikowski | 3e49f3e | 2015-09-20 10:13:49 +0200 | [diff] [blame] | 91 | static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); |
Mateusz Kulikowski | 98208f9 | 2015-09-20 10:13:05 +0200 | [diff] [blame] | 92 | static void _rtl92e_tx_cmd(struct net_device *dev, struct sk_buff *skb); |
Mateusz Kulikowski | 374a3c5 | 2015-09-20 10:13:04 +0200 | [diff] [blame] | 93 | static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb); |
Mateusz Kulikowski | 197917a | 2015-09-20 10:12:56 +0200 | [diff] [blame] | 94 | static short _rtl92e_pci_initdescring(struct net_device *dev); |
Mateusz Kulikowski | a2743b2 | 2015-09-20 10:09:30 +0200 | [diff] [blame] | 95 | static void _rtl92e_irq_tx_tasklet(struct r8192_priv *priv); |
Mateusz Kulikowski | 2940405 | 2015-09-20 10:09:29 +0200 | [diff] [blame] | 96 | static void _rtl92e_irq_rx_tasklet(struct r8192_priv *priv); |
Mateusz Kulikowski | 4dba03a | 2015-09-20 10:14:12 +0200 | [diff] [blame] | 97 | static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv); |
Mateusz Kulikowski | 81524bb | 2015-09-20 10:12:54 +0200 | [diff] [blame] | 98 | static int _rtl92e_up(struct net_device *dev, bool is_silent_reset); |
Mateusz Kulikowski | b1665a6 | 2015-09-20 10:12:53 +0200 | [diff] [blame] | 99 | static int _rtl92e_try_up(struct net_device *dev); |
Mateusz Kulikowski | 33bec9b | 2015-09-20 10:12:51 +0200 | [diff] [blame] | 100 | static int _rtl92e_down(struct net_device *dev, bool shutdownrf); |
Mateusz Kulikowski | 78e67df | 2015-09-20 10:12:52 +0200 | [diff] [blame] | 101 | static void _rtl92e_restart(void *data); |
Mateusz Kulikowski | 235a86c | 2015-07-14 22:04:21 +0200 | [diff] [blame] | 102 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 103 | /**************************************************************************** |
| 104 | -----------------------------IO STUFF------------------------- |
| 105 | *****************************************************************************/ |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 106 | |
Mateusz Kulikowski | b59a4ca | 2015-07-19 19:28:09 +0200 | [diff] [blame] | 107 | u8 rtl92e_readb(struct net_device *dev, int x) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 108 | { |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 109 | return 0xff & readb((u8 __iomem *)dev->mem_start + x); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 110 | } |
| 111 | |
Mateusz Kulikowski | 99aa47e | 2015-07-19 19:28:10 +0200 | [diff] [blame] | 112 | u32 rtl92e_readl(struct net_device *dev, int x) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 113 | { |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 114 | return readl((u8 __iomem *)dev->mem_start + x); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 115 | } |
| 116 | |
Mateusz Kulikowski | 1c0a7c0 | 2015-07-19 19:28:11 +0200 | [diff] [blame] | 117 | u16 rtl92e_readw(struct net_device *dev, int x) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 118 | { |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 119 | return readw((u8 __iomem *)dev->mem_start + x); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 120 | } |
| 121 | |
Mateusz Kulikowski | d8ae196 | 2015-07-19 19:28:26 +0200 | [diff] [blame] | 122 | void rtl92e_writeb(struct net_device *dev, int x, u8 y) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 123 | { |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 124 | writeb(y, (u8 __iomem *)dev->mem_start + x); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 125 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 126 | udelay(20); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 127 | } |
| 128 | |
Mateusz Kulikowski | 8ea5410 | 2015-07-19 19:28:27 +0200 | [diff] [blame] | 129 | void rtl92e_writel(struct net_device *dev, int x, u32 y) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 130 | { |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 131 | writel(y, (u8 __iomem *)dev->mem_start + x); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 132 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 133 | udelay(20); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 134 | } |
| 135 | |
Mateusz Kulikowski | 6dee0c8 | 2015-07-19 19:28:28 +0200 | [diff] [blame] | 136 | void rtl92e_writew(struct net_device *dev, int x, u16 y) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 137 | { |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 138 | writew(y, (u8 __iomem *)dev->mem_start + x); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 139 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 140 | udelay(20); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 141 | } |
| 142 | |
| 143 | /**************************************************************************** |
| 144 | -----------------------------GENERAL FUNCTION------------------------- |
| 145 | *****************************************************************************/ |
Mateusz Kulikowski | f434f9d | 2015-07-19 19:28:06 +0200 | [diff] [blame] | 146 | bool rtl92e_set_rf_state(struct net_device *dev, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 147 | enum rt_rf_power_state StateToSet, |
Mateusz Kulikowski | 2937a5d | 2015-07-28 23:31:41 +0200 | [diff] [blame] | 148 | RT_RF_CHANGE_SOURCE ChangeSource) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 149 | { |
| 150 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 151 | struct rtllib_device *ieee = priv->rtllib; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 152 | bool bActionAllowed = false; |
| 153 | bool bConnectBySSID = false; |
Larry Finger | de7c885 | 2011-07-19 21:00:33 -0500 | [diff] [blame] | 154 | enum rt_rf_power_state rtState; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 155 | u16 RFWaitCounter = 0; |
| 156 | unsigned long flag; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 157 | |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 158 | RT_TRACE((COMP_PS | COMP_RF), |
Mateusz Kulikowski | f434f9d | 2015-07-19 19:28:06 +0200 | [diff] [blame] | 159 | "===>rtl92e_set_rf_state(): StateToSet(%d)\n", StateToSet); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 160 | |
Mateusz Kulikowski | 2937a5d | 2015-07-28 23:31:41 +0200 | [diff] [blame] | 161 | while (true) { |
| 162 | spin_lock_irqsave(&priv->rf_ps_lock, flag); |
| 163 | if (priv->RFChangeInProgress) { |
| 164 | spin_unlock_irqrestore(&priv->rf_ps_lock, flag); |
| 165 | RT_TRACE((COMP_PS | COMP_RF), |
| 166 | "rtl92e_set_rf_state(): RF Change in progress! Wait to set..StateToSet(%d).\n", |
| 167 | StateToSet); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 168 | |
Mateusz Kulikowski | 2937a5d | 2015-07-28 23:31:41 +0200 | [diff] [blame] | 169 | while (priv->RFChangeInProgress) { |
| 170 | RFWaitCounter++; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 171 | RT_TRACE((COMP_PS | COMP_RF), |
Mateusz Kulikowski | 2937a5d | 2015-07-28 23:31:41 +0200 | [diff] [blame] | 172 | "rtl92e_set_rf_state(): Wait 1 ms (%d times)...\n", |
| 173 | RFWaitCounter); |
| 174 | mdelay(1); |
Mike McCormack | 4f6807e | 2011-07-11 08:56:20 +0900 | [diff] [blame] | 175 | |
Mateusz Kulikowski | 2937a5d | 2015-07-28 23:31:41 +0200 | [diff] [blame] | 176 | if (RFWaitCounter > 100) { |
| 177 | netdev_warn(dev, |
| 178 | "%s(): Timeout waiting for RF change.\n", |
| 179 | __func__); |
| 180 | return false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 181 | } |
| 182 | } |
Mateusz Kulikowski | 2937a5d | 2015-07-28 23:31:41 +0200 | [diff] [blame] | 183 | } else { |
| 184 | priv->RFChangeInProgress = true; |
| 185 | spin_unlock_irqrestore(&priv->rf_ps_lock, flag); |
| 186 | break; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 187 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | rtState = priv->rtllib->eRFPowerState; |
| 191 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 192 | switch (StateToSet) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 193 | case eRfOn: |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 194 | priv->rtllib->RfOffReason &= (~ChangeSource); |
| 195 | |
Valentina Manea | 4bb0142 | 2013-10-25 11:28:10 +0300 | [diff] [blame] | 196 | if ((ChangeSource == RF_CHANGE_BY_HW) && priv->bHwRadioOff) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 197 | priv->bHwRadioOff = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 198 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 199 | if (!priv->rtllib->RfOffReason) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 200 | priv->rtllib->RfOffReason = 0; |
| 201 | bActionAllowed = true; |
| 202 | |
| 203 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 204 | if (rtState == eRfOff && |
| 205 | ChangeSource >= RF_CHANGE_BY_HW) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 206 | bConnectBySSID = true; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 207 | } else { |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 208 | RT_TRACE((COMP_PS | COMP_RF), |
Mateusz Kulikowski | f434f9d | 2015-07-19 19:28:06 +0200 | [diff] [blame] | 209 | "rtl92e_set_rf_state - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 210 | priv->rtllib->RfOffReason, ChangeSource); |
| 211 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 212 | |
| 213 | break; |
| 214 | |
| 215 | case eRfOff: |
| 216 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 217 | if ((priv->rtllib->iw_mode == IW_MODE_INFRA) || |
| 218 | (priv->rtllib->iw_mode == IW_MODE_ADHOC)) { |
| 219 | if ((priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) || |
| 220 | (ChangeSource > RF_CHANGE_BY_IPS)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 221 | if (ieee->state == RTLLIB_LINKED) |
| 222 | priv->blinked_ingpio = true; |
| 223 | else |
| 224 | priv->blinked_ingpio = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 225 | rtllib_MgntDisconnect(priv->rtllib, |
Paul Gortmaker | acd442d | 2015-04-27 01:25:41 -0400 | [diff] [blame] | 226 | WLAN_REASON_DISASSOC_STA_HAS_LEFT); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 227 | } |
| 228 | } |
Valentina Manea | 4bb0142 | 2013-10-25 11:28:10 +0300 | [diff] [blame] | 229 | if ((ChangeSource == RF_CHANGE_BY_HW) && !priv->bHwRadioOff) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 230 | priv->bHwRadioOff = true; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 231 | priv->rtllib->RfOffReason |= ChangeSource; |
| 232 | bActionAllowed = true; |
| 233 | break; |
| 234 | |
| 235 | case eRfSleep: |
| 236 | priv->rtllib->RfOffReason |= ChangeSource; |
| 237 | bActionAllowed = true; |
| 238 | break; |
| 239 | |
| 240 | default: |
| 241 | break; |
| 242 | } |
| 243 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 244 | if (bActionAllowed) { |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 245 | RT_TRACE((COMP_PS | COMP_RF), |
Mateusz Kulikowski | f434f9d | 2015-07-19 19:28:06 +0200 | [diff] [blame] | 246 | "rtl92e_set_rf_state(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 247 | StateToSet, priv->rtllib->RfOffReason); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 248 | PHY_SetRFPowerState(dev, StateToSet); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 249 | if (StateToSet == eRfOn) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 250 | |
Valentina Manea | 4bb0142 | 2013-10-25 11:28:10 +0300 | [diff] [blame] | 251 | if (bConnectBySSID && priv->blinked_ingpio) { |
Amitoj Kaur Chawla | 354605f | 2016-02-20 15:36:26 +0530 | [diff] [blame] | 252 | schedule_delayed_work( |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 253 | &ieee->associate_procedure_wq, 0); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 254 | priv->blinked_ingpio = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 255 | } |
| 256 | } |
| 257 | } else { |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 258 | RT_TRACE((COMP_PS | COMP_RF), |
Mateusz Kulikowski | f434f9d | 2015-07-19 19:28:06 +0200 | [diff] [blame] | 259 | "rtl92e_set_rf_state(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 260 | StateToSet, ChangeSource, priv->rtllib->RfOffReason); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 261 | } |
| 262 | |
Mateusz Kulikowski | 2937a5d | 2015-07-28 23:31:41 +0200 | [diff] [blame] | 263 | spin_lock_irqsave(&priv->rf_ps_lock, flag); |
| 264 | priv->RFChangeInProgress = false; |
| 265 | spin_unlock_irqrestore(&priv->rf_ps_lock, flag); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 266 | |
Mateusz Kulikowski | f434f9d | 2015-07-19 19:28:06 +0200 | [diff] [blame] | 267 | RT_TRACE((COMP_PS | COMP_RF), "<===rtl92e_set_rf_state()\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 268 | return bActionAllowed; |
| 269 | } |
| 270 | |
Mateusz Kulikowski | 288adaf | 2015-09-20 10:14:13 +0200 | [diff] [blame] | 271 | static short _rtl92e_check_nic_enough_desc(struct net_device *dev, int prio) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 272 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 273 | struct r8192_priv *priv = rtllib_priv(dev); |
| 274 | struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 275 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 276 | if (ring->entries - skb_queue_len(&ring->queue) >= 2) |
| 277 | return 1; |
| 278 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 279 | } |
| 280 | |
Mateusz Kulikowski | ac39265 | 2015-09-20 10:13:07 +0200 | [diff] [blame] | 281 | static void _rtl92e_tx_timeout(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 282 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 283 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 284 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 285 | schedule_work(&priv->reset_wq); |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 286 | netdev_info(dev, "TXTIMEOUT"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 287 | } |
| 288 | |
Mateusz Kulikowski | b74299c | 2015-07-19 19:28:15 +0200 | [diff] [blame] | 289 | void rtl92e_irq_enable(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 290 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 291 | struct r8192_priv *priv = rtllib_priv(dev); |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 292 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 293 | priv->irq_enabled = 1; |
| 294 | |
| 295 | priv->ops->irq_enable(dev); |
| 296 | } |
| 297 | |
Mateusz Kulikowski | b7b50d6 | 2015-07-19 19:28:14 +0200 | [diff] [blame] | 298 | void rtl92e_irq_disable(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 299 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 300 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 301 | |
| 302 | priv->ops->irq_disable(dev); |
| 303 | |
| 304 | priv->irq_enabled = 0; |
| 305 | } |
| 306 | |
Mateusz Kulikowski | 5da06ad | 2015-09-20 10:13:32 +0200 | [diff] [blame] | 307 | static void _rtl92e_set_chan(struct net_device *dev, short ch) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 308 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 309 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 310 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 311 | RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __func__, ch); |
| 312 | if (priv->chan_forced) |
| 313 | return; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 314 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 315 | priv->chan = ch; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 316 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 317 | if (priv->rf_set_chan) |
| 318 | priv->rf_set_chan(dev, priv->chan); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 319 | } |
| 320 | |
Mateusz Kulikowski | 9a99c56 | 2015-09-20 10:13:37 +0200 | [diff] [blame] | 321 | static void _rtl92e_update_cap(struct net_device *dev, u16 cap) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 322 | { |
| 323 | struct r8192_priv *priv = rtllib_priv(dev); |
| 324 | struct rtllib_network *net = &priv->rtllib->current_network; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 325 | bool ShortPreamble; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 326 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 327 | if (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) { |
| 328 | if (priv->dot11CurrentPreambleMode != PREAMBLE_SHORT) { |
| 329 | ShortPreamble = true; |
| 330 | priv->dot11CurrentPreambleMode = PREAMBLE_SHORT; |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 331 | RT_TRACE(COMP_DBG, |
| 332 | "%s(): WLAN_CAPABILITY_SHORT_PREAMBLE\n", |
| 333 | __func__); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 334 | priv->rtllib->SetHwRegHandler(dev, HW_VAR_ACK_PREAMBLE, |
| 335 | (unsigned char *)&ShortPreamble); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 336 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 337 | } else { |
| 338 | if (priv->dot11CurrentPreambleMode != PREAMBLE_LONG) { |
| 339 | ShortPreamble = false; |
| 340 | priv->dot11CurrentPreambleMode = PREAMBLE_LONG; |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 341 | RT_TRACE(COMP_DBG, |
| 342 | "%s(): WLAN_CAPABILITY_LONG_PREAMBLE\n", |
| 343 | __func__); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 344 | priv->rtllib->SetHwRegHandler(dev, HW_VAR_ACK_PREAMBLE, |
| 345 | (unsigned char *)&ShortPreamble); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 346 | } |
| 347 | } |
| 348 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 349 | if (net->mode & (IEEE_G|IEEE_N_24G)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 350 | u8 slot_time_val; |
| 351 | u8 CurSlotTime = priv->slot_time; |
| 352 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 353 | if ((cap & WLAN_CAPABILITY_SHORT_SLOT_TIME) && |
| 354 | (!priv->rtllib->pHTInfo->bCurrentRT2RTLongSlotTime)) { |
| 355 | if (CurSlotTime != SHORT_SLOT_TIME) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 356 | slot_time_val = SHORT_SLOT_TIME; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 357 | priv->rtllib->SetHwRegHandler(dev, |
| 358 | HW_VAR_SLOT_TIME, &slot_time_val); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 359 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 360 | } else { |
| 361 | if (CurSlotTime != NON_SHORT_SLOT_TIME) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 362 | slot_time_val = NON_SHORT_SLOT_TIME; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 363 | priv->rtllib->SetHwRegHandler(dev, |
| 364 | HW_VAR_SLOT_TIME, &slot_time_val); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 365 | } |
| 366 | } |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | static struct rtllib_qos_parameters def_qos_parameters = { |
Rashika Kheria | 34e987e | 2013-11-07 19:15:48 +0530 | [diff] [blame] | 371 | {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)}, |
| 372 | {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)}, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 373 | {2, 2, 2, 2}, |
| 374 | {0, 0, 0, 0}, |
| 375 | {0, 0, 0, 0} |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 376 | }; |
| 377 | |
Mateusz Kulikowski | dc88840 | 2015-09-20 10:13:36 +0200 | [diff] [blame] | 378 | static void _rtl92e_update_beacon(void *data) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 379 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 380 | struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv, |
| 381 | update_beacon_wq.work); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 382 | struct net_device *dev = priv->rtllib->dev; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 383 | struct rtllib_device *ieee = priv->rtllib; |
| 384 | struct rtllib_network *net = &ieee->current_network; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 385 | |
| 386 | if (ieee->pHTInfo->bCurrentHTSupport) |
Sean MacLennan | 976d534 | 2011-11-30 15:18:52 -0500 | [diff] [blame] | 387 | HT_update_self_and_peer_setting(ieee, net); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 388 | ieee->pHTInfo->bCurrentRT2RTLongSlotTime = |
| 389 | net->bssht.bdRT2RTLongSlotTime; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 390 | ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode; |
Mateusz Kulikowski | 9a99c56 | 2015-09-20 10:13:37 +0200 | [diff] [blame] | 391 | _rtl92e_update_cap(dev, net->capability); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 392 | } |
| 393 | |
Mateusz Kulikowski | ae1fe0d | 2015-09-20 10:13:28 +0200 | [diff] [blame] | 394 | static void _rtl92e_qos_activate(void *data) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 395 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 396 | struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv, |
| 397 | qos_activate); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 398 | struct net_device *dev = priv->rtllib->dev; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 399 | int i; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 400 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 401 | mutex_lock(&priv->mutex); |
| 402 | if (priv->rtllib->state != RTLLIB_LINKED) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 403 | goto success; |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 404 | RT_TRACE(COMP_QOS, |
| 405 | "qos active process with associate response received\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 406 | |
Vaishali Thakkar | fe40a0b | 2014-09-17 08:35:24 +0530 | [diff] [blame] | 407 | for (i = 0; i < QOS_QUEUE_NUM; i++) |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 408 | priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, (u8 *)(&i)); |
Vaishali Thakkar | fe40a0b | 2014-09-17 08:35:24 +0530 | [diff] [blame] | 409 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 410 | |
| 411 | success: |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 412 | mutex_unlock(&priv->mutex); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 413 | } |
| 414 | |
Mateusz Kulikowski | c5d0d6f | 2015-09-20 10:13:30 +0200 | [diff] [blame] | 415 | static int _rtl92e_qos_handle_probe_response(struct r8192_priv *priv, |
| 416 | int active_network, |
| 417 | struct rtllib_network *network) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 418 | { |
| 419 | int ret = 0; |
| 420 | u32 size = sizeof(struct rtllib_qos_parameters); |
| 421 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 422 | if (priv->rtllib->state != RTLLIB_LINKED) |
| 423 | return ret; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 424 | |
Mateusz Kulikowski | 025b8bb | 2015-04-01 00:24:29 +0200 | [diff] [blame] | 425 | if (priv->rtllib->iw_mode != IW_MODE_INFRA) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 426 | return ret; |
| 427 | |
| 428 | if (network->flags & NETWORK_HAS_QOS_MASK) { |
| 429 | if (active_network && |
| 430 | (network->flags & NETWORK_HAS_QOS_PARAMETERS)) |
| 431 | network->qos_data.active = network->qos_data.supported; |
| 432 | |
| 433 | if ((network->qos_data.active == 1) && (active_network == 1) && |
| 434 | (network->flags & NETWORK_HAS_QOS_PARAMETERS) && |
| 435 | (network->qos_data.old_param_count != |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 436 | network->qos_data.param_count)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 437 | network->qos_data.old_param_count = |
| 438 | network->qos_data.param_count; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 439 | priv->rtllib->wmm_acm = network->qos_data.wmm_acm; |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 440 | schedule_work(&priv->qos_activate); |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 441 | RT_TRACE(COMP_QOS, |
| 442 | "QoS parameters change call qos_activate\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 443 | } |
| 444 | } else { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 445 | memcpy(&priv->rtllib->current_network.qos_data.parameters, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 446 | &def_qos_parameters, size); |
| 447 | |
| 448 | if ((network->qos_data.active == 1) && (active_network == 1)) { |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 449 | schedule_work(&priv->qos_activate); |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 450 | RT_TRACE(COMP_QOS, |
| 451 | "QoS was disabled call qos_activate\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 452 | } |
| 453 | network->qos_data.active = 0; |
| 454 | network->qos_data.supported = 0; |
| 455 | } |
| 456 | |
| 457 | return 0; |
| 458 | } |
| 459 | |
Mateusz Kulikowski | 5341f07 | 2015-09-20 10:13:47 +0200 | [diff] [blame] | 460 | static int _rtl92e_handle_beacon(struct net_device *dev, |
| 461 | struct rtllib_beacon *beacon, |
| 462 | struct rtllib_network *network) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 463 | { |
| 464 | struct r8192_priv *priv = rtllib_priv(dev); |
| 465 | |
Mateusz Kulikowski | c5d0d6f | 2015-09-20 10:13:30 +0200 | [diff] [blame] | 466 | _rtl92e_qos_handle_probe_response(priv, 1, network); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 467 | |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 468 | schedule_delayed_work(&priv->update_beacon_wq, 0); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 469 | return 0; |
| 470 | |
| 471 | } |
| 472 | |
Mateusz Kulikowski | 24bee78 | 2015-09-20 10:13:29 +0200 | [diff] [blame] | 473 | static int _rtl92e_qos_assoc_resp(struct r8192_priv *priv, |
| 474 | struct rtllib_network *network) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 475 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 476 | unsigned long flags; |
| 477 | u32 size = sizeof(struct rtllib_qos_parameters); |
| 478 | int set_qos_param = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 479 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 480 | if ((priv == NULL) || (network == NULL)) |
Vaishali Thakkar | 5c8b396 | 2014-09-17 08:02:43 +0530 | [diff] [blame] | 481 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 482 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 483 | if (priv->rtllib->state != RTLLIB_LINKED) |
Vaishali Thakkar | 5c8b396 | 2014-09-17 08:02:43 +0530 | [diff] [blame] | 484 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 485 | |
Mateusz Kulikowski | 025b8bb | 2015-04-01 00:24:29 +0200 | [diff] [blame] | 486 | if (priv->rtllib->iw_mode != IW_MODE_INFRA) |
Vaishali Thakkar | 5c8b396 | 2014-09-17 08:02:43 +0530 | [diff] [blame] | 487 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 488 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 489 | spin_lock_irqsave(&priv->rtllib->lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 490 | if (network->flags & NETWORK_HAS_QOS_PARAMETERS) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 491 | memcpy(&priv->rtllib->current_network.qos_data.parameters, |
| 492 | &network->qos_data.parameters, |
| 493 | sizeof(struct rtllib_qos_parameters)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 494 | priv->rtllib->current_network.qos_data.active = 1; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 495 | priv->rtllib->wmm_acm = network->qos_data.wmm_acm; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 496 | set_qos_param = 1; |
| 497 | priv->rtllib->current_network.qos_data.old_param_count = |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 498 | priv->rtllib->current_network.qos_data.param_count; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 499 | priv->rtllib->current_network.qos_data.param_count = |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 500 | network->qos_data.param_count; |
| 501 | } else { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 502 | memcpy(&priv->rtllib->current_network.qos_data.parameters, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 503 | &def_qos_parameters, size); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 504 | priv->rtllib->current_network.qos_data.active = 0; |
| 505 | priv->rtllib->current_network.qos_data.supported = 0; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 506 | set_qos_param = 1; |
| 507 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 508 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 509 | spin_unlock_irqrestore(&priv->rtllib->lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 510 | |
| 511 | RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __func__, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 512 | network->flags, priv->rtllib->current_network.qos_data.active); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 513 | if (set_qos_param == 1) { |
Mateusz Kulikowski | 7842c2d | 2015-07-19 19:28:32 +0200 | [diff] [blame] | 514 | rtl92e_dm_init_edca_turbo(priv->rtllib->dev); |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 515 | schedule_work(&priv->qos_activate); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 516 | } |
Vaishali Thakkar | 5c8b396 | 2014-09-17 08:02:43 +0530 | [diff] [blame] | 517 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 518 | } |
| 519 | |
Mateusz Kulikowski | 8b5a803 | 2015-09-20 10:13:46 +0200 | [diff] [blame] | 520 | static int _rtl92e_handle_assoc_response(struct net_device *dev, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 521 | struct rtllib_assoc_response_frame *resp, |
| 522 | struct rtllib_network *network) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 523 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 524 | struct r8192_priv *priv = rtllib_priv(dev); |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 525 | |
Mateusz Kulikowski | 24bee78 | 2015-09-20 10:13:29 +0200 | [diff] [blame] | 526 | _rtl92e_qos_assoc_resp(priv, network); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 527 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 528 | } |
| 529 | |
Mateusz Kulikowski | e009a84 | 2015-09-20 10:13:27 +0200 | [diff] [blame] | 530 | static void _rtl92e_prepare_beacon(struct r8192_priv *priv) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 531 | { |
| 532 | struct net_device *dev = priv->rtllib->dev; |
| 533 | struct sk_buff *pskb = NULL, *pnewskb = NULL; |
Larry Finger | 3b83db4 | 2011-07-19 00:01:29 -0500 | [diff] [blame] | 534 | struct cb_desc *tcb_desc = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 535 | struct rtl8192_tx_ring *ring = NULL; |
Larry Finger | bc27e89 | 2011-07-18 22:27:06 -0500 | [diff] [blame] | 536 | struct tx_desc *pdesc = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 537 | |
| 538 | ring = &priv->tx_ring[BEACON_QUEUE]; |
| 539 | pskb = __skb_dequeue(&ring->queue); |
Wei Yongjun | 085b501 | 2012-08-28 21:10:35 +0800 | [diff] [blame] | 540 | kfree_skb(pskb); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 541 | |
| 542 | pnewskb = rtllib_get_beacon(priv->rtllib); |
| 543 | if (!pnewskb) |
| 544 | return; |
| 545 | |
Larry Finger | 3b83db4 | 2011-07-19 00:01:29 -0500 | [diff] [blame] | 546 | tcb_desc = (struct cb_desc *)(pnewskb->cb + 8); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 547 | tcb_desc->queue_index = BEACON_QUEUE; |
| 548 | tcb_desc->data_rate = 2; |
| 549 | tcb_desc->RATRIndex = 7; |
| 550 | tcb_desc->bTxDisableRateFallBack = 1; |
| 551 | tcb_desc->bTxUseDriverAssingedRate = 1; |
| 552 | skb_push(pnewskb, priv->rtllib->tx_headroom); |
| 553 | |
| 554 | pdesc = &ring->desc[0]; |
| 555 | priv->ops->tx_fill_descriptor(dev, pdesc, tcb_desc, pnewskb); |
| 556 | __skb_queue_tail(&ring->queue, pnewskb); |
| 557 | pdesc->OWN = 1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 558 | } |
| 559 | |
Mateusz Kulikowski | f2f08fc | 2015-09-20 10:13:35 +0200 | [diff] [blame] | 560 | static void _rtl92e_stop_beacon(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 561 | { |
| 562 | } |
| 563 | |
Mateusz Kulikowski | 122fe9f | 2015-07-19 19:28:13 +0200 | [diff] [blame] | 564 | void rtl92e_config_rate(struct net_device *dev, u16 *rate_config) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 565 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 566 | struct r8192_priv *priv = rtllib_priv(dev); |
| 567 | struct rtllib_network *net; |
| 568 | u8 i = 0, basic_rate = 0; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 569 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 570 | net = &priv->rtllib->current_network; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 571 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 572 | for (i = 0; i < net->rates_len; i++) { |
| 573 | basic_rate = net->rates[i] & 0x7f; |
| 574 | switch (basic_rate) { |
| 575 | case MGN_1M: |
| 576 | *rate_config |= RRSR_1M; |
| 577 | break; |
| 578 | case MGN_2M: |
| 579 | *rate_config |= RRSR_2M; |
| 580 | break; |
| 581 | case MGN_5_5M: |
| 582 | *rate_config |= RRSR_5_5M; |
| 583 | break; |
| 584 | case MGN_11M: |
| 585 | *rate_config |= RRSR_11M; |
| 586 | break; |
| 587 | case MGN_6M: |
| 588 | *rate_config |= RRSR_6M; |
| 589 | break; |
| 590 | case MGN_9M: |
| 591 | *rate_config |= RRSR_9M; |
| 592 | break; |
| 593 | case MGN_12M: |
| 594 | *rate_config |= RRSR_12M; |
| 595 | break; |
| 596 | case MGN_18M: |
| 597 | *rate_config |= RRSR_18M; |
| 598 | break; |
| 599 | case MGN_24M: |
| 600 | *rate_config |= RRSR_24M; |
| 601 | break; |
| 602 | case MGN_36M: |
| 603 | *rate_config |= RRSR_36M; |
| 604 | break; |
| 605 | case MGN_48M: |
| 606 | *rate_config |= RRSR_48M; |
| 607 | break; |
| 608 | case MGN_54M: |
| 609 | *rate_config |= RRSR_54M; |
| 610 | break; |
| 611 | } |
| 612 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 613 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 614 | for (i = 0; i < net->rates_ex_len; i++) { |
| 615 | basic_rate = net->rates_ex[i] & 0x7f; |
| 616 | switch (basic_rate) { |
| 617 | case MGN_1M: |
| 618 | *rate_config |= RRSR_1M; |
| 619 | break; |
| 620 | case MGN_2M: |
| 621 | *rate_config |= RRSR_2M; |
| 622 | break; |
| 623 | case MGN_5_5M: |
| 624 | *rate_config |= RRSR_5_5M; |
| 625 | break; |
| 626 | case MGN_11M: |
| 627 | *rate_config |= RRSR_11M; |
| 628 | break; |
| 629 | case MGN_6M: |
| 630 | *rate_config |= RRSR_6M; |
| 631 | break; |
| 632 | case MGN_9M: |
| 633 | *rate_config |= RRSR_9M; |
| 634 | break; |
| 635 | case MGN_12M: |
| 636 | *rate_config |= RRSR_12M; |
| 637 | break; |
| 638 | case MGN_18M: |
| 639 | *rate_config |= RRSR_18M; |
| 640 | break; |
| 641 | case MGN_24M: |
| 642 | *rate_config |= RRSR_24M; |
| 643 | break; |
| 644 | case MGN_36M: |
| 645 | *rate_config |= RRSR_36M; |
| 646 | break; |
| 647 | case MGN_48M: |
| 648 | *rate_config |= RRSR_48M; |
| 649 | break; |
| 650 | case MGN_54M: |
| 651 | *rate_config |= RRSR_54M; |
| 652 | break; |
| 653 | } |
| 654 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 655 | } |
| 656 | |
Mateusz Kulikowski | 422c8be | 2015-09-20 10:13:31 +0200 | [diff] [blame] | 657 | static void _rtl92e_refresh_support_rate(struct r8192_priv *priv) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 658 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 659 | struct rtllib_device *ieee = priv->rtllib; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 660 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 661 | if (ieee->mode == WIRELESS_MODE_N_24G || |
| 662 | ieee->mode == WIRELESS_MODE_N_5G) { |
| 663 | memcpy(ieee->Regdot11HTOperationalRateSet, |
| 664 | ieee->RegHTSuppRateSet, 16); |
| 665 | memcpy(ieee->Regdot11TxHTOperationalRateSet, |
| 666 | ieee->RegHTSuppRateSet, 16); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 667 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 668 | } else { |
| 669 | memset(ieee->Regdot11HTOperationalRateSet, 0, 16); |
| 670 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 671 | } |
| 672 | |
Mateusz Kulikowski | ee394a7 | 2015-09-20 10:13:45 +0200 | [diff] [blame] | 673 | static u8 _rtl92e_get_supported_wireless_mode(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 674 | { |
| 675 | struct r8192_priv *priv = rtllib_priv(dev); |
| 676 | u8 ret = 0; |
| 677 | |
| 678 | switch (priv->rf_chip) { |
| 679 | case RF_8225: |
| 680 | case RF_8256: |
| 681 | case RF_6052: |
| 682 | case RF_PSEUDO_11N: |
| 683 | ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G | WIRELESS_MODE_B); |
| 684 | break; |
| 685 | case RF_8258: |
| 686 | ret = (WIRELESS_MODE_A | WIRELESS_MODE_N_5G); |
| 687 | break; |
| 688 | default: |
| 689 | ret = WIRELESS_MODE_B; |
| 690 | break; |
| 691 | } |
| 692 | return ret; |
| 693 | } |
| 694 | |
Mateusz Kulikowski | 35bf848 | 2015-07-19 19:28:19 +0200 | [diff] [blame] | 695 | void rtl92e_set_wireless_mode(struct net_device *dev, u8 wireless_mode) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 696 | { |
| 697 | struct r8192_priv *priv = rtllib_priv(dev); |
Mateusz Kulikowski | ee394a7 | 2015-09-20 10:13:45 +0200 | [diff] [blame] | 698 | u8 bSupportMode = _rtl92e_get_supported_wireless_mode(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 699 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 700 | if ((wireless_mode == WIRELESS_MODE_AUTO) || |
| 701 | ((wireless_mode & bSupportMode) == 0)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 702 | if (bSupportMode & WIRELESS_MODE_N_24G) { |
| 703 | wireless_mode = WIRELESS_MODE_N_24G; |
| 704 | } else if (bSupportMode & WIRELESS_MODE_N_5G) { |
| 705 | wireless_mode = WIRELESS_MODE_N_5G; |
| 706 | } else if ((bSupportMode & WIRELESS_MODE_A)) { |
| 707 | wireless_mode = WIRELESS_MODE_A; |
| 708 | } else if ((bSupportMode & WIRELESS_MODE_G)) { |
| 709 | wireless_mode = WIRELESS_MODE_G; |
| 710 | } else if ((bSupportMode & WIRELESS_MODE_B)) { |
| 711 | wireless_mode = WIRELESS_MODE_B; |
| 712 | } else { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 713 | netdev_info(dev, |
| 714 | "%s(): Unsupported mode requested. Fallback to 802.11b\n", |
| 715 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 716 | wireless_mode = WIRELESS_MODE_B; |
| 717 | } |
| 718 | } |
| 719 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 720 | if ((wireless_mode & (WIRELESS_MODE_B | WIRELESS_MODE_G)) == |
| 721 | (WIRELESS_MODE_G | WIRELESS_MODE_B)) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 722 | wireless_mode = WIRELESS_MODE_G; |
| 723 | |
| 724 | priv->rtllib->mode = wireless_mode; |
| 725 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 726 | if ((wireless_mode == WIRELESS_MODE_N_24G) || |
| 727 | (wireless_mode == WIRELESS_MODE_N_5G)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 728 | priv->rtllib->pHTInfo->bEnableHT = 1; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 729 | RT_TRACE(COMP_DBG, "%s(), wireless_mode:%x, bEnableHT = 1\n", |
| 730 | __func__, wireless_mode); |
| 731 | } else { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 732 | priv->rtllib->pHTInfo->bEnableHT = 0; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 733 | RT_TRACE(COMP_DBG, "%s(), wireless_mode:%x, bEnableHT = 0\n", |
| 734 | __func__, wireless_mode); |
| 735 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 736 | |
| 737 | RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode); |
Mateusz Kulikowski | 422c8be | 2015-09-20 10:13:31 +0200 | [diff] [blame] | 738 | _rtl92e_refresh_support_rate(priv); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 739 | } |
| 740 | |
Mateusz Kulikowski | dba0e06 | 2015-09-20 10:13:34 +0200 | [diff] [blame] | 741 | static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 742 | { |
| 743 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 744 | struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) |
| 745 | (&(priv->rtllib->PowerSaveControl)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 746 | bool init_status = true; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 747 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 748 | priv->bDriverIsGoingToUnload = false; |
| 749 | priv->bdisable_nic = false; |
| 750 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 751 | priv->up = 1; |
| 752 | priv->rtllib->ieee_up = 1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 753 | |
| 754 | priv->up_first_time = 0; |
| 755 | RT_TRACE(COMP_INIT, "Bringing up iface"); |
| 756 | priv->bfirst_init = true; |
| 757 | init_status = priv->ops->initialize_adapter(dev); |
Valentina Manea | 4bb0142 | 2013-10-25 11:28:10 +0300 | [diff] [blame] | 758 | if (!init_status) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 759 | netdev_err(dev, "%s(): Initialization failed!\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 760 | priv->bfirst_init = false; |
| 761 | return -1; |
| 762 | } |
| 763 | |
| 764 | RT_TRACE(COMP_INIT, "start adapter finished\n"); |
| 765 | RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); |
| 766 | priv->bfirst_init = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 767 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 768 | if (priv->polling_timer_on == 0) |
Mateusz Kulikowski | a643d92 | 2015-07-19 19:28:05 +0200 | [diff] [blame] | 769 | rtl92e_check_rfctrl_gpio_timer((unsigned long)dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 770 | |
| 771 | if (priv->rtllib->state != RTLLIB_LINKED) |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 772 | rtllib_softmac_start_protocol(priv->rtllib, 0); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 773 | rtllib_reset_queue(priv->rtllib); |
Mateusz Kulikowski | 2cfc375 | 2015-09-20 10:13:43 +0200 | [diff] [blame] | 774 | _rtl92e_watchdog_timer_cb((unsigned long)dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 775 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 776 | if (!netif_queue_stopped(dev)) |
| 777 | netif_start_queue(dev); |
| 778 | else |
| 779 | netif_wake_queue(dev); |
| 780 | |
| 781 | return 0; |
| 782 | } |
| 783 | |
Mateusz Kulikowski | 2b19e22 | 2015-09-20 10:13:33 +0200 | [diff] [blame] | 784 | static int _rtl92e_sta_down(struct net_device *dev, bool shutdownrf) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 785 | { |
| 786 | struct r8192_priv *priv = rtllib_priv(dev); |
| 787 | unsigned long flags = 0; |
| 788 | u8 RFInProgressTimeOut = 0; |
| 789 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 790 | if (priv->up == 0) |
| 791 | return -1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 792 | |
| 793 | if (priv->rtllib->rtllib_ips_leave != NULL) |
| 794 | priv->rtllib->rtllib_ips_leave(dev); |
| 795 | |
| 796 | if (priv->rtllib->state == RTLLIB_LINKED) |
Mateusz Kulikowski | 9c4a55d | 2015-07-19 19:33:50 +0200 | [diff] [blame] | 797 | rtl92e_leisure_ps_leave(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 798 | |
| 799 | priv->bDriverIsGoingToUnload = true; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 800 | priv->up = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 801 | priv->rtllib->ieee_up = 0; |
Valentina Manea | 014e4c2 | 2013-10-29 20:58:48 +0200 | [diff] [blame] | 802 | priv->bfirst_after_down = true; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 803 | RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__); |
| 804 | if (!netif_queue_stopped(dev)) |
| 805 | netif_stop_queue(dev); |
| 806 | |
| 807 | priv->rtllib->wpa_ie_len = 0; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 808 | kfree(priv->rtllib->wpa_ie); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 809 | priv->rtllib->wpa_ie = NULL; |
Mateusz Kulikowski | 358e4ee | 2015-07-19 19:28:00 +0200 | [diff] [blame] | 810 | rtl92e_cam_reset(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 811 | memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); |
Mateusz Kulikowski | b7b50d6 | 2015-07-19 19:28:14 +0200 | [diff] [blame] | 812 | rtl92e_irq_disable(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 813 | |
| 814 | del_timer_sync(&priv->watch_dog_timer); |
Mateusz Kulikowski | 4dba03a | 2015-09-20 10:14:12 +0200 | [diff] [blame] | 815 | _rtl92e_cancel_deferred_work(priv); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 816 | cancel_delayed_work(&priv->rtllib->hw_wakeup_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 817 | |
| 818 | rtllib_softmac_stop_protocol(priv->rtllib, 0, true); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 819 | spin_lock_irqsave(&priv->rf_ps_lock, flags); |
| 820 | while (priv->RFChangeInProgress) { |
| 821 | spin_unlock_irqrestore(&priv->rf_ps_lock, flags); |
| 822 | if (RFInProgressTimeOut > 100) { |
| 823 | spin_lock_irqsave(&priv->rf_ps_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 824 | break; |
| 825 | } |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 826 | RT_TRACE(COMP_DBG, |
| 827 | "===>%s():RF is in progress, need to wait until rf change is done.\n", |
| 828 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 829 | mdelay(1); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 830 | RFInProgressTimeOut++; |
| 831 | spin_lock_irqsave(&priv->rf_ps_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 832 | } |
| 833 | priv->RFChangeInProgress = true; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 834 | spin_unlock_irqrestore(&priv->rf_ps_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 835 | priv->ops->stop_adapter(dev, false); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 836 | spin_lock_irqsave(&priv->rf_ps_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 837 | priv->RFChangeInProgress = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 838 | spin_unlock_irqrestore(&priv->rf_ps_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 839 | udelay(100); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 840 | memset(&priv->rtllib->current_network, 0, |
| 841 | offsetof(struct rtllib_network, list)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 842 | RT_TRACE(COMP_DOWN, "<==========%s()\n", __func__); |
| 843 | |
| 844 | return 0; |
| 845 | } |
| 846 | |
Mateusz Kulikowski | b8d0dc3 | 2015-09-20 10:09:24 +0200 | [diff] [blame] | 847 | static void _rtl92e_init_priv_handler(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 848 | { |
| 849 | struct r8192_priv *priv = rtllib_priv(dev); |
| 850 | |
Mateusz Kulikowski | 3e49f3e | 2015-09-20 10:13:49 +0200 | [diff] [blame] | 851 | priv->rtllib->softmac_hard_start_xmit = _rtl92e_hard_start_xmit; |
Mateusz Kulikowski | 5da06ad | 2015-09-20 10:13:32 +0200 | [diff] [blame] | 852 | priv->rtllib->set_chan = _rtl92e_set_chan; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 853 | priv->rtllib->link_change = priv->ops->link_change; |
Mateusz Kulikowski | 52a7404 | 2015-09-20 10:13:48 +0200 | [diff] [blame] | 854 | priv->rtllib->softmac_data_hard_start_xmit = _rtl92e_hard_data_xmit; |
Mateusz Kulikowski | 288adaf | 2015-09-20 10:14:13 +0200 | [diff] [blame] | 855 | priv->rtllib->check_nic_enough_desc = _rtl92e_check_nic_enough_desc; |
Mateusz Kulikowski | 8b5a803 | 2015-09-20 10:13:46 +0200 | [diff] [blame] | 856 | priv->rtllib->handle_assoc_response = _rtl92e_handle_assoc_response; |
Mateusz Kulikowski | 5341f07 | 2015-09-20 10:13:47 +0200 | [diff] [blame] | 857 | priv->rtllib->handle_beacon = _rtl92e_handle_beacon; |
Mateusz Kulikowski | 35bf848 | 2015-07-19 19:28:19 +0200 | [diff] [blame] | 858 | priv->rtllib->SetWirelessMode = rtl92e_set_wireless_mode; |
Mateusz Kulikowski | 9c4a55d | 2015-07-19 19:33:50 +0200 | [diff] [blame] | 859 | priv->rtllib->LeisurePSLeave = rtl92e_leisure_ps_leave; |
Mateusz Kulikowski | ae924ac | 2015-07-19 19:27:58 +0200 | [diff] [blame] | 860 | priv->rtllib->SetBWModeHandler = rtl92e_set_bw_mode; |
Mateusz Kulikowski | 68a5143 | 2015-07-19 19:27:55 +0200 | [diff] [blame] | 861 | priv->rf_set_chan = rtl92e_set_channel; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 862 | |
Mateusz Kulikowski | 89d4a8b | 2015-07-19 19:27:27 +0200 | [diff] [blame] | 863 | priv->rtllib->start_send_beacons = rtl92e_start_beacon; |
Mateusz Kulikowski | f2f08fc | 2015-09-20 10:13:35 +0200 | [diff] [blame] | 864 | priv->rtllib->stop_send_beacons = _rtl92e_stop_beacon; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 865 | |
Mateusz Kulikowski | 43bcb3b | 2015-07-19 19:33:53 +0200 | [diff] [blame] | 866 | priv->rtllib->sta_wake_up = rtl92e_hw_wakeup; |
Mateusz Kulikowski | feb257e | 2015-07-19 19:33:52 +0200 | [diff] [blame] | 867 | priv->rtllib->enter_sleep_state = rtl92e_enter_sleep; |
Mateusz Kulikowski | 6f8d4a7 | 2015-09-20 10:13:09 +0200 | [diff] [blame] | 868 | priv->rtllib->ps_is_queue_empty = _rtl92e_is_tx_queue_empty; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 869 | |
Mateusz Kulikowski | 56a5b5a | 2015-07-19 19:27:30 +0200 | [diff] [blame] | 870 | priv->rtllib->GetNmodeSupportBySecCfg = rtl92e_get_nmode_support_by_sec; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 871 | priv->rtllib->GetHalfNmodeSupportByAPsHandler = |
Mateusz Kulikowski | 86534a2 | 2015-07-19 19:27:29 +0200 | [diff] [blame] | 872 | rtl92e_is_halfn_supported_by_ap; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 873 | |
Mateusz Kulikowski | 61fea23 | 2015-07-19 19:27:26 +0200 | [diff] [blame] | 874 | priv->rtllib->SetHwRegHandler = rtl92e_set_reg; |
Mateusz Kulikowski | 33e1748 | 2015-07-19 19:27:20 +0200 | [diff] [blame] | 875 | priv->rtllib->AllowAllDestAddrHandler = rtl92e_set_monitor_mode; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 876 | priv->rtllib->SetFwCmdHandler = NULL; |
Mateusz Kulikowski | dfb7a12 | 2015-07-19 19:27:42 +0200 | [diff] [blame] | 877 | priv->rtllib->InitialGainHandler = rtl92e_init_gain; |
Mateusz Kulikowski | d66e938 | 2015-07-19 19:33:56 +0200 | [diff] [blame] | 878 | priv->rtllib->rtllib_ips_leave_wq = rtl92e_rtllib_ips_leave_wq; |
Mateusz Kulikowski | bf135a1 | 2015-07-19 19:33:55 +0200 | [diff] [blame] | 879 | priv->rtllib->rtllib_ips_leave = rtl92e_rtllib_ips_leave; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 880 | |
| 881 | priv->rtllib->LedControlHandler = NULL; |
| 882 | priv->rtllib->UpdateBeaconInterruptHandler = NULL; |
| 883 | |
Mateusz Kulikowski | 9a44c6e | 2015-07-19 19:27:43 +0200 | [diff] [blame] | 884 | priv->rtllib->ScanOperationBackupHandler = rtl92e_scan_op_backup; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 885 | } |
| 886 | |
Mateusz Kulikowski | 6b2aaea | 2015-09-20 10:09:23 +0200 | [diff] [blame] | 887 | static void _rtl92e_init_priv_constant(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 888 | { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 889 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 890 | struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) |
| 891 | &(priv->rtllib->PowerSaveControl); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 892 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 893 | pPSC->RegMaxLPSAwakeIntvl = 5; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 894 | } |
| 895 | |
| 896 | |
Mateusz Kulikowski | 414f401 | 2015-09-20 10:09:27 +0200 | [diff] [blame] | 897 | static void _rtl92e_init_priv_variable(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 898 | { |
| 899 | struct r8192_priv *priv = rtllib_priv(dev); |
| 900 | u8 i; |
| 901 | |
| 902 | priv->AcmMethod = eAcmWay2_SW; |
| 903 | priv->dot11CurrentPreambleMode = PREAMBLE_AUTO; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 904 | priv->rtllib->status = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 905 | priv->polling_timer_on = 0; |
| 906 | priv->up_first_time = 1; |
| 907 | priv->blinked_ingpio = false; |
| 908 | priv->bDriverIsGoingToUnload = false; |
| 909 | priv->being_init_adapter = false; |
| 910 | priv->initialized_at_probe = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 911 | priv->bdisable_nic = false; |
| 912 | priv->bfirst_init = false; |
| 913 | priv->txringcount = 64; |
| 914 | priv->rxbuffersize = 9100; |
| 915 | priv->rxringcount = MAX_RX_COUNT; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 916 | priv->irq_enabled = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 917 | priv->chan = 1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 918 | priv->RegChannelPlan = 0xf; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 919 | priv->rtllib->mode = WIRELESS_MODE_AUTO; |
| 920 | priv->rtllib->iw_mode = IW_MODE_INFRA; |
| 921 | priv->rtllib->bNetPromiscuousMode = false; |
| 922 | priv->rtllib->IntelPromiscuousModeInfo.bPromiscuousOn = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 923 | priv->rtllib->IntelPromiscuousModeInfo.bFilterSourceStationFrame = |
| 924 | false; |
| 925 | priv->rtllib->ieee_up = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 926 | priv->retry_rts = DEFAULT_RETRY_RTS; |
| 927 | priv->retry_data = DEFAULT_RETRY_DATA; |
| 928 | priv->rtllib->rts = DEFAULT_RTS_THRESHOLD; |
| 929 | priv->rtllib->rate = 110; |
| 930 | priv->rtllib->short_slot = 1; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 931 | priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 932 | priv->bcck_in_ch14 = false; |
| 933 | priv->bfsync_processing = false; |
| 934 | priv->CCKPresentAttentuation = 0; |
| 935 | priv->rfa_txpowertrackingindex = 0; |
| 936 | priv->rfc_txpowertrackingindex = 0; |
| 937 | priv->CckPwEnl = 6; |
| 938 | priv->ScanDelay = 50; |
| 939 | priv->ResetProgress = RESET_TYPE_NORESET; |
Valentina Manea | 014e4c2 | 2013-10-29 20:58:48 +0200 | [diff] [blame] | 940 | priv->bForcedSilentReset = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 941 | priv->bDisableNormalResetCheck = false; |
| 942 | priv->force_reset = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 943 | memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 944 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 945 | memset(&priv->InterruptLog, 0, sizeof(struct log_int_8190)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 946 | priv->RxCounter = 0; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 947 | priv->rtllib->wx_set_enc = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 948 | priv->bHwRadioOff = false; |
Valentina Manea | 014e4c2 | 2013-10-29 20:58:48 +0200 | [diff] [blame] | 949 | priv->RegRfOff = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 950 | priv->isRFOff = false; |
| 951 | priv->bInPowerSaveMode = false; |
| 952 | priv->rtllib->RfOffReason = 0; |
| 953 | priv->RFChangeInProgress = false; |
| 954 | priv->bHwRfOffAction = 0; |
| 955 | priv->SetRFPowerStateInProgress = false; |
| 956 | priv->rtllib->PowerSaveControl.bInactivePs = true; |
| 957 | priv->rtllib->PowerSaveControl.bIPSModeBackup = false; |
| 958 | priv->rtllib->PowerSaveControl.bLeisurePs = true; |
| 959 | priv->rtllib->PowerSaveControl.bFwCtrlLPS = false; |
| 960 | priv->rtllib->LPSDelayCnt = 0; |
| 961 | priv->rtllib->sta_sleep = LPS_IS_WAKE; |
| 962 | priv->rtllib->eRFPowerState = eRfOn; |
| 963 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 964 | priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; |
| 965 | priv->rtllib->iw_mode = IW_MODE_INFRA; |
| 966 | priv->rtllib->active_scan = 1; |
| 967 | priv->rtllib->be_scan_inprogress = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 968 | priv->rtllib->modulation = RTLLIB_CCK_MODULATION | |
| 969 | RTLLIB_OFDM_MODULATION; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 970 | priv->rtllib->host_encrypt = 1; |
| 971 | priv->rtllib->host_decrypt = 1; |
| 972 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 973 | priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 974 | |
| 975 | priv->card_type = PCI; |
| 976 | |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 977 | priv->pFirmware = vzalloc(sizeof(struct rt_firmware)); |
| 978 | if (!priv->pFirmware) |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 979 | netdev_err(dev, |
| 980 | "rtl8192e: Unable to allocate space for firmware\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 981 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 982 | skb_queue_head_init(&priv->skb_queue); |
| 983 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 984 | for (i = 0; i < MAX_QUEUE_SIZE; i++) |
| 985 | skb_queue_head_init(&priv->rtllib->skb_waitQ[i]); |
| 986 | for (i = 0; i < MAX_QUEUE_SIZE; i++) |
| 987 | skb_queue_head_init(&priv->rtllib->skb_aggQ[i]); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 988 | } |
| 989 | |
Mateusz Kulikowski | 529c66c | 2015-09-20 10:09:25 +0200 | [diff] [blame] | 990 | static void _rtl92e_init_priv_lock(struct r8192_priv *priv) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 991 | { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 992 | spin_lock_init(&priv->tx_lock); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 993 | spin_lock_init(&priv->irq_th_lock); |
| 994 | spin_lock_init(&priv->rf_ps_lock); |
| 995 | spin_lock_init(&priv->ps_lock); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 996 | sema_init(&priv->wx_sem, 1); |
| 997 | sema_init(&priv->rf_sem, 1); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 998 | mutex_init(&priv->mutex); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 999 | } |
| 1000 | |
Mateusz Kulikowski | 4ab2a8f | 2015-09-20 10:09:26 +0200 | [diff] [blame] | 1001 | static void _rtl92e_init_priv_task(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1002 | { |
| 1003 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1004 | |
Mateusz Kulikowski | 78e67df | 2015-09-20 10:12:52 +0200 | [diff] [blame] | 1005 | INIT_WORK_RSL(&priv->reset_wq, (void *)_rtl92e_restart, dev); |
Mateusz Kulikowski | a514c79 | 2015-07-19 19:33:48 +0200 | [diff] [blame] | 1006 | INIT_WORK_RSL(&priv->rtllib->ips_leave_wq, (void *)rtl92e_ips_leave_wq, |
| 1007 | dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1008 | INIT_DELAYED_WORK_RSL(&priv->watch_dog_wq, |
Mateusz Kulikowski | 7e2d598 | 2015-09-20 10:13:42 +0200 | [diff] [blame] | 1009 | (void *)_rtl92e_watchdog_wq_cb, dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1010 | INIT_DELAYED_WORK_RSL(&priv->txpower_tracking_wq, |
Mateusz Kulikowski | 33059f5 | 2015-07-19 19:28:36 +0200 | [diff] [blame] | 1011 | (void *)rtl92e_dm_txpower_tracking_wq, dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1012 | INIT_DELAYED_WORK_RSL(&priv->rfpath_check_wq, |
Mateusz Kulikowski | 3cd4db7 | 2015-07-19 19:28:35 +0200 | [diff] [blame] | 1013 | (void *)rtl92e_dm_rf_pathcheck_wq, dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1014 | INIT_DELAYED_WORK_RSL(&priv->update_beacon_wq, |
Mateusz Kulikowski | dc88840 | 2015-09-20 10:13:36 +0200 | [diff] [blame] | 1015 | (void *)_rtl92e_update_beacon, dev); |
Mateusz Kulikowski | ae1fe0d | 2015-09-20 10:13:28 +0200 | [diff] [blame] | 1016 | INIT_WORK_RSL(&priv->qos_activate, (void *)_rtl92e_qos_activate, dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1017 | INIT_DELAYED_WORK_RSL(&priv->rtllib->hw_wakeup_wq, |
Mateusz Kulikowski | c34b29f | 2015-07-19 19:33:54 +0200 | [diff] [blame] | 1018 | (void *) rtl92e_hw_wakeup_wq, dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1019 | INIT_DELAYED_WORK_RSL(&priv->rtllib->hw_sleep_wq, |
Mateusz Kulikowski | bcdcc1e | 2015-07-19 19:33:51 +0200 | [diff] [blame] | 1020 | (void *) rtl92e_hw_sleep_wq, dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1021 | tasklet_init(&priv->irq_rx_tasklet, |
Mateusz Kulikowski | 2940405 | 2015-09-20 10:09:29 +0200 | [diff] [blame] | 1022 | (void(*)(unsigned long))_rtl92e_irq_rx_tasklet, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1023 | (unsigned long)priv); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1024 | tasklet_init(&priv->irq_tx_tasklet, |
Mateusz Kulikowski | a2743b2 | 2015-09-20 10:09:30 +0200 | [diff] [blame] | 1025 | (void(*)(unsigned long))_rtl92e_irq_tx_tasklet, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1026 | (unsigned long)priv); |
| 1027 | tasklet_init(&priv->irq_prepare_beacon_tasklet, |
Mateusz Kulikowski | e009a84 | 2015-09-20 10:13:27 +0200 | [diff] [blame] | 1028 | (void(*)(unsigned long))_rtl92e_prepare_beacon, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1029 | (unsigned long)priv); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1030 | } |
| 1031 | |
Mateusz Kulikowski | 66a5c29 | 2015-09-20 10:13:44 +0200 | [diff] [blame] | 1032 | static short _rtl92e_get_channel_map(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1033 | { |
| 1034 | int i; |
| 1035 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1036 | struct r8192_priv *priv = rtllib_priv(dev); |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 1037 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1038 | if ((priv->rf_chip != RF_8225) && (priv->rf_chip != RF_8256) |
| 1039 | && (priv->rf_chip != RF_6052)) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1040 | netdev_err(dev, "%s: unknown rf chip, can't set channel map\n", |
| 1041 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1042 | return -1; |
| 1043 | } |
| 1044 | |
Dan Carpenter | 8f019bf | 2011-09-21 10:17:04 +0300 | [diff] [blame] | 1045 | if (priv->ChannelPlan >= COUNTRY_CODE_MAX) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1046 | netdev_info(dev, |
| 1047 | "rtl819x_init:Error channel plan! Set to default.\n"); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1048 | priv->ChannelPlan = COUNTRY_CODE_FCC; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1049 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1050 | RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan); |
Sean MacLennan | 976d534 | 2011-11-30 15:18:52 -0500 | [diff] [blame] | 1051 | dot11d_init(priv->rtllib); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1052 | Dot11d_Channelmap(priv->ChannelPlan, priv->rtllib); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1053 | for (i = 1; i <= 11; i++) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1054 | (priv->rtllib->active_channel_map)[i] = 1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1055 | (priv->rtllib->active_channel_map)[12] = 2; |
| 1056 | (priv->rtllib->active_channel_map)[13] = 2; |
| 1057 | |
| 1058 | return 0; |
| 1059 | } |
| 1060 | |
Mateusz Kulikowski | 6bd5e8e | 2015-09-20 10:09:22 +0200 | [diff] [blame] | 1061 | static short _rtl92e_init(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1062 | { |
| 1063 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1064 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1065 | memset(&(priv->stats), 0, sizeof(struct rt_stats)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1066 | |
Mateusz Kulikowski | b8d0dc3 | 2015-09-20 10:09:24 +0200 | [diff] [blame] | 1067 | _rtl92e_init_priv_handler(dev); |
Mateusz Kulikowski | 6b2aaea | 2015-09-20 10:09:23 +0200 | [diff] [blame] | 1068 | _rtl92e_init_priv_constant(dev); |
Mateusz Kulikowski | 414f401 | 2015-09-20 10:09:27 +0200 | [diff] [blame] | 1069 | _rtl92e_init_priv_variable(dev); |
Mateusz Kulikowski | 529c66c | 2015-09-20 10:09:25 +0200 | [diff] [blame] | 1070 | _rtl92e_init_priv_lock(priv); |
Mateusz Kulikowski | 4ab2a8f | 2015-09-20 10:09:26 +0200 | [diff] [blame] | 1071 | _rtl92e_init_priv_task(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1072 | priv->ops->get_eeprom_size(dev); |
| 1073 | priv->ops->init_adapter_variable(dev); |
Mateusz Kulikowski | 66a5c29 | 2015-09-20 10:13:44 +0200 | [diff] [blame] | 1074 | _rtl92e_get_channel_map(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1075 | |
Mateusz Kulikowski | ab74359 | 2015-07-19 19:33:58 +0200 | [diff] [blame] | 1076 | rtl92e_dm_init(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1077 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1078 | setup_timer(&priv->watch_dog_timer, |
Mateusz Kulikowski | 2cfc375 | 2015-09-20 10:13:43 +0200 | [diff] [blame] | 1079 | _rtl92e_watchdog_timer_cb, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1080 | (unsigned long) dev); |
| 1081 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1082 | setup_timer(&priv->gpio_polling_timer, |
Mateusz Kulikowski | a643d92 | 2015-07-19 19:28:05 +0200 | [diff] [blame] | 1083 | rtl92e_check_rfctrl_gpio_timer, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1084 | (unsigned long)dev); |
| 1085 | |
Mateusz Kulikowski | b7b50d6 | 2015-07-19 19:28:14 +0200 | [diff] [blame] | 1086 | rtl92e_irq_disable(dev); |
Mateusz Kulikowski | 87e01f2 | 2015-09-20 10:09:28 +0200 | [diff] [blame] | 1087 | if (request_irq(dev->irq, _rtl92e_irq, IRQF_SHARED, dev->name, dev)) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1088 | netdev_err(dev, "Error allocating IRQ %d", dev->irq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1089 | return -1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1090 | } |
| 1091 | |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 1092 | priv->irq = dev->irq; |
| 1093 | RT_TRACE(COMP_INIT, "IRQ %d\n", dev->irq); |
| 1094 | |
Mateusz Kulikowski | 197917a | 2015-09-20 10:12:56 +0200 | [diff] [blame] | 1095 | if (_rtl92e_pci_initdescring(dev) != 0) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1096 | netdev_err(dev, "Endopoints initialization failed"); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 1097 | free_irq(dev->irq, dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1098 | return -1; |
| 1099 | } |
| 1100 | |
| 1101 | return 0; |
| 1102 | } |
| 1103 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1104 | /*************************************************************************** |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1105 | -------------------------------WATCHDOG STUFF--------------------------- |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1106 | ***************************************************************************/ |
Mateusz Kulikowski | 6f8d4a7 | 2015-09-20 10:13:09 +0200 | [diff] [blame] | 1107 | static short _rtl92e_is_tx_queue_empty(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1108 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1109 | int i = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1110 | struct r8192_priv *priv = rtllib_priv(dev); |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 1111 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1112 | for (i = 0; i <= MGNT_QUEUE; i++) { |
| 1113 | if ((i == TXCMD_QUEUE) || (i == HCCA_QUEUE)) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1114 | continue; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1115 | if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1116 | netdev_info(dev, "===>tx queue is not empty:%d, %d\n", |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1117 | i, skb_queue_len(&(&priv->tx_ring[i])->queue)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1118 | return 0; |
| 1119 | } |
| 1120 | } |
| 1121 | return 1; |
| 1122 | } |
| 1123 | |
Mateusz Kulikowski | c8d8419 | 2015-09-20 10:13:10 +0200 | [diff] [blame] | 1124 | static enum reset_type _rtl92e_tx_check_stuck(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1125 | { |
| 1126 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1127 | u8 QueueID; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1128 | bool bCheckFwTxCnt = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1129 | struct rtl8192_tx_ring *ring = NULL; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1130 | struct sk_buff *skb = NULL; |
| 1131 | struct cb_desc *tcb_desc = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1132 | unsigned long flags = 0; |
| 1133 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1134 | switch (priv->rtllib->ps) { |
| 1135 | case RTLLIB_PS_DISABLED: |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1136 | break; |
| 1137 | case (RTLLIB_PS_MBCAST|RTLLIB_PS_UNICAST): |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1138 | break; |
| 1139 | default: |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1140 | break; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1141 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1142 | spin_lock_irqsave(&priv->irq_th_lock, flags); |
| 1143 | for (QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1144 | if (QueueID == TXCMD_QUEUE) |
| 1145 | continue; |
| 1146 | |
| 1147 | if (QueueID == BEACON_QUEUE) |
| 1148 | continue; |
| 1149 | |
| 1150 | ring = &priv->tx_ring[QueueID]; |
| 1151 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1152 | if (skb_queue_len(&ring->queue) == 0) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1153 | continue; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1154 | } else { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1155 | skb = (&ring->queue)->next; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1156 | tcb_desc = (struct cb_desc *)(skb->cb + |
| 1157 | MAX_DEV_ADDR_SIZE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1158 | tcb_desc->nStuckCount++; |
| 1159 | bCheckFwTxCnt = true; |
| 1160 | if (tcb_desc->nStuckCount > 1) |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1161 | netdev_info(dev, |
| 1162 | "%s: QueueID=%d tcb_desc->nStuckCount=%d\n", |
| 1163 | __func__, QueueID, |
| 1164 | tcb_desc->nStuckCount); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1165 | } |
| 1166 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1167 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1168 | |
| 1169 | if (bCheckFwTxCnt) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1170 | if (priv->ops->TxCheckStuckHandler(dev)) { |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 1171 | RT_TRACE(COMP_RESET, |
| 1172 | "TxCheckStuck(): Fw indicates no Tx condition!\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1173 | return RESET_TYPE_SILENT; |
| 1174 | } |
| 1175 | } |
| 1176 | |
| 1177 | return RESET_TYPE_NORESET; |
| 1178 | } |
| 1179 | |
Mateusz Kulikowski | ea2d705 | 2015-09-20 10:13:12 +0200 | [diff] [blame] | 1180 | static enum reset_type _rtl92e_rx_check_stuck(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1181 | { |
| 1182 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1183 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1184 | if (priv->ops->RxCheckStuckHandler(dev)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1185 | RT_TRACE(COMP_RESET, "RxStuck Condition\n"); |
| 1186 | return RESET_TYPE_SILENT; |
| 1187 | } |
| 1188 | |
| 1189 | return RESET_TYPE_NORESET; |
| 1190 | } |
| 1191 | |
Mateusz Kulikowski | 79fbe93 | 2015-09-20 10:13:38 +0200 | [diff] [blame] | 1192 | static enum reset_type _rtl92e_if_check_reset(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1193 | { |
| 1194 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | ab0d7cc | 2011-07-19 19:49:51 -0500 | [diff] [blame] | 1195 | enum reset_type TxResetType = RESET_TYPE_NORESET; |
| 1196 | enum reset_type RxResetType = RESET_TYPE_NORESET; |
Larry Finger | de7c885 | 2011-07-19 21:00:33 -0500 | [diff] [blame] | 1197 | enum rt_rf_power_state rfState; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1198 | |
| 1199 | rfState = priv->rtllib->eRFPowerState; |
| 1200 | |
| 1201 | if (rfState == eRfOn) |
Mateusz Kulikowski | c8d8419 | 2015-09-20 10:13:10 +0200 | [diff] [blame] | 1202 | TxResetType = _rtl92e_tx_check_stuck(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1203 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1204 | if (rfState == eRfOn && |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1205 | (priv->rtllib->iw_mode == IW_MODE_INFRA) && |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1206 | (priv->rtllib->state == RTLLIB_LINKED)) |
Mateusz Kulikowski | ea2d705 | 2015-09-20 10:13:12 +0200 | [diff] [blame] | 1207 | RxResetType = _rtl92e_rx_check_stuck(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1208 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1209 | if (TxResetType == RESET_TYPE_NORMAL || |
| 1210 | RxResetType == RESET_TYPE_NORMAL) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1211 | netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n", |
| 1212 | __func__, TxResetType, RxResetType); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1213 | return RESET_TYPE_NORMAL; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1214 | } else if (TxResetType == RESET_TYPE_SILENT || |
| 1215 | RxResetType == RESET_TYPE_SILENT) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1216 | netdev_info(dev, "%s(): TxResetType is %d, RxResetType is %d\n", |
| 1217 | __func__, TxResetType, RxResetType); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1218 | return RESET_TYPE_SILENT; |
| 1219 | } else { |
| 1220 | return RESET_TYPE_NORESET; |
| 1221 | } |
| 1222 | |
| 1223 | } |
| 1224 | |
Mateusz Kulikowski | 5e177a9 | 2015-09-20 10:13:39 +0200 | [diff] [blame] | 1225 | static void _rtl92e_if_silent_reset(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1226 | { |
| 1227 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1228 | u8 reset_times = 0; |
| 1229 | int reset_status = 0; |
| 1230 | struct rtllib_device *ieee = priv->rtllib; |
| 1231 | unsigned long flag; |
| 1232 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1233 | if (priv->ResetProgress == RESET_TYPE_NORESET) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1234 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1235 | RT_TRACE(COMP_RESET, "=========>Reset progress!!\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1236 | |
| 1237 | priv->ResetProgress = RESET_TYPE_SILENT; |
| 1238 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1239 | spin_lock_irqsave(&priv->rf_ps_lock, flag); |
| 1240 | if (priv->RFChangeInProgress) { |
| 1241 | spin_unlock_irqrestore(&priv->rf_ps_lock, flag); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1242 | goto END; |
| 1243 | } |
| 1244 | priv->RFChangeInProgress = true; |
| 1245 | priv->bResetInProgress = true; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1246 | spin_unlock_irqrestore(&priv->rf_ps_lock, flag); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1247 | |
| 1248 | RESET_START: |
| 1249 | |
| 1250 | down(&priv->wx_sem); |
| 1251 | |
| 1252 | if (priv->rtllib->state == RTLLIB_LINKED) |
Mateusz Kulikowski | 9c4a55d | 2015-07-19 19:33:50 +0200 | [diff] [blame] | 1253 | rtl92e_leisure_ps_leave(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1254 | |
Vaishali Thakkar | 5dc4296 | 2015-03-03 13:08:24 +0530 | [diff] [blame] | 1255 | if (priv->up) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1256 | netdev_info(dev, "%s():the driver is not up.\n", |
| 1257 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1258 | up(&priv->wx_sem); |
Vaishali Thakkar | fe40a0b | 2014-09-17 08:35:24 +0530 | [diff] [blame] | 1259 | return; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1260 | } |
| 1261 | priv->up = 0; |
| 1262 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1263 | RT_TRACE(COMP_RESET, "%s():======>start to down the driver\n", |
| 1264 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1265 | mdelay(1000); |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 1266 | RT_TRACE(COMP_RESET, |
| 1267 | "%s():111111111111111111111111======>start to down the driver\n", |
| 1268 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1269 | |
| 1270 | if (!netif_queue_stopped(dev)) |
| 1271 | netif_stop_queue(dev); |
| 1272 | |
Mateusz Kulikowski | b7b50d6 | 2015-07-19 19:28:14 +0200 | [diff] [blame] | 1273 | rtl92e_irq_disable(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1274 | del_timer_sync(&priv->watch_dog_timer); |
Mateusz Kulikowski | 4dba03a | 2015-09-20 10:14:12 +0200 | [diff] [blame] | 1275 | _rtl92e_cancel_deferred_work(priv); |
Mateusz Kulikowski | fd9e317 | 2015-07-19 19:28:29 +0200 | [diff] [blame] | 1276 | rtl92e_dm_deinit(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1277 | rtllib_stop_scan_syncro(ieee); |
| 1278 | |
| 1279 | if (ieee->state == RTLLIB_LINKED) { |
| 1280 | SEM_DOWN_IEEE_WX(&ieee->wx_sem); |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1281 | netdev_info(dev, "ieee->state is RTLLIB_LINKED\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1282 | rtllib_stop_send_beacons(priv->rtllib); |
| 1283 | del_timer_sync(&ieee->associate_timer); |
| 1284 | cancel_delayed_work(&ieee->associate_retry_wq); |
| 1285 | rtllib_stop_scan(ieee); |
| 1286 | netif_carrier_off(dev); |
| 1287 | SEM_UP_IEEE_WX(&ieee->wx_sem); |
| 1288 | } else { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1289 | netdev_info(dev, "ieee->state is NOT LINKED\n"); |
Mateusz Kulikowski | f669228 | 2015-04-13 23:47:27 +0200 | [diff] [blame] | 1290 | rtllib_softmac_stop_protocol(priv->rtllib, 0, true); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1291 | } |
| 1292 | |
Mateusz Kulikowski | 090e8a4 | 2015-07-19 19:28:30 +0200 | [diff] [blame] | 1293 | rtl92e_dm_backup_state(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1294 | |
| 1295 | up(&priv->wx_sem); |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 1296 | RT_TRACE(COMP_RESET, |
| 1297 | "%s():<==========down process is finished\n", |
| 1298 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1299 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1300 | RT_TRACE(COMP_RESET, "%s():<===========up process start\n", |
| 1301 | __func__); |
Mateusz Kulikowski | 81524bb | 2015-09-20 10:12:54 +0200 | [diff] [blame] | 1302 | reset_status = _rtl92e_up(dev, true); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1303 | |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 1304 | RT_TRACE(COMP_RESET, |
| 1305 | "%s():<===========up process is finished\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1306 | if (reset_status == -1) { |
| 1307 | if (reset_times < 3) { |
| 1308 | reset_times++; |
| 1309 | goto RESET_START; |
| 1310 | } else { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1311 | netdev_warn(dev, "%s(): Reset Failed\n", |
| 1312 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1313 | } |
| 1314 | } |
| 1315 | |
| 1316 | ieee->is_silent_reset = 1; |
| 1317 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1318 | spin_lock_irqsave(&priv->rf_ps_lock, flag); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1319 | priv->RFChangeInProgress = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1320 | spin_unlock_irqrestore(&priv->rf_ps_lock, flag); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1321 | |
Mateusz Kulikowski | 3742093 | 2015-07-19 19:28:02 +0200 | [diff] [blame] | 1322 | rtl92e_enable_hw_security_config(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1323 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1324 | if (ieee->state == RTLLIB_LINKED && ieee->iw_mode == |
| 1325 | IW_MODE_INFRA) { |
| 1326 | ieee->set_chan(ieee->dev, |
| 1327 | ieee->current_network.channel); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1328 | |
Amitoj Kaur Chawla | 354605f | 2016-02-20 15:36:26 +0530 | [diff] [blame] | 1329 | schedule_work(&ieee->associate_complete_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1330 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1331 | } else if (ieee->state == RTLLIB_LINKED && ieee->iw_mode == |
| 1332 | IW_MODE_ADHOC) { |
| 1333 | ieee->set_chan(ieee->dev, |
| 1334 | ieee->current_network.channel); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1335 | ieee->link_change(ieee->dev); |
| 1336 | |
| 1337 | notify_wx_assoc_event(ieee); |
| 1338 | |
| 1339 | rtllib_start_send_beacons(ieee); |
| 1340 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1341 | netif_carrier_on(ieee->dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1342 | } |
| 1343 | |
Mateusz Kulikowski | 66497f0 | 2015-07-19 19:28:01 +0200 | [diff] [blame] | 1344 | rtl92e_cam_restore(dev); |
Mateusz Kulikowski | 25c01ec | 2015-07-19 19:28:34 +0200 | [diff] [blame] | 1345 | rtl92e_dm_restore_state(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1346 | END: |
| 1347 | priv->ResetProgress = RESET_TYPE_NORESET; |
| 1348 | priv->reset_count++; |
| 1349 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1350 | priv->bForcedSilentReset = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1351 | priv->bResetInProgress = false; |
| 1352 | |
Mateusz Kulikowski | d8ae196 | 2015-07-19 19:28:26 +0200 | [diff] [blame] | 1353 | rtl92e_writeb(dev, UFWP, 1); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1354 | RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", |
| 1355 | priv->reset_count); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1356 | } |
| 1357 | } |
| 1358 | |
Mateusz Kulikowski | c3b4816 | 2015-09-20 10:13:41 +0200 | [diff] [blame] | 1359 | static void _rtl92e_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum, |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 1360 | u32 *TotalRxDataNum) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1361 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1362 | u16 SlotIndex; |
| 1363 | u8 i; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1364 | |
| 1365 | *TotalRxBcnNum = 0; |
| 1366 | *TotalRxDataNum = 0; |
| 1367 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1368 | SlotIndex = (priv->rtllib->LinkDetectInfo.SlotIndex++) % |
| 1369 | (priv->rtllib->LinkDetectInfo.SlotNum); |
| 1370 | priv->rtllib->LinkDetectInfo.RxBcnNum[SlotIndex] = |
| 1371 | priv->rtllib->LinkDetectInfo.NumRecvBcnInPeriod; |
| 1372 | priv->rtllib->LinkDetectInfo.RxDataNum[SlotIndex] = |
| 1373 | priv->rtllib->LinkDetectInfo.NumRecvDataInPeriod; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1374 | for (i = 0; i < priv->rtllib->LinkDetectInfo.SlotNum; i++) { |
| 1375 | *TotalRxBcnNum += priv->rtllib->LinkDetectInfo.RxBcnNum[i]; |
| 1376 | *TotalRxDataNum += priv->rtllib->LinkDetectInfo.RxDataNum[i]; |
| 1377 | } |
| 1378 | } |
| 1379 | |
Mateusz Kulikowski | 7e2d598 | 2015-09-20 10:13:42 +0200 | [diff] [blame] | 1380 | static void _rtl92e_watchdog_wq_cb(void *data) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1381 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1382 | struct r8192_priv *priv = container_of_dwork_rsl(data, |
| 1383 | struct r8192_priv, watch_dog_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1384 | struct net_device *dev = priv->rtllib->dev; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1385 | struct rtllib_device *ieee = priv->rtllib; |
Larry Finger | ab0d7cc | 2011-07-19 19:49:51 -0500 | [diff] [blame] | 1386 | enum reset_type ResetType = RESET_TYPE_NORESET; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1387 | static u8 check_reset_cnt; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1388 | unsigned long flags; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1389 | struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) |
| 1390 | (&(priv->rtllib->PowerSaveControl)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1391 | bool bBusyTraffic = false; |
| 1392 | bool bHigherBusyTraffic = false; |
| 1393 | bool bHigherBusyRxTraffic = false; |
| 1394 | bool bEnterPS = false; |
| 1395 | |
Vaishali Thakkar | 5dc4296 | 2015-03-03 13:08:24 +0530 | [diff] [blame] | 1396 | if (!priv->up || priv->bHwRadioOff) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1397 | return; |
| 1398 | |
| 1399 | if (priv->rtllib->state >= RTLLIB_LINKED) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1400 | if (priv->rtllib->CntAfterLink < 2) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1401 | priv->rtllib->CntAfterLink++; |
| 1402 | } else { |
| 1403 | priv->rtllib->CntAfterLink = 0; |
| 1404 | } |
| 1405 | |
Mateusz Kulikowski | 8e1e64b | 2015-07-19 19:28:37 +0200 | [diff] [blame] | 1406 | rtl92e_dm_watchdog(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1407 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1408 | if (rtllib_act_scanning(priv->rtllib, false) == false) { |
| 1409 | if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == |
| 1410 | RTLLIB_NOLINK) && |
| 1411 | (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key && |
| 1412 | (!ieee->proto_stoppping) && !ieee->wx_set_enc) { |
| 1413 | if ((ieee->PowerSaveControl.ReturnPoint == |
| 1414 | IPS_CALLBACK_NONE) && |
| 1415 | (!ieee->bNetPromiscuousMode)) { |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 1416 | RT_TRACE(COMP_PS, |
Mateusz Kulikowski | 410d6fc | 2015-07-19 19:28:43 +0200 | [diff] [blame] | 1417 | "====================>haha: rtl92e_ips_enter()\n"); |
| 1418 | rtl92e_ips_enter(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1419 | } |
| 1420 | } |
| 1421 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1422 | if ((ieee->state == RTLLIB_LINKED) && (ieee->iw_mode == |
| 1423 | IW_MODE_INFRA) && (!ieee->bNetPromiscuousMode)) { |
| 1424 | if (ieee->LinkDetectInfo.NumRxOkInPeriod > 100 || |
| 1425 | ieee->LinkDetectInfo.NumTxOkInPeriod > 100) |
| 1426 | bBusyTraffic = true; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1427 | |
| 1428 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1429 | if (ieee->LinkDetectInfo.NumRxOkInPeriod > 4000 || |
| 1430 | ieee->LinkDetectInfo.NumTxOkInPeriod > 4000) { |
| 1431 | bHigherBusyTraffic = true; |
| 1432 | if (ieee->LinkDetectInfo.NumRxOkInPeriod > 5000) |
| 1433 | bHigherBusyRxTraffic = true; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1434 | else |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1435 | bHigherBusyRxTraffic = false; |
| 1436 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1437 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1438 | if (((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + |
| 1439 | ieee->LinkDetectInfo.NumTxOkInPeriod) > 8) || |
| 1440 | (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) |
| 1441 | bEnterPS = false; |
| 1442 | else |
| 1443 | bEnterPS = true; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1444 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1445 | if (ieee->current_network.beacon_interval < 95) |
| 1446 | bEnterPS = false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1447 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1448 | if (bEnterPS) |
Mateusz Kulikowski | 04197ef | 2015-07-19 19:33:49 +0200 | [diff] [blame] | 1449 | rtl92e_leisure_ps_enter(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1450 | else |
Mateusz Kulikowski | 9c4a55d | 2015-07-19 19:33:50 +0200 | [diff] [blame] | 1451 | rtl92e_leisure_ps_leave(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1452 | |
| 1453 | } else { |
| 1454 | RT_TRACE(COMP_LPS, "====>no link LPS leave\n"); |
Mateusz Kulikowski | 9c4a55d | 2015-07-19 19:33:50 +0200 | [diff] [blame] | 1455 | rtl92e_leisure_ps_leave(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1456 | } |
| 1457 | |
| 1458 | ieee->LinkDetectInfo.NumRxOkInPeriod = 0; |
| 1459 | ieee->LinkDetectInfo.NumTxOkInPeriod = 0; |
| 1460 | ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; |
| 1461 | ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; |
| 1462 | |
| 1463 | ieee->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; |
| 1464 | ieee->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; |
| 1465 | |
| 1466 | if (ieee->state == RTLLIB_LINKED && ieee->iw_mode == IW_MODE_INFRA) { |
| 1467 | u32 TotalRxBcnNum = 0; |
| 1468 | u32 TotalRxDataNum = 0; |
| 1469 | |
Mateusz Kulikowski | c3b4816 | 2015-09-20 10:13:41 +0200 | [diff] [blame] | 1470 | _rtl92e_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1471 | |
| 1472 | if ((TotalRxBcnNum+TotalRxDataNum) == 0) |
| 1473 | priv->check_roaming_cnt++; |
| 1474 | else |
| 1475 | priv->check_roaming_cnt = 0; |
| 1476 | |
| 1477 | |
| 1478 | if (priv->check_roaming_cnt > 0) { |
| 1479 | if (ieee->eRFPowerState == eRfOff) |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1480 | netdev_info(dev, "%s(): RF is off\n", __func__); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1481 | |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 1482 | netdev_info(dev, |
| 1483 | "===>%s(): AP is power off, chan:%d, connect another one\n", |
| 1484 | __func__, priv->chan); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1485 | |
| 1486 | ieee->state = RTLLIB_ASSOCIATING; |
| 1487 | |
| 1488 | RemovePeerTS(priv->rtllib, |
| 1489 | priv->rtllib->current_network.bssid); |
| 1490 | ieee->is_roaming = true; |
| 1491 | ieee->is_set_key = false; |
| 1492 | ieee->link_change(dev); |
| 1493 | if (ieee->LedControlHandler) |
| 1494 | ieee->LedControlHandler(ieee->dev, |
| 1495 | LED_CTL_START_TO_LINK); |
| 1496 | |
| 1497 | notify_wx_assoc_event(ieee); |
| 1498 | |
| 1499 | if (!(ieee->rtllib_ap_sec_type(ieee) & |
| 1500 | (SEC_ALG_CCMP|SEC_ALG_TKIP))) |
Amitoj Kaur Chawla | 354605f | 2016-02-20 15:36:26 +0530 | [diff] [blame] | 1501 | schedule_delayed_work( |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1502 | &ieee->associate_procedure_wq, 0); |
| 1503 | |
| 1504 | priv->check_roaming_cnt = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1505 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1506 | ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; |
| 1507 | ieee->LinkDetectInfo.NumRecvDataInPeriod = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1508 | |
| 1509 | } |
| 1510 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1511 | spin_lock_irqsave(&priv->tx_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1512 | if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) && |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1513 | (!priv->RFChangeInProgress) && (!pPSC->bSwRfProcessing)) { |
Mateusz Kulikowski | 79fbe93 | 2015-09-20 10:13:38 +0200 | [diff] [blame] | 1514 | ResetType = _rtl92e_if_check_reset(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1515 | check_reset_cnt = 3; |
| 1516 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1517 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1518 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1519 | if (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1520 | priv->ResetProgress = RESET_TYPE_NORMAL; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1521 | RT_TRACE(COMP_RESET, "%s(): NOMAL RESET\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1522 | return; |
| 1523 | } |
| 1524 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1525 | if (((priv->force_reset) || (!priv->bDisableNormalResetCheck && |
| 1526 | ResetType == RESET_TYPE_SILENT))) |
Mateusz Kulikowski | 5e177a9 | 2015-09-20 10:13:39 +0200 | [diff] [blame] | 1527 | _rtl92e_if_silent_reset(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1528 | priv->force_reset = false; |
| 1529 | priv->bForcedSilentReset = false; |
| 1530 | priv->bResetInProgress = false; |
| 1531 | RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n"); |
| 1532 | } |
| 1533 | |
Mateusz Kulikowski | 2cfc375 | 2015-09-20 10:13:43 +0200 | [diff] [blame] | 1534 | static void _rtl92e_watchdog_timer_cb(unsigned long data) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1535 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1536 | struct r8192_priv *priv = rtllib_priv((struct net_device *)data); |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 1537 | |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 1538 | schedule_delayed_work(&priv->watch_dog_wq, 0); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1539 | mod_timer(&priv->watch_dog_timer, jiffies + |
Vaishali Thakkar | 8b9733c | 2015-03-11 13:51:36 +0530 | [diff] [blame] | 1540 | msecs_to_jiffies(RTLLIB_WATCH_DOG_TIME)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1541 | } |
| 1542 | |
| 1543 | /**************************************************************************** |
| 1544 | ---------------------------- NIC TX/RX STUFF--------------------------- |
| 1545 | *****************************************************************************/ |
Mateusz Kulikowski | 630268b | 2015-07-19 19:28:18 +0200 | [diff] [blame] | 1546 | void rtl92e_rx_enable(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1547 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 1548 | struct r8192_priv *priv = rtllib_priv(dev); |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 1549 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1550 | priv->ops->rx_enable(dev); |
| 1551 | } |
| 1552 | |
Mateusz Kulikowski | 94199b3 | 2015-07-19 19:28:20 +0200 | [diff] [blame] | 1553 | void rtl92e_tx_enable(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1554 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 1555 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1556 | |
| 1557 | priv->ops->tx_enable(dev); |
| 1558 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1559 | rtllib_reset_queue(priv->rtllib); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1560 | } |
| 1561 | |
| 1562 | |
Mateusz Kulikowski | 694f9d3 | 2015-09-20 10:13:02 +0200 | [diff] [blame] | 1563 | static void _rtl92e_free_rx_ring(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1564 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1565 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1566 | int i, rx_queue_idx; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1567 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1568 | for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; |
| 1569 | rx_queue_idx++) { |
| 1570 | for (i = 0; i < priv->rxringcount; i++) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1571 | struct sk_buff *skb = priv->rx_buf[rx_queue_idx][i]; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 1572 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1573 | if (!skb) |
| 1574 | continue; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1575 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1576 | pci_unmap_single(priv->pdev, |
| 1577 | *((dma_addr_t *)skb->cb), |
| 1578 | priv->rxbuffersize, PCI_DMA_FROMDEVICE); |
| 1579 | kfree_skb(skb); |
| 1580 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1581 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1582 | pci_free_consistent(priv->pdev, |
| 1583 | sizeof(*priv->rx_ring[rx_queue_idx]) * |
| 1584 | priv->rxringcount, |
| 1585 | priv->rx_ring[rx_queue_idx], |
| 1586 | priv->rx_ring_dma[rx_queue_idx]); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1587 | priv->rx_ring[rx_queue_idx] = NULL; |
| 1588 | } |
| 1589 | } |
| 1590 | |
Mateusz Kulikowski | ebc36ec | 2015-09-20 10:13:03 +0200 | [diff] [blame] | 1591 | static void _rtl92e_free_tx_ring(struct net_device *dev, unsigned int prio) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1592 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1593 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1594 | struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1595 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1596 | while (skb_queue_len(&ring->queue)) { |
| 1597 | struct tx_desc *entry = &ring->desc[ring->idx]; |
| 1598 | struct sk_buff *skb = __skb_dequeue(&ring->queue); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1599 | |
Rashika Kheria | 466bc7f2 | 2013-11-07 19:16:36 +0530 | [diff] [blame] | 1600 | pci_unmap_single(priv->pdev, entry->TxBuffAddr, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1601 | skb->len, PCI_DMA_TODEVICE); |
| 1602 | kfree_skb(skb); |
| 1603 | ring->idx = (ring->idx + 1) % ring->entries; |
| 1604 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1605 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1606 | pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries, |
| 1607 | ring->desc, ring->dma); |
| 1608 | ring->desc = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1609 | } |
| 1610 | |
Mateusz Kulikowski | 52a7404 | 2015-09-20 10:13:48 +0200 | [diff] [blame] | 1611 | static void _rtl92e_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, |
| 1612 | int rate) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1613 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 1614 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1615 | int ret; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1616 | struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + |
| 1617 | MAX_DEV_ADDR_SIZE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1618 | u8 queue_index = tcb_desc->queue_index; |
| 1619 | |
Vaishali Thakkar | 5dc4296 | 2015-03-03 13:08:24 +0530 | [diff] [blame] | 1620 | if ((priv->rtllib->eRFPowerState == eRfOff) || !priv->up || |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1621 | priv->bResetInProgress) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1622 | kfree_skb(skb); |
| 1623 | return; |
| 1624 | } |
| 1625 | |
Mateusz Kulikowski | 435009b | 2015-08-12 21:54:49 +0200 | [diff] [blame] | 1626 | if (queue_index == TXCMD_QUEUE) |
| 1627 | netdev_warn(dev, "%s(): queue index == TXCMD_QUEUE\n", |
Mateusz Kulikowski | ca93dcb | 2015-05-31 20:19:38 +0200 | [diff] [blame] | 1628 | __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1629 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1630 | memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1631 | skb_push(skb, priv->rtllib->tx_headroom); |
Mateusz Kulikowski | 374a3c5 | 2015-09-20 10:13:04 +0200 | [diff] [blame] | 1632 | ret = _rtl92e_tx(dev, skb); |
Joe Perches | a22526e | 2013-10-10 16:07:59 -0700 | [diff] [blame] | 1633 | if (ret != 0) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1634 | kfree_skb(skb); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1635 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1636 | if (queue_index != MGNT_QUEUE) { |
| 1637 | priv->rtllib->stats.tx_bytes += (skb->len - |
| 1638 | priv->rtllib->tx_headroom); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1639 | priv->rtllib->stats.tx_packets++; |
| 1640 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1641 | } |
| 1642 | |
Mateusz Kulikowski | 3e49f3e | 2015-09-20 10:13:49 +0200 | [diff] [blame] | 1643 | static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1644 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 1645 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1646 | int ret; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1647 | struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + |
| 1648 | MAX_DEV_ADDR_SIZE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1649 | u8 queue_index = tcb_desc->queue_index; |
| 1650 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1651 | if (queue_index != TXCMD_QUEUE) { |
| 1652 | if ((priv->rtllib->eRFPowerState == eRfOff) || |
Vaishali Thakkar | 5dc4296 | 2015-03-03 13:08:24 +0530 | [diff] [blame] | 1653 | !priv->up || priv->bResetInProgress) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1654 | kfree_skb(skb); |
| 1655 | return 0; |
| 1656 | } |
| 1657 | } |
| 1658 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1659 | memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1660 | if (queue_index == TXCMD_QUEUE) { |
Mateusz Kulikowski | 98208f9 | 2015-09-20 10:13:05 +0200 | [diff] [blame] | 1661 | _rtl92e_tx_cmd(dev, skb); |
Julia Lawall | 26e2fa7 | 2014-05-19 06:31:12 +0200 | [diff] [blame] | 1662 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1663 | } |
| 1664 | |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 1665 | tcb_desc->RATRIndex = 7; |
| 1666 | tcb_desc->bTxDisableRateFallBack = 1; |
| 1667 | tcb_desc->bTxUseDriverAssingedRate = 1; |
| 1668 | tcb_desc->bTxEnableFwCalcDur = 1; |
| 1669 | skb_push(skb, priv->rtllib->tx_headroom); |
Mateusz Kulikowski | 374a3c5 | 2015-09-20 10:13:04 +0200 | [diff] [blame] | 1670 | ret = _rtl92e_tx(dev, skb); |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 1671 | if (ret != 0) |
| 1672 | kfree_skb(skb); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1673 | return ret; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1674 | } |
| 1675 | |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 1676 | static void _rtl92e_tx_isr(struct net_device *dev, int prio) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1677 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 1678 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1679 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1680 | struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1681 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1682 | while (skb_queue_len(&ring->queue)) { |
| 1683 | struct tx_desc *entry = &ring->desc[ring->idx]; |
| 1684 | struct sk_buff *skb; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1685 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1686 | if (prio != BEACON_QUEUE) { |
| 1687 | if (entry->OWN) |
| 1688 | return; |
| 1689 | ring->idx = (ring->idx + 1) % ring->entries; |
| 1690 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1691 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1692 | skb = __skb_dequeue(&ring->queue); |
Rashika Kheria | 466bc7f2 | 2013-11-07 19:16:36 +0530 | [diff] [blame] | 1693 | pci_unmap_single(priv->pdev, entry->TxBuffAddr, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1694 | skb->len, PCI_DMA_TODEVICE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1695 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1696 | kfree_skb(skb); |
| 1697 | } |
| 1698 | if (prio != BEACON_QUEUE) |
| 1699 | tasklet_schedule(&priv->irq_tx_tasklet); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1700 | } |
| 1701 | |
Mateusz Kulikowski | 98208f9 | 2015-09-20 10:13:05 +0200 | [diff] [blame] | 1702 | static void _rtl92e_tx_cmd(struct net_device *dev, struct sk_buff *skb) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1703 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1704 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1705 | struct rtl8192_tx_ring *ring; |
| 1706 | struct tx_desc_cmd *entry; |
| 1707 | unsigned int idx; |
| 1708 | struct cb_desc *tcb_desc; |
| 1709 | unsigned long flags; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1710 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1711 | spin_lock_irqsave(&priv->irq_th_lock, flags); |
| 1712 | ring = &priv->tx_ring[TXCMD_QUEUE]; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1713 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1714 | idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; |
| 1715 | entry = (struct tx_desc_cmd *) &ring->desc[idx]; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1716 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1717 | tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1718 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1719 | priv->ops->tx_fill_cmd_descriptor(dev, entry, tcb_desc, skb); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1720 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1721 | __skb_queue_tail(&ring->queue, skb); |
| 1722 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1723 | } |
| 1724 | |
Mateusz Kulikowski | 374a3c5 | 2015-09-20 10:13:04 +0200 | [diff] [blame] | 1725 | static short _rtl92e_tx(struct net_device *dev, struct sk_buff *skb) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1726 | { |
| 1727 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1728 | struct rtl8192_tx_ring *ring; |
| 1729 | unsigned long flags; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1730 | struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + |
| 1731 | MAX_DEV_ADDR_SIZE); |
Larry Finger | bc27e89 | 2011-07-18 22:27:06 -0500 | [diff] [blame] | 1732 | struct tx_desc *pdesc = NULL; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1733 | struct rtllib_hdr_1addr *header = NULL; |
| 1734 | u16 fc = 0, type = 0, stype = 0; |
| 1735 | bool multi_addr = false, broad_addr = false, uni_addr = false; |
| 1736 | u8 *pda_addr = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1737 | int idx; |
| 1738 | u32 fwinfo_size = 0; |
| 1739 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1740 | if (priv->bdisable_nic) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1741 | netdev_warn(dev, "%s: Nic is disabled! Can't tx packet.\n", |
| 1742 | __func__); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1743 | return skb->len; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1744 | } |
| 1745 | |
| 1746 | priv->rtllib->bAwakePktSent = true; |
| 1747 | |
Larry Finger | a07dc3d | 2011-07-18 21:27:34 -0500 | [diff] [blame] | 1748 | fwinfo_size = sizeof(struct tx_fwinfo_8190pci); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1749 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1750 | header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size); |
Rashika Kheria | 34e987e | 2013-11-07 19:15:48 +0530 | [diff] [blame] | 1751 | fc = le16_to_cpu(header->frame_ctl); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1752 | type = WLAN_FC_GET_TYPE(fc); |
| 1753 | stype = WLAN_FC_GET_STYPE(fc); |
| 1754 | pda_addr = header->addr1; |
| 1755 | |
Joe Perches | 14fc423 | 2012-05-08 10:11:56 -0700 | [diff] [blame] | 1756 | if (is_broadcast_ether_addr(pda_addr)) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1757 | broad_addr = true; |
Joe Perches | 14fc423 | 2012-05-08 10:11:56 -0700 | [diff] [blame] | 1758 | else if (is_multicast_ether_addr(pda_addr)) |
| 1759 | multi_addr = true; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1760 | else |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1761 | uni_addr = true; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1762 | |
| 1763 | if (uni_addr) |
| 1764 | priv->stats.txbytesunicast += skb->len - fwinfo_size; |
| 1765 | else if (multi_addr) |
| 1766 | priv->stats.txbytesmulticast += skb->len - fwinfo_size; |
| 1767 | else |
| 1768 | priv->stats.txbytesbroadcast += skb->len - fwinfo_size; |
| 1769 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1770 | spin_lock_irqsave(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1771 | ring = &priv->tx_ring[tcb_desc->queue_index]; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1772 | if (tcb_desc->queue_index != BEACON_QUEUE) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1773 | idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1774 | else |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1775 | idx = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1776 | |
| 1777 | pdesc = &ring->desc[idx]; |
| 1778 | if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1779 | netdev_warn(dev, |
| 1780 | "No more TX desc@%d, ring->idx = %d, idx = %d, skblen = 0x%x queuelen=%d", |
| 1781 | tcb_desc->queue_index, ring->idx, idx, skb->len, |
| 1782 | skb_queue_len(&ring->queue)); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1783 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1784 | return skb->len; |
| 1785 | } |
| 1786 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1787 | if (type == RTLLIB_FTYPE_DATA) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1788 | if (priv->rtllib->LedControlHandler) |
| 1789 | priv->rtllib->LedControlHandler(dev, LED_CTL_TX); |
| 1790 | } |
| 1791 | priv->ops->tx_fill_descriptor(dev, pdesc, tcb_desc, skb); |
| 1792 | __skb_queue_tail(&ring->queue, skb); |
| 1793 | pdesc->OWN = 1; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1794 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Florian Westphal | 860e953 | 2016-05-03 16:33:13 +0200 | [diff] [blame] | 1795 | netif_trans_update(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1796 | |
Mateusz Kulikowski | 6dee0c8 | 2015-07-19 19:28:28 +0200 | [diff] [blame] | 1797 | rtl92e_writew(dev, TPPoll, 0x01 << tcb_desc->queue_index); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1798 | return 0; |
| 1799 | } |
| 1800 | |
Mateusz Kulikowski | 9d14896 | 2015-09-20 10:13:00 +0200 | [diff] [blame] | 1801 | static short _rtl92e_alloc_rx_ring(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1802 | { |
| 1803 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 4f534b3 | 2011-07-18 22:52:12 -0500 | [diff] [blame] | 1804 | struct rx_desc *entry = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1805 | int i, rx_queue_idx; |
| 1806 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1807 | for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) { |
Mateusz Kulikowski | 35e33b0 | 2015-05-31 20:19:40 +0200 | [diff] [blame] | 1808 | priv->rx_ring[rx_queue_idx] = pci_zalloc_consistent(priv->pdev, |
Joe Perches | 8b983be | 2014-08-08 14:24:48 -0700 | [diff] [blame] | 1809 | sizeof(*priv->rx_ring[rx_queue_idx]) * priv->rxringcount, |
| 1810 | &priv->rx_ring_dma[rx_queue_idx]); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1811 | if (!priv->rx_ring[rx_queue_idx] || |
| 1812 | (unsigned long)priv->rx_ring[rx_queue_idx] & 0xFF) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1813 | netdev_warn(dev, "Cannot allocate RX ring\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1814 | return -ENOMEM; |
| 1815 | } |
| 1816 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1817 | priv->rx_idx[rx_queue_idx] = 0; |
| 1818 | |
| 1819 | for (i = 0; i < priv->rxringcount; i++) { |
| 1820 | struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize); |
| 1821 | dma_addr_t *mapping; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 1822 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1823 | entry = &priv->rx_ring[rx_queue_idx][i]; |
| 1824 | if (!skb) |
| 1825 | return 0; |
| 1826 | skb->dev = dev; |
| 1827 | priv->rx_buf[rx_queue_idx][i] = skb; |
| 1828 | mapping = (dma_addr_t *)skb->cb; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1829 | *mapping = pci_map_single(priv->pdev, |
| 1830 | skb_tail_pointer_rsl(skb), |
| 1831 | priv->rxbuffersize, |
| 1832 | PCI_DMA_FROMDEVICE); |
Larry Finger | 2dcb4a2 | 2012-12-26 20:51:12 -0600 | [diff] [blame] | 1833 | if (pci_dma_mapping_error(priv->pdev, *mapping)) { |
| 1834 | dev_kfree_skb_any(skb); |
| 1835 | return -1; |
| 1836 | } |
Rashika Kheria | 34e987e | 2013-11-07 19:15:48 +0530 | [diff] [blame] | 1837 | entry->BufferAddress = *mapping; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1838 | |
| 1839 | entry->Length = priv->rxbuffersize; |
| 1840 | entry->OWN = 1; |
| 1841 | } |
| 1842 | |
Mateusz Kulikowski | f669228 | 2015-04-13 23:47:27 +0200 | [diff] [blame] | 1843 | if (entry) |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 1844 | entry->EOR = 1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1845 | } |
| 1846 | return 0; |
| 1847 | } |
| 1848 | |
Mateusz Kulikowski | bf1ddf2 | 2015-09-20 10:13:01 +0200 | [diff] [blame] | 1849 | static int _rtl92e_alloc_tx_ring(struct net_device *dev, unsigned int prio, |
| 1850 | unsigned int entries) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1851 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 1852 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1853 | struct tx_desc *ring; |
| 1854 | dma_addr_t dma; |
| 1855 | int i; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1856 | |
Joe Perches | 8b983be | 2014-08-08 14:24:48 -0700 | [diff] [blame] | 1857 | ring = pci_zalloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1858 | if (!ring || (unsigned long)ring & 0xFF) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 1859 | netdev_warn(dev, "Cannot allocate TX ring (prio = %d)\n", prio); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1860 | return -ENOMEM; |
| 1861 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1862 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1863 | priv->tx_ring[prio].desc = ring; |
| 1864 | priv->tx_ring[prio].dma = dma; |
| 1865 | priv->tx_ring[prio].idx = 0; |
| 1866 | priv->tx_ring[prio].entries = entries; |
| 1867 | skb_queue_head_init(&priv->tx_ring[prio].queue); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1868 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1869 | for (i = 0; i < entries; i++) |
| 1870 | ring[i].NextDescAddress = |
Rashika Kheria | 34e987e | 2013-11-07 19:15:48 +0530 | [diff] [blame] | 1871 | (u32)dma + ((i + 1) % entries) * |
| 1872 | sizeof(*ring); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1873 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1874 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1875 | } |
| 1876 | |
Mateusz Kulikowski | 197917a | 2015-09-20 10:12:56 +0200 | [diff] [blame] | 1877 | static short _rtl92e_pci_initdescring(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1878 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1879 | u32 ret; |
| 1880 | int i; |
| 1881 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1882 | |
Mateusz Kulikowski | 9d14896 | 2015-09-20 10:13:00 +0200 | [diff] [blame] | 1883 | ret = _rtl92e_alloc_rx_ring(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1884 | if (ret) |
| 1885 | return ret; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1886 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1887 | for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { |
Mateusz Kulikowski | bf1ddf2 | 2015-09-20 10:13:01 +0200 | [diff] [blame] | 1888 | ret = _rtl92e_alloc_tx_ring(dev, i, priv->txringcount); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1889 | if (ret) |
| 1890 | goto err_free_rings; |
| 1891 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1892 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1893 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1894 | |
| 1895 | err_free_rings: |
Mateusz Kulikowski | 694f9d3 | 2015-09-20 10:13:02 +0200 | [diff] [blame] | 1896 | _rtl92e_free_rx_ring(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1897 | for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) |
| 1898 | if (priv->tx_ring[i].desc) |
Mateusz Kulikowski | ebc36ec | 2015-09-20 10:13:03 +0200 | [diff] [blame] | 1899 | _rtl92e_free_tx_ring(dev, i); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1900 | return 1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1901 | } |
| 1902 | |
Mateusz Kulikowski | 36154dc | 2015-07-19 19:28:16 +0200 | [diff] [blame] | 1903 | void rtl92e_reset_desc_ring(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1904 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1905 | struct r8192_priv *priv = rtllib_priv(dev); |
| 1906 | int i, rx_queue_idx; |
| 1907 | unsigned long flags = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1908 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1909 | for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1910 | if (priv->rx_ring[rx_queue_idx]) { |
Larry Finger | 4f534b3 | 2011-07-18 22:52:12 -0500 | [diff] [blame] | 1911 | struct rx_desc *entry = NULL; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 1912 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1913 | for (i = 0; i < priv->rxringcount; i++) { |
| 1914 | entry = &priv->rx_ring[rx_queue_idx][i]; |
| 1915 | entry->OWN = 1; |
| 1916 | } |
| 1917 | priv->rx_idx[rx_queue_idx] = 0; |
| 1918 | } |
| 1919 | } |
| 1920 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1921 | spin_lock_irqsave(&priv->irq_th_lock, flags); |
| 1922 | for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { |
| 1923 | if (priv->tx_ring[i].desc) { |
| 1924 | struct rtl8192_tx_ring *ring = &priv->tx_ring[i]; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1925 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1926 | while (skb_queue_len(&ring->queue)) { |
| 1927 | struct tx_desc *entry = &ring->desc[ring->idx]; |
| 1928 | struct sk_buff *skb = |
| 1929 | __skb_dequeue(&ring->queue); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1930 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1931 | pci_unmap_single(priv->pdev, |
Rashika Kheria | 466bc7f2 | 2013-11-07 19:16:36 +0530 | [diff] [blame] | 1932 | entry->TxBuffAddr, |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1933 | skb->len, PCI_DMA_TODEVICE); |
| 1934 | kfree_skb(skb); |
| 1935 | ring->idx = (ring->idx + 1) % ring->entries; |
| 1936 | } |
| 1937 | ring->idx = 0; |
| 1938 | } |
| 1939 | } |
| 1940 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1941 | } |
| 1942 | |
Mateusz Kulikowski | 7879efc | 2015-07-19 19:28:24 +0200 | [diff] [blame] | 1943 | void rtl92e_update_rx_pkt_timestamp(struct net_device *dev, |
| 1944 | struct rtllib_rx_stats *stats) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1945 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 1946 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1947 | |
Larry Finger | 0dd5650 | 2011-08-25 11:48:12 -0500 | [diff] [blame] | 1948 | if (stats->bIsAMPDU && !stats->bFirstMPDU) |
| 1949 | stats->mac_time = priv->LastRxDescTSF; |
| 1950 | else |
| 1951 | priv->LastRxDescTSF = stats->mac_time; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1952 | } |
| 1953 | |
Mateusz Kulikowski | f54f10b | 2015-07-19 19:28:23 +0200 | [diff] [blame] | 1954 | long rtl92e_translate_to_dbm(struct r8192_priv *priv, u8 signal_strength_index) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1955 | { |
| 1956 | long signal_power; |
| 1957 | |
| 1958 | signal_power = (long)((signal_strength_index + 1) >> 1); |
| 1959 | signal_power -= 95; |
| 1960 | |
| 1961 | return signal_power; |
| 1962 | } |
| 1963 | |
| 1964 | |
Mateusz Kulikowski | 97ef450 | 2015-07-19 19:28:25 +0200 | [diff] [blame] | 1965 | void rtl92e_update_rx_statistics(struct r8192_priv *priv, |
| 1966 | struct rtllib_rx_stats *pprevious_stats) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1967 | { |
| 1968 | int weighting = 0; |
| 1969 | |
| 1970 | |
| 1971 | if (priv->stats.recv_signal_power == 0) |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1972 | priv->stats.recv_signal_power = |
| 1973 | pprevious_stats->RecvSignalPower; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1974 | |
| 1975 | if (pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power) |
| 1976 | weighting = 5; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1977 | else if (pprevious_stats->RecvSignalPower < |
| 1978 | priv->stats.recv_signal_power) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1979 | weighting = (-5); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1980 | priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + |
| 1981 | pprevious_stats->RecvSignalPower + |
| 1982 | weighting) / 6; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1983 | } |
| 1984 | |
Mateusz Kulikowski | aa80403 | 2015-07-19 19:28:22 +0200 | [diff] [blame] | 1985 | u8 rtl92e_rx_db_to_percent(char antpower) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1986 | { |
| 1987 | if ((antpower <= -100) || (antpower >= 20)) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1988 | return 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1989 | else if (antpower >= 0) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1990 | return 100; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1991 | else |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 1992 | return 100 + antpower; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1993 | |
| 1994 | } /* QueryRxPwrPercentage */ |
| 1995 | |
Mateusz Kulikowski | 6b89d0e | 2015-07-19 19:28:21 +0200 | [diff] [blame] | 1996 | u8 rtl92e_evm_db_to_percent(char value) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 1997 | { |
| 1998 | char ret_val; |
| 1999 | |
| 2000 | ret_val = value; |
| 2001 | |
| 2002 | if (ret_val >= 0) |
| 2003 | ret_val = 0; |
| 2004 | if (ret_val <= -33) |
| 2005 | ret_val = -33; |
| 2006 | ret_val = 0 - ret_val; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2007 | ret_val *= 3; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2008 | if (ret_val == 99) |
| 2009 | ret_val = 100; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2010 | return ret_val; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2011 | } |
| 2012 | |
Mateusz Kulikowski | e58701d | 2015-07-19 19:28:17 +0200 | [diff] [blame] | 2013 | void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats, |
| 2014 | struct rtllib_rx_stats *ptarget_stats) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2015 | { |
| 2016 | ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU; |
| 2017 | ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU; |
| 2018 | } |
| 2019 | |
| 2020 | |
| 2021 | |
Mateusz Kulikowski | 0ba8f7c | 2015-09-20 10:13:11 +0200 | [diff] [blame] | 2022 | static void _rtl92e_rx_normal(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2023 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 2024 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2025 | struct rtllib_hdr_1addr *rtllib_hdr = NULL; |
| 2026 | bool unicast_packet = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2027 | bool bLedBlinking = true; |
| 2028 | u16 fc = 0, type = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2029 | u32 skb_len = 0; |
| 2030 | int rx_queue_idx = RX_MPDU_QUEUE; |
| 2031 | |
| 2032 | struct rtllib_rx_stats stats = { |
| 2033 | .signal = 0, |
Gujulan Elango, Hari Prasath (H.) | 94e057d | 2015-05-04 09:29:05 +0000 | [diff] [blame] | 2034 | .noise = (u8) -98, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2035 | .rate = 0, |
| 2036 | .freq = RTLLIB_24GHZ_BAND, |
| 2037 | }; |
| 2038 | unsigned int count = priv->rxringcount; |
| 2039 | |
| 2040 | stats.nic_type = NIC_8192E; |
| 2041 | |
| 2042 | while (count--) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2043 | struct rx_desc *pdesc = &priv->rx_ring[rx_queue_idx] |
| 2044 | [priv->rx_idx[rx_queue_idx]]; |
| 2045 | struct sk_buff *skb = priv->rx_buf[rx_queue_idx] |
| 2046 | [priv->rx_idx[rx_queue_idx]]; |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 2047 | struct sk_buff *new_skb; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2048 | |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 2049 | if (pdesc->OWN) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2050 | return; |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 2051 | if (!priv->ops->rx_query_status_descriptor(dev, &stats, |
| 2052 | pdesc, skb)) |
| 2053 | goto done; |
| 2054 | new_skb = dev_alloc_skb(priv->rxbuffersize); |
| 2055 | /* if allocation of new skb failed - drop current packet |
Mateusz Kulikowski | 14b40d9 | 2015-04-01 00:24:37 +0200 | [diff] [blame] | 2056 | * and reuse skb |
| 2057 | */ |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 2058 | if (unlikely(!new_skb)) |
| 2059 | goto done; |
| 2060 | |
| 2061 | pci_unmap_single(priv->pdev, |
| 2062 | *((dma_addr_t *)skb->cb), |
| 2063 | priv->rxbuffersize, |
| 2064 | PCI_DMA_FROMDEVICE); |
| 2065 | |
| 2066 | skb_put(skb, pdesc->Length); |
| 2067 | skb_reserve(skb, stats.RxDrvInfoSize + |
| 2068 | stats.RxBufShift); |
| 2069 | skb_trim(skb, skb->len - 4/*sCrcLng*/); |
| 2070 | rtllib_hdr = (struct rtllib_hdr_1addr *)skb->data; |
| 2071 | if (!is_multicast_ether_addr(rtllib_hdr->addr1)) { |
| 2072 | /* unicast packet */ |
| 2073 | unicast_packet = true; |
| 2074 | } |
| 2075 | fc = le16_to_cpu(rtllib_hdr->frame_ctl); |
| 2076 | type = WLAN_FC_GET_TYPE(fc); |
| 2077 | if (type == RTLLIB_FTYPE_MGMT) |
| 2078 | bLedBlinking = false; |
| 2079 | |
| 2080 | if (bLedBlinking) |
| 2081 | if (priv->rtllib->LedControlHandler) |
| 2082 | priv->rtllib->LedControlHandler(dev, |
| 2083 | LED_CTL_RX); |
| 2084 | |
| 2085 | if (stats.bCRC) { |
| 2086 | if (type != RTLLIB_FTYPE_MGMT) |
| 2087 | priv->stats.rxdatacrcerr++; |
| 2088 | else |
| 2089 | priv->stats.rxmgmtcrcerr++; |
| 2090 | } |
| 2091 | |
| 2092 | skb_len = skb->len; |
| 2093 | |
| 2094 | if (!rtllib_rx(priv->rtllib, skb, &stats)) { |
| 2095 | dev_kfree_skb_any(skb); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2096 | } else { |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 2097 | priv->stats.rxok++; |
| 2098 | if (unicast_packet) |
| 2099 | priv->stats.rxbytesunicast += skb_len; |
| 2100 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2101 | |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 2102 | skb = new_skb; |
| 2103 | skb->dev = dev; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2104 | |
Mateusz Kulikowski | 285b7c0 | 2015-04-01 00:24:26 +0200 | [diff] [blame] | 2105 | priv->rx_buf[rx_queue_idx][priv->rx_idx[rx_queue_idx]] = |
| 2106 | skb; |
| 2107 | *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, |
| 2108 | skb_tail_pointer_rsl(skb), |
| 2109 | priv->rxbuffersize, |
| 2110 | PCI_DMA_FROMDEVICE); |
| 2111 | if (pci_dma_mapping_error(priv->pdev, |
| 2112 | *((dma_addr_t *)skb->cb))) { |
| 2113 | dev_kfree_skb_any(skb); |
| 2114 | return; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2115 | } |
| 2116 | done: |
Rashika Kheria | 34e987e | 2013-11-07 19:15:48 +0530 | [diff] [blame] | 2117 | pdesc->BufferAddress = *((dma_addr_t *)skb->cb); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2118 | pdesc->OWN = 1; |
| 2119 | pdesc->Length = priv->rxbuffersize; |
| 2120 | if (priv->rx_idx[rx_queue_idx] == priv->rxringcount-1) |
| 2121 | pdesc->EOR = 1; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2122 | priv->rx_idx[rx_queue_idx] = (priv->rx_idx[rx_queue_idx] + 1) % |
| 2123 | priv->rxringcount; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2124 | } |
| 2125 | |
| 2126 | } |
| 2127 | |
Mateusz Kulikowski | a67c790 | 2015-09-20 10:13:08 +0200 | [diff] [blame] | 2128 | static void _rtl92e_tx_resume(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2129 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 2130 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2131 | struct rtllib_device *ieee = priv->rtllib; |
| 2132 | struct sk_buff *skb; |
| 2133 | int queue_index; |
| 2134 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2135 | for (queue_index = BK_QUEUE; |
| 2136 | queue_index < MAX_QUEUE_SIZE; queue_index++) { |
| 2137 | while ((!skb_queue_empty(&ieee->skb_waitQ[queue_index])) && |
| 2138 | (priv->rtllib->check_nic_enough_desc(dev, queue_index) > 0)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2139 | skb = skb_dequeue(&ieee->skb_waitQ[queue_index]); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2140 | ieee->softmac_data_hard_start_xmit(skb, dev, 0); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2141 | } |
| 2142 | } |
| 2143 | } |
| 2144 | |
Mateusz Kulikowski | a2743b2 | 2015-09-20 10:09:30 +0200 | [diff] [blame] | 2145 | static void _rtl92e_irq_tx_tasklet(struct r8192_priv *priv) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2146 | { |
Mateusz Kulikowski | a67c790 | 2015-09-20 10:13:08 +0200 | [diff] [blame] | 2147 | _rtl92e_tx_resume(priv->rtllib->dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2148 | } |
| 2149 | |
Mateusz Kulikowski | 2940405 | 2015-09-20 10:09:29 +0200 | [diff] [blame] | 2150 | static void _rtl92e_irq_rx_tasklet(struct r8192_priv *priv) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2151 | { |
Mateusz Kulikowski | 0ba8f7c | 2015-09-20 10:13:11 +0200 | [diff] [blame] | 2152 | _rtl92e_rx_normal(priv->rtllib->dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2153 | |
Mateusz Kulikowski | 8ea5410 | 2015-07-19 19:28:27 +0200 | [diff] [blame] | 2154 | rtl92e_writel(priv->rtllib->dev, INTA_MASK, |
| 2155 | rtl92e_readl(priv->rtllib->dev, INTA_MASK) | IMR_RDU); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2156 | } |
| 2157 | |
| 2158 | /**************************************************************************** |
| 2159 | ---------------------------- NIC START/CLOSE STUFF--------------------------- |
| 2160 | *****************************************************************************/ |
Mateusz Kulikowski | 4dba03a | 2015-09-20 10:14:12 +0200 | [diff] [blame] | 2161 | static void _rtl92e_cancel_deferred_work(struct r8192_priv *priv) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2162 | { |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 2163 | cancel_delayed_work_sync(&priv->watch_dog_wq); |
| 2164 | cancel_delayed_work_sync(&priv->update_beacon_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2165 | cancel_delayed_work(&priv->rtllib->hw_sleep_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2166 | cancel_work_sync(&priv->reset_wq); |
| 2167 | cancel_work_sync(&priv->qos_activate); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2168 | } |
| 2169 | |
Mateusz Kulikowski | 81524bb | 2015-09-20 10:12:54 +0200 | [diff] [blame] | 2170 | static int _rtl92e_up(struct net_device *dev, bool is_silent_reset) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2171 | { |
Mateusz Kulikowski | dba0e06 | 2015-09-20 10:13:34 +0200 | [diff] [blame] | 2172 | if (_rtl92e_sta_up(dev, is_silent_reset) == -1) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2173 | return -1; |
| 2174 | return 0; |
| 2175 | } |
| 2176 | |
Mateusz Kulikowski | 27d673b | 2015-09-20 10:12:49 +0200 | [diff] [blame] | 2177 | static int _rtl92e_open(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2178 | { |
| 2179 | struct r8192_priv *priv = rtllib_priv(dev); |
| 2180 | int ret; |
| 2181 | |
| 2182 | down(&priv->wx_sem); |
Mateusz Kulikowski | b1665a6 | 2015-09-20 10:12:53 +0200 | [diff] [blame] | 2183 | ret = _rtl92e_try_up(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2184 | up(&priv->wx_sem); |
| 2185 | return ret; |
| 2186 | |
| 2187 | } |
| 2188 | |
Mateusz Kulikowski | b1665a6 | 2015-09-20 10:12:53 +0200 | [diff] [blame] | 2189 | static int _rtl92e_try_up(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2190 | { |
| 2191 | struct r8192_priv *priv = rtllib_priv(dev); |
| 2192 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2193 | if (priv->up == 1) |
| 2194 | return -1; |
Mateusz Kulikowski | 81524bb | 2015-09-20 10:12:54 +0200 | [diff] [blame] | 2195 | return _rtl92e_up(dev, false); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2196 | } |
| 2197 | |
| 2198 | |
Mateusz Kulikowski | 27cbba6 | 2015-09-20 10:12:50 +0200 | [diff] [blame] | 2199 | static int _rtl92e_close(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2200 | { |
| 2201 | struct r8192_priv *priv = rtllib_priv(dev); |
| 2202 | int ret; |
| 2203 | |
| 2204 | if ((rtllib_act_scanning(priv->rtllib, false)) && |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2205 | !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2206 | rtllib_stop_scan(priv->rtllib); |
| 2207 | } |
| 2208 | |
| 2209 | down(&priv->wx_sem); |
| 2210 | |
Mateusz Kulikowski | 33bec9b | 2015-09-20 10:12:51 +0200 | [diff] [blame] | 2211 | ret = _rtl92e_down(dev, true); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2212 | |
| 2213 | up(&priv->wx_sem); |
| 2214 | |
| 2215 | return ret; |
| 2216 | |
| 2217 | } |
| 2218 | |
Mateusz Kulikowski | 33bec9b | 2015-09-20 10:12:51 +0200 | [diff] [blame] | 2219 | static int _rtl92e_down(struct net_device *dev, bool shutdownrf) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2220 | { |
Mateusz Kulikowski | 2b19e22 | 2015-09-20 10:13:33 +0200 | [diff] [blame] | 2221 | if (_rtl92e_sta_down(dev, shutdownrf) == -1) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2222 | return -1; |
| 2223 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2224 | return 0; |
| 2225 | } |
| 2226 | |
Mateusz Kulikowski | bc4f2cc | 2015-07-19 19:28:12 +0200 | [diff] [blame] | 2227 | void rtl92e_commit(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2228 | { |
| 2229 | struct r8192_priv *priv = rtllib_priv(dev); |
| 2230 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2231 | if (priv->up == 0) |
| 2232 | return; |
Mateusz Kulikowski | f669228 | 2015-04-13 23:47:27 +0200 | [diff] [blame] | 2233 | rtllib_softmac_stop_protocol(priv->rtllib, 0, true); |
Mateusz Kulikowski | b7b50d6 | 2015-07-19 19:28:14 +0200 | [diff] [blame] | 2234 | rtl92e_irq_disable(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2235 | priv->ops->stop_adapter(dev, true); |
Mateusz Kulikowski | 81524bb | 2015-09-20 10:12:54 +0200 | [diff] [blame] | 2236 | _rtl92e_up(dev, false); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2237 | } |
| 2238 | |
Mateusz Kulikowski | 78e67df | 2015-09-20 10:12:52 +0200 | [diff] [blame] | 2239 | static void _rtl92e_restart(void *data) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2240 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2241 | struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv, |
| 2242 | reset_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2243 | struct net_device *dev = priv->rtllib->dev; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2244 | |
| 2245 | down(&priv->wx_sem); |
| 2246 | |
Mateusz Kulikowski | bc4f2cc | 2015-07-19 19:28:12 +0200 | [diff] [blame] | 2247 | rtl92e_commit(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2248 | |
| 2249 | up(&priv->wx_sem); |
| 2250 | } |
| 2251 | |
Mateusz Kulikowski | 2002978 | 2015-09-20 10:14:11 +0200 | [diff] [blame] | 2252 | static void _rtl92e_set_multicast(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2253 | { |
| 2254 | struct r8192_priv *priv = rtllib_priv(dev); |
| 2255 | short promisc; |
| 2256 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2257 | promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2258 | priv->promisc = promisc; |
| 2259 | |
| 2260 | } |
| 2261 | |
| 2262 | |
Mateusz Kulikowski | 3ef7f1e | 2015-09-20 10:14:10 +0200 | [diff] [blame] | 2263 | static int _rtl92e_set_mac_adr(struct net_device *dev, void *mac) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2264 | { |
| 2265 | struct r8192_priv *priv = rtllib_priv(dev); |
| 2266 | struct sockaddr *addr = mac; |
| 2267 | |
| 2268 | down(&priv->wx_sem); |
| 2269 | |
Melike Yurtoglu | 1f3aefb | 2015-02-22 16:58:08 +0200 | [diff] [blame] | 2270 | ether_addr_copy(dev->dev_addr, addr->sa_data); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2271 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2272 | schedule_work(&priv->reset_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2273 | up(&priv->wx_sem); |
| 2274 | |
| 2275 | return 0; |
| 2276 | } |
| 2277 | |
| 2278 | /* based on ipw2200 driver */ |
Mateusz Kulikowski | 09c26de | 2015-09-20 10:12:48 +0200 | [diff] [blame] | 2279 | static int _rtl92e_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2280 | { |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 2281 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2282 | struct iwreq *wrq = (struct iwreq *)rq; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2283 | int ret = -1; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2284 | struct rtllib_device *ieee = priv->rtllib; |
| 2285 | u32 key[4]; |
Mateusz Kulikowski | 06c1110 | 2015-05-31 20:19:21 +0200 | [diff] [blame] | 2286 | const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2287 | struct iw_point *p = &wrq->u.data; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2288 | struct ieee_param *ipw = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2289 | |
| 2290 | down(&priv->wx_sem); |
| 2291 | |
| 2292 | switch (cmd) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2293 | case RTL_IOCTL_WPA_SUPPLICANT: |
| 2294 | if (p->length < sizeof(struct ieee_param) || !p->pointer) { |
| 2295 | ret = -EINVAL; |
| 2296 | goto out; |
| 2297 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2298 | |
Teodora Baluta | 2162498 | 2013-10-26 09:18:22 +0300 | [diff] [blame] | 2299 | ipw = memdup_user(p->pointer, p->length); |
| 2300 | if (IS_ERR(ipw)) { |
| 2301 | ret = PTR_ERR(ipw); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2302 | goto out; |
| 2303 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2304 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2305 | if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) { |
| 2306 | if (ipw->u.crypt.set_tx) { |
| 2307 | if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) |
| 2308 | ieee->pairwise_key_type = KEY_TYPE_CCMP; |
| 2309 | else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) |
| 2310 | ieee->pairwise_key_type = KEY_TYPE_TKIP; |
| 2311 | else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { |
| 2312 | if (ipw->u.crypt.key_len == 13) |
| 2313 | ieee->pairwise_key_type = |
| 2314 | KEY_TYPE_WEP104; |
| 2315 | else if (ipw->u.crypt.key_len == 5) |
| 2316 | ieee->pairwise_key_type = |
| 2317 | KEY_TYPE_WEP40; |
| 2318 | } else { |
| 2319 | ieee->pairwise_key_type = KEY_TYPE_NA; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2320 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2321 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2322 | if (ieee->pairwise_key_type) { |
Mateusz Kulikowski | 06c1110 | 2015-05-31 20:19:21 +0200 | [diff] [blame] | 2323 | if (is_zero_ether_addr(ieee->ap_mac_addr)) |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2324 | ieee->iw_mode = IW_MODE_ADHOC; |
| 2325 | memcpy((u8 *)key, ipw->u.crypt.key, 16); |
Mateusz Kulikowski | 3742093 | 2015-07-19 19:28:02 +0200 | [diff] [blame] | 2326 | rtl92e_enable_hw_security_config(dev); |
Mateusz Kulikowski | aae7e72 | 2015-07-19 19:28:04 +0200 | [diff] [blame] | 2327 | rtl92e_set_swcam(dev, 4, |
| 2328 | ipw->u.crypt.idx, |
| 2329 | ieee->pairwise_key_type, |
| 2330 | (u8 *)ieee->ap_mac_addr, |
| 2331 | 0, key, 0); |
Mateusz Kulikowski | 408bd7b | 2015-07-19 19:28:03 +0200 | [diff] [blame] | 2332 | rtl92e_set_key(dev, 4, ipw->u.crypt.idx, |
| 2333 | ieee->pairwise_key_type, |
| 2334 | (u8 *)ieee->ap_mac_addr, |
| 2335 | 0, key); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2336 | if (ieee->iw_mode == IW_MODE_ADHOC) { |
Mateusz Kulikowski | aae7e72 | 2015-07-19 19:28:04 +0200 | [diff] [blame] | 2337 | rtl92e_set_swcam(dev, |
| 2338 | ipw->u.crypt.idx, |
| 2339 | ipw->u.crypt.idx, |
| 2340 | ieee->pairwise_key_type, |
| 2341 | (u8 *)ieee->ap_mac_addr, |
| 2342 | 0, key, 0); |
Mateusz Kulikowski | 408bd7b | 2015-07-19 19:28:03 +0200 | [diff] [blame] | 2343 | rtl92e_set_key(dev, |
| 2344 | ipw->u.crypt.idx, |
| 2345 | ipw->u.crypt.idx, |
| 2346 | ieee->pairwise_key_type, |
| 2347 | (u8 *)ieee->ap_mac_addr, |
| 2348 | 0, key); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2349 | } |
| 2350 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2351 | if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) |
| 2352 | && ieee->pHTInfo->bCurrentHTSupport) { |
Mateusz Kulikowski | d8ae196 | 2015-07-19 19:28:26 +0200 | [diff] [blame] | 2353 | rtl92e_writeb(dev, 0x173, 1); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2354 | } |
| 2355 | |
| 2356 | } else { |
| 2357 | memcpy((u8 *)key, ipw->u.crypt.key, 16); |
| 2358 | if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) |
| 2359 | ieee->group_key_type = KEY_TYPE_CCMP; |
| 2360 | else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) |
| 2361 | ieee->group_key_type = KEY_TYPE_TKIP; |
| 2362 | else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { |
| 2363 | if (ipw->u.crypt.key_len == 13) |
| 2364 | ieee->group_key_type = |
| 2365 | KEY_TYPE_WEP104; |
| 2366 | else if (ipw->u.crypt.key_len == 5) |
| 2367 | ieee->group_key_type = |
| 2368 | KEY_TYPE_WEP40; |
| 2369 | } else |
| 2370 | ieee->group_key_type = KEY_TYPE_NA; |
| 2371 | |
| 2372 | if (ieee->group_key_type) { |
Mateusz Kulikowski | aae7e72 | 2015-07-19 19:28:04 +0200 | [diff] [blame] | 2373 | rtl92e_set_swcam(dev, ipw->u.crypt.idx, |
| 2374 | ipw->u.crypt.idx, |
| 2375 | ieee->group_key_type, |
| 2376 | broadcast_addr, 0, key, |
| 2377 | 0); |
Mateusz Kulikowski | 408bd7b | 2015-07-19 19:28:03 +0200 | [diff] [blame] | 2378 | rtl92e_set_key(dev, ipw->u.crypt.idx, |
| 2379 | ipw->u.crypt.idx, |
| 2380 | ieee->group_key_type, |
| 2381 | broadcast_addr, 0, key); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2382 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2383 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2384 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2385 | |
| 2386 | ret = rtllib_wpa_supplicant_ioctl(priv->rtllib, &wrq->u.data, |
| 2387 | 0); |
| 2388 | kfree(ipw); |
| 2389 | break; |
| 2390 | default: |
| 2391 | ret = -EOPNOTSUPP; |
| 2392 | break; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2393 | } |
| 2394 | |
| 2395 | out: |
| 2396 | up(&priv->wx_sem); |
| 2397 | |
| 2398 | return ret; |
| 2399 | } |
| 2400 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2401 | |
Mateusz Kulikowski | 87e01f2 | 2015-09-20 10:09:28 +0200 | [diff] [blame] | 2402 | static irqreturn_t _rtl92e_irq(int irq, void *netdev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2403 | { |
Janani Ravichandran | 314e4be | 2016-02-25 14:56:33 -0500 | [diff] [blame] | 2404 | struct net_device *dev = netdev; |
Janani Ravichandran | a4eed41 | 2016-02-16 12:24:40 -0500 | [diff] [blame] | 2405 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2406 | unsigned long flags; |
| 2407 | u32 inta; |
| 2408 | u32 intb; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 2409 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2410 | intb = 0; |
| 2411 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2412 | if (priv->irq_enabled == 0) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2413 | goto done; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2414 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2415 | spin_lock_irqsave(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2416 | |
| 2417 | priv->ops->interrupt_recognized(dev, &inta, &intb); |
| 2418 | priv->stats.shints++; |
| 2419 | |
| 2420 | if (!inta) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2421 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2422 | goto done; |
| 2423 | } |
| 2424 | |
| 2425 | if (inta == 0xffff) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2426 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2427 | goto done; |
| 2428 | } |
| 2429 | |
| 2430 | priv->stats.ints++; |
| 2431 | |
| 2432 | if (!netif_running(dev)) { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2433 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2434 | goto done; |
| 2435 | } |
| 2436 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2437 | if (inta & IMR_TBDOK) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2438 | RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); |
| 2439 | priv->stats.txbeaconokint++; |
| 2440 | } |
| 2441 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2442 | if (inta & IMR_TBDER) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2443 | RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); |
| 2444 | priv->stats.txbeaconerr++; |
| 2445 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2446 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2447 | if (inta & IMR_BDOK) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2448 | RT_TRACE(COMP_INTR, "beacon interrupt!\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2449 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2450 | if (inta & IMR_MGNTDOK) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2451 | RT_TRACE(COMP_INTR, "Manage ok interrupt!\n"); |
| 2452 | priv->stats.txmanageokint++; |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 2453 | _rtl92e_tx_isr(dev, MGNT_QUEUE); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2454 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
| 2455 | if (priv->rtllib->ack_tx_to_ieee) { |
Mateusz Kulikowski | 6f8d4a7 | 2015-09-20 10:13:09 +0200 | [diff] [blame] | 2456 | if (_rtl92e_is_tx_queue_empty(dev)) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2457 | priv->rtllib->ack_tx_to_ieee = 0; |
| 2458 | rtllib_ps_tx_ack(priv->rtllib, 1); |
| 2459 | } |
| 2460 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2461 | spin_lock_irqsave(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2462 | } |
| 2463 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2464 | if (inta & IMR_COMDOK) { |
| 2465 | priv->stats.txcmdpktokint++; |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 2466 | _rtl92e_tx_isr(dev, TXCMD_QUEUE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2467 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2468 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2469 | if (inta & IMR_HIGHDOK) |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 2470 | _rtl92e_tx_isr(dev, HIGH_QUEUE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2471 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2472 | if (inta & IMR_ROK) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2473 | priv->stats.rxint++; |
| 2474 | priv->InterruptLog.nIMR_ROK++; |
| 2475 | tasklet_schedule(&priv->irq_rx_tasklet); |
| 2476 | } |
| 2477 | |
| 2478 | if (inta & IMR_BcnInt) { |
| 2479 | RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2480 | tasklet_schedule(&priv->irq_prepare_beacon_tasklet); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2481 | } |
| 2482 | |
| 2483 | if (inta & IMR_RDU) { |
| 2484 | RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n"); |
| 2485 | priv->stats.rxrdu++; |
Mateusz Kulikowski | 8ea5410 | 2015-07-19 19:28:27 +0200 | [diff] [blame] | 2486 | rtl92e_writel(dev, INTA_MASK, |
| 2487 | rtl92e_readl(dev, INTA_MASK) & ~IMR_RDU); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2488 | tasklet_schedule(&priv->irq_rx_tasklet); |
| 2489 | } |
| 2490 | |
| 2491 | if (inta & IMR_RXFOVW) { |
| 2492 | RT_TRACE(COMP_INTR, "rx overflow !\n"); |
| 2493 | priv->stats.rxoverflow++; |
| 2494 | tasklet_schedule(&priv->irq_rx_tasklet); |
| 2495 | } |
| 2496 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2497 | if (inta & IMR_TXFOVW) |
| 2498 | priv->stats.txoverflow++; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2499 | |
| 2500 | if (inta & IMR_BKDOK) { |
| 2501 | RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n"); |
| 2502 | priv->stats.txbkokint++; |
| 2503 | priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 2504 | _rtl92e_tx_isr(dev, BK_QUEUE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2505 | } |
| 2506 | |
| 2507 | if (inta & IMR_BEDOK) { |
| 2508 | RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n"); |
| 2509 | priv->stats.txbeokint++; |
| 2510 | priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 2511 | _rtl92e_tx_isr(dev, BE_QUEUE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2512 | } |
| 2513 | |
| 2514 | if (inta & IMR_VIDOK) { |
| 2515 | RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n"); |
| 2516 | priv->stats.txviokint++; |
| 2517 | priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 2518 | _rtl92e_tx_isr(dev, VI_QUEUE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2519 | } |
| 2520 | |
| 2521 | if (inta & IMR_VODOK) { |
| 2522 | priv->stats.txvookint++; |
| 2523 | RT_TRACE(COMP_INTR, "Vo TX OK interrupt!\n"); |
| 2524 | priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; |
Mateusz Kulikowski | 7effc87 | 2015-09-20 10:13:06 +0200 | [diff] [blame] | 2525 | _rtl92e_tx_isr(dev, VO_QUEUE); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2526 | } |
| 2527 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2528 | spin_unlock_irqrestore(&priv->irq_th_lock, flags); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2529 | |
| 2530 | done: |
| 2531 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2532 | return IRQ_HANDLED; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2533 | } |
| 2534 | |
| 2535 | |
| 2536 | |
| 2537 | /**************************************************************************** |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2538 | ---------------------------- PCI_STUFF--------------------------- |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2539 | *****************************************************************************/ |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2540 | static const struct net_device_ops rtl8192_netdev_ops = { |
Mateusz Kulikowski | 27d673b | 2015-09-20 10:12:49 +0200 | [diff] [blame] | 2541 | .ndo_open = _rtl92e_open, |
Mateusz Kulikowski | 27cbba6 | 2015-09-20 10:12:50 +0200 | [diff] [blame] | 2542 | .ndo_stop = _rtl92e_close, |
Mateusz Kulikowski | ac39265 | 2015-09-20 10:13:07 +0200 | [diff] [blame] | 2543 | .ndo_tx_timeout = _rtl92e_tx_timeout, |
Mateusz Kulikowski | 09c26de | 2015-09-20 10:12:48 +0200 | [diff] [blame] | 2544 | .ndo_do_ioctl = _rtl92e_ioctl, |
Mateusz Kulikowski | 2002978 | 2015-09-20 10:14:11 +0200 | [diff] [blame] | 2545 | .ndo_set_rx_mode = _rtl92e_set_multicast, |
Mateusz Kulikowski | 3ef7f1e | 2015-09-20 10:14:10 +0200 | [diff] [blame] | 2546 | .ndo_set_mac_address = _rtl92e_set_mac_adr, |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2547 | .ndo_validate_addr = eth_validate_addr, |
| 2548 | .ndo_change_mtu = eth_change_mtu, |
| 2549 | .ndo_start_xmit = rtllib_xmit, |
| 2550 | }; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2551 | |
Mateusz Kulikowski | 93cc57b | 2015-09-20 10:12:59 +0200 | [diff] [blame] | 2552 | static int _rtl92e_pci_probe(struct pci_dev *pdev, |
| 2553 | const struct pci_device_id *id) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2554 | { |
| 2555 | unsigned long ioaddr = 0; |
| 2556 | struct net_device *dev = NULL; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2557 | struct r8192_priv *priv = NULL; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2558 | struct rtl819x_ops *ops = (struct rtl819x_ops *)(id->driver_data); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2559 | unsigned long pmem_start, pmem_len, pmem_flags; |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2560 | int err = -ENOMEM; |
Mike McCormack | 1ec3e2f | 2011-07-11 08:56:20 +0900 | [diff] [blame] | 2561 | u8 revision_id; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2562 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2563 | RT_TRACE(COMP_INIT, "Configuring chip resources"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2564 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2565 | if (pci_enable_device(pdev)) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 2566 | dev_err(&pdev->dev, "Failed to enable PCI device"); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2567 | return -EIO; |
| 2568 | } |
| 2569 | |
| 2570 | pci_set_master(pdev); |
| 2571 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2572 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { |
| 2573 | if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 2574 | dev_info(&pdev->dev, |
| 2575 | "Unable to obtain 32bit DMA for consistent allocations\n"); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2576 | goto err_pci_disable; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2577 | } |
| 2578 | } |
| 2579 | dev = alloc_rtllib(sizeof(struct r8192_priv)); |
| 2580 | if (!dev) |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2581 | goto err_pci_disable; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2582 | |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2583 | err = -ENODEV; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2584 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2585 | pci_set_drvdata(pdev, dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2586 | SET_NETDEV_DEV(dev, &pdev->dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2587 | priv = rtllib_priv(dev); |
| 2588 | priv->rtllib = (struct rtllib_device *)netdev_priv_rsl(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2589 | priv->pdev = pdev; |
| 2590 | priv->rtllib->pdev = pdev; |
| 2591 | if ((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK) && |
| 2592 | (pdev->subsystem_device == 0x3304)) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2593 | priv->rtllib->bSupportRemoteWakeUp = 1; |
Mike McCormack | cb76215 | 2011-07-11 08:56:20 +0900 | [diff] [blame] | 2594 | else |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2595 | priv->rtllib->bSupportRemoteWakeUp = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2596 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2597 | pmem_start = pci_resource_start(pdev, 1); |
| 2598 | pmem_len = pci_resource_len(pdev, 1); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2599 | pmem_flags = pci_resource_flags(pdev, 1); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2600 | |
| 2601 | if (!(pmem_flags & IORESOURCE_MEM)) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 2602 | netdev_err(dev, "region #1 not a MMIO resource, aborting"); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2603 | goto err_rel_rtllib; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2604 | } |
| 2605 | |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 2606 | dev_info(&pdev->dev, "Memory mapped space start: 0x%08lx\n", |
| 2607 | pmem_start); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2608 | if (!request_mem_region(pmem_start, pmem_len, DRV_NAME)) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 2609 | netdev_err(dev, "request_mem_region failed!"); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2610 | goto err_rel_rtllib; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2611 | } |
| 2612 | |
| 2613 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2614 | ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len); |
| 2615 | if (ioaddr == (unsigned long)NULL) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 2616 | netdev_err(dev, "ioremap failed!"); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2617 | goto err_rel_mem; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2618 | } |
| 2619 | |
| 2620 | dev->mem_start = ioaddr; |
| 2621 | dev->mem_end = ioaddr + pci_resource_len(pdev, 0); |
| 2622 | |
Mike McCormack | 1ec3e2f | 2011-07-11 08:56:20 +0900 | [diff] [blame] | 2623 | pci_read_config_byte(pdev, 0x08, &revision_id); |
| 2624 | /* If the revisionid is 0x10, the device uses rtl8192se. */ |
| 2625 | if (pdev->device == 0x8192 && revision_id == 0x10) |
Mateusz Kulikowski | 948fa94 | 2015-07-28 23:31:47 +0200 | [diff] [blame] | 2626 | goto err_unmap; |
Mike McCormack | 1ec3e2f | 2011-07-11 08:56:20 +0900 | [diff] [blame] | 2627 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2628 | priv->ops = ops; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2629 | |
Mateusz Kulikowski | e250592 | 2015-07-19 19:28:40 +0200 | [diff] [blame] | 2630 | if (rtl92e_check_adapter(pdev, dev) == false) |
Mateusz Kulikowski | 948fa94 | 2015-07-28 23:31:47 +0200 | [diff] [blame] | 2631 | goto err_unmap; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2632 | |
| 2633 | dev->irq = pdev->irq; |
| 2634 | priv->irq = 0; |
| 2635 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2636 | dev->netdev_ops = &rtl8192_netdev_ops; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2637 | |
Joel Pelaez Jorge | 5169af2 | 2014-04-19 22:32:32 -0500 | [diff] [blame] | 2638 | dev->wireless_handlers = &r8192_wx_handlers_def; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2639 | dev->ethtool_ops = &rtl819x_ethtool_ops; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2640 | |
| 2641 | dev->type = ARPHRD_ETHER; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2642 | dev->watchdog_timeo = HZ * 3; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2643 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2644 | if (dev_alloc_name(dev, ifname) < 0) { |
Mateusz Kulikowski | 0822339 | 2015-03-17 00:00:48 +0100 | [diff] [blame] | 2645 | RT_TRACE(COMP_INIT, |
| 2646 | "Oops: devname already taken! Trying wlan%%d...\n"); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2647 | dev_alloc_name(dev, ifname); |
| 2648 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2649 | |
| 2650 | RT_TRACE(COMP_INIT, "Driver probe completed1\n"); |
Mateusz Kulikowski | 6bd5e8e | 2015-09-20 10:09:22 +0200 | [diff] [blame] | 2651 | if (_rtl92e_init(dev) != 0) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 2652 | netdev_warn(dev, "Initialization failed"); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2653 | goto err_free_irq; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2654 | } |
| 2655 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2656 | netif_carrier_off(dev); |
| 2657 | netif_stop_queue(dev); |
| 2658 | |
Kumar Amit Mehta | 4087641 | 2012-11-15 22:52:13 +0530 | [diff] [blame] | 2659 | if (register_netdev(dev)) |
| 2660 | goto err_free_irq; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2661 | RT_TRACE(COMP_INIT, "dev name: %s\n", dev->name); |
Sean MacLennan | 80c0d83 | 2011-11-28 20:17:10 -0500 | [diff] [blame] | 2662 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2663 | if (priv->polling_timer_on == 0) |
Mateusz Kulikowski | a643d92 | 2015-07-19 19:28:05 +0200 | [diff] [blame] | 2664 | rtl92e_check_rfctrl_gpio_timer((unsigned long)dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2665 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2666 | RT_TRACE(COMP_INIT, "Driver probe completed\n"); |
| 2667 | return 0; |
| 2668 | |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2669 | err_free_irq: |
| 2670 | free_irq(dev->irq, dev); |
| 2671 | priv->irq = 0; |
Mateusz Kulikowski | 948fa94 | 2015-07-28 23:31:47 +0200 | [diff] [blame] | 2672 | err_unmap: |
| 2673 | iounmap((void __iomem *)ioaddr); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2674 | err_rel_mem: |
| 2675 | release_mem_region(pmem_start, pmem_len); |
| 2676 | err_rel_rtllib: |
| 2677 | free_rtllib(dev); |
Larry Finger | 35f8673 | 2011-09-01 12:23:14 -0500 | [diff] [blame] | 2678 | err_pci_disable: |
| 2679 | pci_disable_device(pdev); |
| 2680 | return err; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2681 | } |
| 2682 | |
Mateusz Kulikowski | 4a85182 | 2015-09-20 10:12:55 +0200 | [diff] [blame] | 2683 | static void _rtl92e_pci_disconnect(struct pci_dev *pdev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2684 | { |
| 2685 | struct net_device *dev = pci_get_drvdata(pdev); |
Mateusz Kulikowski | dc986e3 | 2015-03-17 00:00:49 +0100 | [diff] [blame] | 2686 | struct r8192_priv *priv; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2687 | u32 i; |
| 2688 | |
| 2689 | if (dev) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2690 | unregister_netdev(dev); |
| 2691 | |
| 2692 | priv = rtllib_priv(dev); |
| 2693 | |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2694 | del_timer_sync(&priv->gpio_polling_timer); |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 2695 | cancel_delayed_work_sync(&priv->gpio_change_rf_wq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2696 | priv->polling_timer_on = 0; |
Mateusz Kulikowski | 33bec9b | 2015-09-20 10:12:51 +0200 | [diff] [blame] | 2697 | _rtl92e_down(dev, true); |
Mateusz Kulikowski | fd9e317 | 2015-07-19 19:28:29 +0200 | [diff] [blame] | 2698 | rtl92e_dm_deinit(dev); |
Mike McCormack | cb76215 | 2011-07-11 08:56:20 +0900 | [diff] [blame] | 2699 | if (priv->pFirmware) { |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2700 | vfree(priv->pFirmware); |
| 2701 | priv->pFirmware = NULL; |
| 2702 | } |
Mateusz Kulikowski | 694f9d3 | 2015-09-20 10:13:02 +0200 | [diff] [blame] | 2703 | _rtl92e_free_rx_ring(dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2704 | for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) |
Mateusz Kulikowski | ebc36ec | 2015-09-20 10:13:03 +0200 | [diff] [blame] | 2705 | _rtl92e_free_tx_ring(dev, i); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2706 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2707 | if (priv->irq) { |
Mateusz Kulikowski | d69d205 | 2015-03-17 00:00:52 +0100 | [diff] [blame] | 2708 | dev_info(&pdev->dev, "Freeing irq %d\n", dev->irq); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2709 | free_irq(dev->irq, dev); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2710 | priv->irq = 0; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2711 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2712 | free_rtllib(dev); |
| 2713 | |
Larry Finger | 6689817 | 2011-07-15 12:32:41 -0500 | [diff] [blame] | 2714 | if (dev->mem_start != 0) { |
Larry Finger | 49aab5f | 2011-08-25 14:07:05 -0500 | [diff] [blame] | 2715 | iounmap((void __iomem *)dev->mem_start); |
Larry Finger | 6689817 | 2011-07-15 12:32:41 -0500 | [diff] [blame] | 2716 | release_mem_region(pci_resource_start(pdev, 1), |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2717 | pci_resource_len(pdev, 1)); |
Larry Finger | 6689817 | 2011-07-15 12:32:41 -0500 | [diff] [blame] | 2718 | } |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2719 | } else { |
| 2720 | priv = rtllib_priv(dev); |
| 2721 | } |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2722 | |
| 2723 | pci_disable_device(pdev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2724 | RT_TRACE(COMP_DOWN, "wlan driver removed\n"); |
| 2725 | } |
| 2726 | |
Mateusz Kulikowski | 502bd1d | 2015-07-19 19:28:08 +0200 | [diff] [blame] | 2727 | bool rtl92e_enable_nic(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2728 | { |
| 2729 | bool init_status = true; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2730 | struct r8192_priv *priv = rtllib_priv(dev); |
| 2731 | struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) |
| 2732 | (&(priv->rtllib->PowerSaveControl)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2733 | |
Vaishali Thakkar | 5dc4296 | 2015-03-03 13:08:24 +0530 | [diff] [blame] | 2734 | if (!priv->up) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 2735 | netdev_warn(dev, "%s(): Driver is already down!\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2736 | priv->bdisable_nic = false; |
Dominique van den Broeck | 7626e3d | 2014-04-27 19:11:15 +0200 | [diff] [blame] | 2737 | return false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2738 | } |
| 2739 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2740 | RT_TRACE(COMP_PS, "===========>%s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2741 | priv->bfirst_init = true; |
| 2742 | init_status = priv->ops->initialize_adapter(dev); |
Valentina Manea | 4bb0142 | 2013-10-25 11:28:10 +0300 | [diff] [blame] | 2743 | if (!init_status) { |
Mateusz Kulikowski | 3b4140a | 2015-05-31 20:19:50 +0200 | [diff] [blame] | 2744 | netdev_warn(dev, "%s(): Initialization failed!\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2745 | priv->bdisable_nic = false; |
Dominique van den Broeck | 7626e3d | 2014-04-27 19:11:15 +0200 | [diff] [blame] | 2746 | return false; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2747 | } |
| 2748 | RT_TRACE(COMP_INIT, "start adapter finished\n"); |
| 2749 | RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); |
| 2750 | priv->bfirst_init = false; |
| 2751 | |
Mateusz Kulikowski | b74299c | 2015-07-19 19:28:15 +0200 | [diff] [blame] | 2752 | rtl92e_irq_enable(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2753 | priv->bdisable_nic = false; |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2754 | RT_TRACE(COMP_PS, "<===========%s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2755 | return init_status; |
| 2756 | } |
Mateusz Kulikowski | af002dc | 2015-07-19 19:28:07 +0200 | [diff] [blame] | 2757 | bool rtl92e_disable_nic(struct net_device *dev) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2758 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2759 | struct r8192_priv *priv = rtllib_priv(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2760 | u8 tmp_state = 0; |
Matthew Casey | 3a6b70c | 2014-08-22 06:27:52 -0400 | [diff] [blame] | 2761 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2762 | RT_TRACE(COMP_PS, "=========>%s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2763 | priv->bdisable_nic = true; |
| 2764 | tmp_state = priv->rtllib->state; |
| 2765 | rtllib_softmac_stop_protocol(priv->rtllib, 0, false); |
| 2766 | priv->rtllib->state = tmp_state; |
Mateusz Kulikowski | 4dba03a | 2015-09-20 10:14:12 +0200 | [diff] [blame] | 2767 | _rtl92e_cancel_deferred_work(priv); |
Mateusz Kulikowski | b7b50d6 | 2015-07-19 19:28:14 +0200 | [diff] [blame] | 2768 | rtl92e_irq_disable(dev); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2769 | |
| 2770 | priv->ops->stop_adapter(dev, false); |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2771 | RT_TRACE(COMP_PS, "<=========%s()\n", __func__); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2772 | |
Cristina Opriceana | e623d0f | 2015-03-12 04:22:38 +0200 | [diff] [blame] | 2773 | return true; |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2774 | } |
| 2775 | |
Ksenija Stanojevic | c1ccddd | 2015-10-19 18:49:12 +0200 | [diff] [blame] | 2776 | module_pci_driver(rtl8192_pci_driver); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2777 | |
Mateusz Kulikowski | a643d92 | 2015-07-19 19:28:05 +0200 | [diff] [blame] | 2778 | void rtl92e_check_rfctrl_gpio_timer(unsigned long data) |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2779 | { |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2780 | struct r8192_priv *priv = rtllib_priv((struct net_device *)data); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2781 | |
| 2782 | priv->polling_timer_on = 1; |
| 2783 | |
Amitoj Kaur Chawla | ecfdd3a | 2016-02-25 09:23:31 +0530 | [diff] [blame] | 2784 | schedule_delayed_work(&priv->gpio_change_rf_wq, 0); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2785 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2786 | mod_timer(&priv->gpio_polling_timer, jiffies + |
Vaishali Thakkar | 8b9733c | 2015-03-11 13:51:36 +0530 | [diff] [blame] | 2787 | msecs_to_jiffies(RTLLIB_WATCH_DOG_TIME)); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2788 | } |
| 2789 | |
| 2790 | /*************************************************************************** |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2791 | ------------------- module init / exit stubs ---------------- |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2792 | ****************************************************************************/ |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2793 | MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); |
| 2794 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2795 | MODULE_VERSION(DRV_VERSION); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2796 | MODULE_LICENSE("GPL"); |
Tim Gardner | 7f34f41 | 2012-07-25 13:08:47 -0600 | [diff] [blame] | 2797 | MODULE_FIRMWARE(RTL8192E_BOOT_IMG_FW); |
| 2798 | MODULE_FIRMWARE(RTL8192E_MAIN_IMG_FW); |
| 2799 | MODULE_FIRMWARE(RTL8192E_DATA_IMG_FW); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2800 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2801 | module_param(ifname, charp, S_IRUGO|S_IWUSR); |
| 2802 | module_param(hwwep, int, S_IRUGO|S_IWUSR); |
| 2803 | module_param(channels, int, S_IRUGO|S_IWUSR); |
Larry Finger | 94a7994 | 2011-08-23 19:00:42 -0500 | [diff] [blame] | 2804 | |
Larry Finger | 1344ee2 | 2011-08-25 11:48:20 -0500 | [diff] [blame] | 2805 | MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); |
| 2806 | MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support(default use hw. set 0 to use software security)"); |
| 2807 | MODULE_PARM_DESC(channels, " Channel bitmask for specific locales. NYI"); |