Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 1 | /* |
| 2 | ************************************************************************* |
| 3 | * Ralink Tech Inc. |
| 4 | * 5F., No.36, Taiyuan St., Jhubei City, |
| 5 | * Hsinchu County 302, |
| 6 | * Taiwan, R.O.C. |
| 7 | * |
| 8 | * (c) Copyright 2002-2007, Ralink Technology, Inc. |
| 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify * |
| 11 | * it under the terms of the GNU General Public License as published by * |
| 12 | * the Free Software Foundation; either version 2 of the License, or * |
| 13 | * (at your option) any later version. * |
| 14 | * * |
| 15 | * This program is distributed in the hope that it will be useful, * |
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
| 18 | * GNU General Public License for more details. * |
| 19 | * * |
| 20 | * You should have received a copy of the GNU General Public License * |
| 21 | * along with this program; if not, write to the * |
| 22 | * Free Software Foundation, Inc., * |
| 23 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
| 24 | * * |
| 25 | *************************************************************************/ |
| 26 | |
| 27 | #include "rt_config.h" |
| 28 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 29 | /* Following information will be show when you run 'modinfo' */ |
Justin P. Mattock | 6ccb5d7 | 2010-11-08 13:41:46 -0800 | [diff] [blame^] | 30 | /* If you have a solution for the bug in current version of driver, please e-mail me. */ |
| 31 | /* Otherwise post to the forum at ralinktech's web site(www.ralinktech.com) and let all users help you. */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 32 | MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>"); |
| 33 | MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver"); |
| 34 | MODULE_LICENSE("GPL"); |
| 35 | #ifdef MODULE_VERSION |
| 36 | MODULE_VERSION(STA_DRIVER_VERSION); |
| 37 | #endif |
| 38 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 39 | /* module table */ |
| 40 | struct usb_device_id rtusb_usb_id[] = { |
| 41 | #ifdef RT2870 |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 42 | {USB_DEVICE(0x148F, 0x2770)}, /* Ralink */ |
| 43 | {USB_DEVICE(0x148F, 0x2870)}, /* Ralink */ |
| 44 | {USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */ |
| 45 | {USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */ |
| 46 | {USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 47 | {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom 2770 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 48 | {USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */ |
| 49 | {USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */ |
| 50 | {USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */ |
| 51 | {USB_DEVICE(0x0789, 0x0164)}, /* Logitec 2870 */ |
| 52 | {USB_DEVICE(0x177f, 0x0302)}, /* lsusb */ |
| 53 | {USB_DEVICE(0x0B05, 0x1731)}, /* Asus */ |
| 54 | {USB_DEVICE(0x0B05, 0x1732)}, /* Asus */ |
| 55 | {USB_DEVICE(0x0B05, 0x1742)}, /* Asus */ |
| 56 | {USB_DEVICE(0x0DF6, 0x0017)}, /* Sitecom */ |
| 57 | {USB_DEVICE(0x0DF6, 0x002B)}, /* Sitecom */ |
| 58 | {USB_DEVICE(0x0DF6, 0x002C)}, /* Sitecom */ |
| 59 | {USB_DEVICE(0x0DF6, 0x002D)}, /* Sitecom */ |
| 60 | {USB_DEVICE(0x14B2, 0x3C06)}, /* Conceptronic */ |
| 61 | {USB_DEVICE(0x14B2, 0x3C28)}, /* Conceptronic */ |
| 62 | {USB_DEVICE(0x2019, 0xED06)}, /* Planex Communications, Inc. */ |
| 63 | {USB_DEVICE(0x07D1, 0x3C09)}, /* D-Link */ |
| 64 | {USB_DEVICE(0x07D1, 0x3C11)}, /* D-Link */ |
| 65 | {USB_DEVICE(0x14B2, 0x3C07)}, /* AL */ |
| 66 | {USB_DEVICE(0x050D, 0x8053)}, /* Belkin */ |
Chris Largret | 12840c6 | 2010-03-03 05:24:26 -0600 | [diff] [blame] | 67 | {USB_DEVICE(0x050D, 0x825B)}, /* Belkin */ |
Larry Finger | 5d92fe3 | 2010-07-25 16:14:53 -0500 | [diff] [blame] | 68 | {USB_DEVICE(0x050D, 0x935B)}, /* Belkin F6D4050 v2 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 69 | {USB_DEVICE(0x14B2, 0x3C23)}, /* Airlink */ |
| 70 | {USB_DEVICE(0x14B2, 0x3C27)}, /* Airlink */ |
| 71 | {USB_DEVICE(0x07AA, 0x002F)}, /* Corega */ |
| 72 | {USB_DEVICE(0x07AA, 0x003C)}, /* Corega */ |
| 73 | {USB_DEVICE(0x07AA, 0x003F)}, /* Corega */ |
| 74 | {USB_DEVICE(0x1044, 0x800B)}, /* Gigabyte */ |
| 75 | {USB_DEVICE(0x15A9, 0x0006)}, /* Sparklan */ |
| 76 | {USB_DEVICE(0x083A, 0xB522)}, /* SMC */ |
| 77 | {USB_DEVICE(0x083A, 0xA618)}, /* SMC */ |
| 78 | {USB_DEVICE(0x083A, 0x8522)}, /* Arcadyan */ |
| 79 | {USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */ |
| 80 | {USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */ |
| 81 | {USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */ |
Ozan Çağlayan | 9674e57 | 2010-06-21 14:00:56 +0300 | [diff] [blame] | 82 | {USB_DEVICE(0x0586, 0x341a)}, /* Zyxel NWD-270N */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 83 | {USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */ |
| 84 | {USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */ |
| 85 | {USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */ |
| 86 | {USB_DEVICE(0x0471, 0x200f)}, /* Philips */ |
| 87 | {USB_DEVICE(0x14B2, 0x3C25)}, /* Draytek */ |
| 88 | {USB_DEVICE(0x13D3, 0x3247)}, /* AzureWave */ |
| 89 | {USB_DEVICE(0x083A, 0x6618)}, /* Accton */ |
| 90 | {USB_DEVICE(0x15c5, 0x0008)}, /* Amit */ |
| 91 | {USB_DEVICE(0x0E66, 0x0001)}, /* Hawking */ |
| 92 | {USB_DEVICE(0x0E66, 0x0003)}, /* Hawking */ |
| 93 | {USB_DEVICE(0x129B, 0x1828)}, /* Siemens */ |
| 94 | {USB_DEVICE(0x157E, 0x300E)}, /* U-Media */ |
| 95 | {USB_DEVICE(0x050d, 0x805c)}, |
| 96 | {USB_DEVICE(0x050d, 0x815c)}, |
| 97 | {USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */ |
| 98 | {USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 99 | {USB_DEVICE(0x04E8, 0x2018)}, /* samsung linkstick2 */ |
| 100 | {USB_DEVICE(0x1690, 0x0740)}, /* Askey */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 101 | {USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */ |
| 102 | {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */ |
| 103 | {USB_DEVICE(0x7392, 0x7718)}, |
| 104 | {USB_DEVICE(0x7392, 0x7717)}, |
Nobuhiro KUSUNO | de37cd4 | 2010-05-06 05:23:28 +0900 | [diff] [blame] | 105 | {USB_DEVICE(0x0411, 0x016f)}, /* MelCo.,Inc. WLI-UC-G301N */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 106 | {USB_DEVICE(0x1737, 0x0070)}, /* Linksys WUSB100 */ |
| 107 | {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ |
| 108 | {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ |
| 109 | {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 110 | {USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */ |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 111 | #endif /* RT2870 // */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 112 | #ifdef RT3070 |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 113 | {USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */ |
| 114 | {USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */ |
| 115 | {USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */ |
| 116 | {USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 117 | {USB_DEVICE(0x0DB0, 0x871C)}, /* Ralink 3070 */ |
| 118 | {USB_DEVICE(0x0DB0, 0x822C)}, /* Ralink 3070 */ |
| 119 | {USB_DEVICE(0x0DB0, 0x871B)}, /* Ralink 3070 */ |
| 120 | {USB_DEVICE(0x0DB0, 0x822B)}, /* Ralink 3070 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 121 | {USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */ |
| 122 | {USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 123 | {USB_DEVICE(0x0DF6, 0x0048)}, /* Sitecom 3070 */ |
| 124 | {USB_DEVICE(0x0DF6, 0x0047)}, /* Sitecom 3071 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 125 | {USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */ |
| 126 | {USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */ |
| 127 | {USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 128 | {USB_DEVICE(0x083A, 0xA701)}, /* SMC 3070 */ |
| 129 | {USB_DEVICE(0x083A, 0xA702)}, /* SMC 3072 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 130 | {USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */ |
| 131 | {USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */ |
| 132 | {USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 133 | {USB_DEVICE(0x1740, 0x9707)}, /* EnGenius 3070 */ |
| 134 | {USB_DEVICE(0x1740, 0x9708)}, /* EnGenius 3071 */ |
| 135 | {USB_DEVICE(0x1740, 0x9709)}, /* EnGenius 3072 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 136 | {USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 137 | {USB_DEVICE(0x13D3, 0x3305)}, /* AzureWave 3070*/ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 138 | {USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */ |
| 139 | {USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */ |
| 140 | {USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */ |
| 141 | {USB_DEVICE(0x07B8, 0x3071)}, /* AboCom 3071 */ |
| 142 | {USB_DEVICE(0x07B8, 0x3072)}, /* Abocom 3072 */ |
| 143 | {USB_DEVICE(0x7392, 0x7711)}, /* Edimax 3070 */ |
| 144 | {USB_DEVICE(0x1A32, 0x0304)}, /* Quanta 3070 */ |
| 145 | {USB_DEVICE(0x1EDA, 0x2310)}, /* AirTies 3070 */ |
| 146 | {USB_DEVICE(0x07D1, 0x3C0A)}, /* D-Link 3072 */ |
| 147 | {USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */ |
| 148 | {USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */ |
| 149 | {USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 150 | {USB_DEVICE(0x07D1, 0x3C16)}, /* D-Link 3070 */ |
| 151 | {USB_DEVICE(0x07D1, 0x3C17)}, /* D-Link 8070 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 152 | {USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */ |
| 153 | {USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */ |
| 154 | {USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */ |
| 155 | {USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */ |
| 156 | {USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 157 | {USB_DEVICE(0x04BB, 0x0947)}, /* I-O DATA 3070 */ |
| 158 | {USB_DEVICE(0x04BB, 0x0948)}, /* I-O DATA 3072 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 159 | {USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */ |
Ben Hutchings | 9e693e4 | 2010-08-29 02:13:11 +0100 | [diff] [blame] | 160 | {USB_DEVICE(0x20B8, 0x8888)}, /* PARA INDUSTRIAL 3070 */ |
| 161 | {USB_DEVICE(0x0B05, 0x1784)}, /* Asus 3072 */ |
| 162 | {USB_DEVICE(0x203D, 0x14A9)}, /* Encore 3070*/ |
| 163 | {USB_DEVICE(0x0DB0, 0x899A)}, /* MSI 3070*/ |
| 164 | {USB_DEVICE(0x0DB0, 0x3870)}, /* MSI 3070*/ |
| 165 | {USB_DEVICE(0x0DB0, 0x870A)}, /* MSI 3070*/ |
| 166 | {USB_DEVICE(0x0DB0, 0x6899)}, /* MSI 3070 */ |
| 167 | {USB_DEVICE(0x0DB0, 0x3822)}, /* MSI 3070 */ |
| 168 | {USB_DEVICE(0x0DB0, 0x3871)}, /* MSI 3070 */ |
| 169 | {USB_DEVICE(0x0DB0, 0x871A)}, /* MSI 3070 */ |
| 170 | {USB_DEVICE(0x0DB0, 0x822A)}, /* MSI 3070 */ |
| 171 | {USB_DEVICE(0x0DB0, 0x3821)}, /* Ralink 3070 */ |
| 172 | {USB_DEVICE(0x0DB0, 0x821A)}, /* Ralink 3070 */ |
| 173 | {USB_DEVICE(0x083A, 0xA703)}, /* IO-MAGIC */ |
| 174 | {USB_DEVICE(0x13D3, 0x3307)}, /* Azurewave */ |
| 175 | {USB_DEVICE(0x13D3, 0x3321)}, /* Azurewave */ |
| 176 | {USB_DEVICE(0x07FA, 0x7712)}, /* Edimax */ |
| 177 | {USB_DEVICE(0x0789, 0x0166)}, /* Edimax */ |
| 178 | {USB_DEVICE(0x148F, 0x2070)}, /* Edimax */ |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 179 | #endif /* RT3070 // */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 180 | {USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */ |
| 181 | {USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */ |
| 182 | {USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */ |
| 183 | {USB_DEVICE(0x2019, 0xED14)}, /* Planex Communications, Inc. */ |
| 184 | {} /* Terminating entry */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 185 | }; |
| 186 | |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 187 | int const rtusb_usb_id_len = |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 188 | sizeof(rtusb_usb_id) / sizeof(struct usb_device_id); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 189 | |
| 190 | MODULE_DEVICE_TABLE(usb, rtusb_usb_id); |
| 191 | |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 192 | static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 193 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 194 | static int __devinit rt2870_probe(IN struct usb_interface *intf, |
| 195 | IN struct usb_device *usb_dev, |
| 196 | IN const struct usb_device_id *dev_id, |
Trey Evans | a3327f0 | 2010-04-19 16:15:37 -0400 | [diff] [blame] | 197 | struct rt_rtmp_adapter **ppAd); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 198 | |
| 199 | #ifndef PF_NOFREEZE |
| 200 | #define PF_NOFREEZE 0 |
| 201 | #endif |
| 202 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 203 | extern int rt28xx_close(IN struct net_device *net_dev); |
| 204 | extern int rt28xx_open(struct net_device *net_dev); |
| 205 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 206 | static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, |
| 207 | IN struct usb_interface *intf, |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 208 | struct rt_rtmp_adapter *pAd); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 209 | |
| 210 | /* |
| 211 | ======================================================================== |
| 212 | Routine Description: |
| 213 | Check the chipset vendor/product ID. |
| 214 | |
| 215 | Arguments: |
| 216 | _dev_p Point to the PCI or USB device |
| 217 | |
| 218 | Return Value: |
| 219 | TRUE Check ok |
| 220 | FALSE Check fail |
| 221 | |
| 222 | Note: |
| 223 | ======================================================================== |
| 224 | */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 225 | BOOLEAN RT28XXChipsetCheck(IN void *_dev_p) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 226 | { |
| 227 | struct usb_interface *intf = (struct usb_interface *)_dev_p; |
| 228 | struct usb_device *dev_p = interface_to_usbdev(intf); |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 229 | u32 i; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 230 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 231 | for (i = 0; i < rtusb_usb_id_len; i++) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 232 | if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor && |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 233 | dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 234 | printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n", |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 235 | dev_p->descriptor.idVendor, |
| 236 | dev_p->descriptor.idProduct); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 237 | break; |
| 238 | } |
| 239 | } |
| 240 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 241 | if (i == rtusb_usb_id_len) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 242 | printk("rt2870: Error! Device Descriptor not matching!\n"); |
| 243 | return FALSE; |
| 244 | } |
| 245 | |
| 246 | return TRUE; |
| 247 | } |
| 248 | |
| 249 | /**************************************************************************/ |
| 250 | /**************************************************************************/ |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 251 | /*tested for kernel 2.6series */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 252 | /**************************************************************************/ |
| 253 | /**************************************************************************/ |
| 254 | |
| 255 | #ifdef CONFIG_PM |
| 256 | static int rt2870_suspend(struct usb_interface *intf, pm_message_t state); |
| 257 | static int rt2870_resume(struct usb_interface *intf); |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 258 | #endif /* CONFIG_PM // */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 259 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 260 | static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, |
| 261 | IN struct usb_interface *intf, |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 262 | struct rt_rtmp_adapter *pAd) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 263 | { |
| 264 | struct usb_host_interface *iface_desc; |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 265 | unsigned long BulkOutIdx; |
| 266 | u32 i; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 267 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 268 | /* get the active interface descriptor */ |
| 269 | iface_desc = intf->cur_altsetting; |
| 270 | |
| 271 | /* get # of enpoints */ |
| 272 | pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 273 | DBGPRINT(RT_DEBUG_TRACE, |
| 274 | ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints)); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 275 | |
| 276 | /* Configure Pipes */ |
| 277 | BulkOutIdx = 0; |
| 278 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 279 | for (i = 0; i < pAd->NumberOfPipes; i++) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 280 | if ((iface_desc->endpoint[i].desc.bmAttributes == |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 281 | USB_ENDPOINT_XFER_BULK) && |
| 282 | ((iface_desc->endpoint[i].desc.bEndpointAddress & |
| 283 | USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) { |
| 284 | pAd->BulkInEpAddr = |
| 285 | iface_desc->endpoint[i].desc.bEndpointAddress; |
| 286 | pAd->BulkInMaxPacketSize = |
| 287 | le2cpu16(iface_desc->endpoint[i].desc. |
| 288 | wMaxPacketSize); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 289 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 290 | DBGPRINT_RAW(RT_DEBUG_TRACE, |
| 291 | ("BULK IN MaxPacketSize = %d\n", |
| 292 | pAd->BulkInMaxPacketSize)); |
| 293 | DBGPRINT_RAW(RT_DEBUG_TRACE, |
| 294 | ("EP address = 0x%2x\n", |
| 295 | iface_desc->endpoint[i].desc. |
| 296 | bEndpointAddress)); |
| 297 | } else |
| 298 | if ((iface_desc->endpoint[i].desc.bmAttributes == |
| 299 | USB_ENDPOINT_XFER_BULK) |
| 300 | && |
| 301 | ((iface_desc->endpoint[i].desc. |
| 302 | bEndpointAddress & USB_ENDPOINT_DIR_MASK) == |
| 303 | USB_DIR_OUT)) { |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 304 | /* there are 6 bulk out EP. EP6 highest priority. */ |
| 305 | /* EP1-4 is EDCA. EP5 is HCCA. */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 306 | pAd->BulkOutEpAddr[BulkOutIdx++] = |
| 307 | iface_desc->endpoint[i].desc.bEndpointAddress; |
| 308 | pAd->BulkOutMaxPacketSize = |
| 309 | le2cpu16(iface_desc->endpoint[i].desc. |
| 310 | wMaxPacketSize); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 311 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 312 | DBGPRINT_RAW(RT_DEBUG_TRACE, |
| 313 | ("BULK OUT MaxPacketSize = %d\n", |
| 314 | pAd->BulkOutMaxPacketSize)); |
| 315 | DBGPRINT_RAW(RT_DEBUG_TRACE, |
| 316 | ("EP address = 0x%2x \n", |
| 317 | iface_desc->endpoint[i].desc. |
| 318 | bEndpointAddress)); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 319 | } |
| 320 | } |
| 321 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 322 | if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) { |
| 323 | printk |
| 324 | ("%s: Could not find both bulk-in and bulk-out endpoints\n", |
| 325 | __FUNCTION__); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 326 | return FALSE; |
| 327 | } |
| 328 | |
| 329 | pAd->config = &dev->config->desc; |
| 330 | usb_set_intfdata(intf, pAd); |
| 331 | |
| 332 | return TRUE; |
| 333 | |
| 334 | } |
| 335 | |
Simon Horman | c33c206 | 2009-12-23 19:54:50 +1100 | [diff] [blame] | 336 | static int __devinit rtusb_probe(struct usb_interface *intf, |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 337 | const struct usb_device_id *id) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 338 | { |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 339 | struct rt_rtmp_adapter *pAd; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 340 | struct usb_device *dev; |
| 341 | int rv; |
| 342 | |
| 343 | dev = interface_to_usbdev(intf); |
| 344 | dev = usb_get_dev(dev); |
| 345 | |
| 346 | rv = rt2870_probe(intf, dev, id, &pAd); |
| 347 | if (rv != 0) |
| 348 | usb_put_dev(dev); |
| 349 | |
| 350 | return rv; |
| 351 | } |
| 352 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 353 | static void rtusb_disconnect(struct usb_interface *intf) |
| 354 | { |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 355 | struct usb_device *dev = interface_to_usbdev(intf); |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 356 | struct rt_rtmp_adapter *pAd; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 357 | |
| 358 | pAd = usb_get_intfdata(intf); |
| 359 | usb_set_intfdata(intf, NULL); |
| 360 | |
| 361 | rt2870_disconnect(dev, pAd); |
| 362 | } |
| 363 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 364 | struct usb_driver rtusb_driver = { |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 365 | .name = "rt2870", |
| 366 | .probe = rtusb_probe, |
| 367 | .disconnect = rtusb_disconnect, |
| 368 | .id_table = rtusb_usb_id, |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 369 | |
| 370 | #ifdef CONFIG_PM |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 371 | suspend:rt2870_suspend, |
| 372 | resume:rt2870_resume, |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 373 | #endif |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 374 | }; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 375 | |
| 376 | #ifdef CONFIG_PM |
| 377 | |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 378 | void RT2870RejectPendingPackets(struct rt_rtmp_adapter *pAd) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 379 | { |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 380 | /* clear PS packets */ |
| 381 | /* clear TxSw packets */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 382 | } |
| 383 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 384 | static int rt2870_suspend(struct usb_interface *intf, pm_message_t state) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 385 | { |
| 386 | struct net_device *net_dev; |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 387 | struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 388 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 389 | DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n")); |
| 390 | net_dev = pAd->net_dev; |
| 391 | netif_device_detach(net_dev); |
| 392 | |
| 393 | pAd->PM_FlgSuspend = 1; |
| 394 | if (netif_running(net_dev)) { |
| 395 | RTUSBCancelPendingBulkInIRP(pAd); |
| 396 | RTUSBCancelPendingBulkOutIRP(pAd); |
| 397 | } |
| 398 | DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n")); |
| 399 | return 0; |
| 400 | } |
| 401 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 402 | static int rt2870_resume(struct usb_interface *intf) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 403 | { |
| 404 | struct net_device *net_dev; |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 405 | struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 406 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 407 | DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n")); |
| 408 | |
| 409 | pAd->PM_FlgSuspend = 0; |
| 410 | net_dev = pAd->net_dev; |
| 411 | netif_device_attach(net_dev); |
| 412 | netif_start_queue(net_dev); |
| 413 | netif_carrier_on(net_dev); |
| 414 | netif_wake_queue(net_dev); |
| 415 | |
| 416 | DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n")); |
| 417 | return 0; |
| 418 | } |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 419 | #endif /* CONFIG_PM // */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 420 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 421 | /* Init driver module */ |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 422 | int __init rtusb_init(void) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 423 | { |
| 424 | printk("rtusb init --->\n"); |
| 425 | return usb_register(&rtusb_driver); |
| 426 | } |
| 427 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 428 | /* Deinit driver module */ |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 429 | void __exit rtusb_exit(void) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 430 | { |
| 431 | usb_deregister(&rtusb_driver); |
| 432 | printk("<--- rtusb exit\n"); |
| 433 | } |
| 434 | |
| 435 | module_init(rtusb_init); |
| 436 | module_exit(rtusb_exit); |
| 437 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 438 | /*--------------------------------------------------------------------- */ |
| 439 | /* function declarations */ |
| 440 | /*--------------------------------------------------------------------- */ |
| 441 | |
| 442 | /* |
| 443 | ======================================================================== |
| 444 | Routine Description: |
| 445 | MLME kernel thread. |
| 446 | |
| 447 | Arguments: |
| 448 | *Context the pAd, driver control block pointer |
| 449 | |
| 450 | Return Value: |
| 451 | 0 close the thread |
| 452 | |
| 453 | Note: |
| 454 | ======================================================================== |
| 455 | */ |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 456 | int MlmeThread(IN void *Context) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 457 | { |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 458 | struct rt_rtmp_adapter *pAd; |
| 459 | struct rt_rtmp_os_task *pTask; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 460 | int status; |
| 461 | status = 0; |
| 462 | |
Kulikov Vasiliy | ef7d8ba | 2010-06-29 14:16:12 +0400 | [diff] [blame] | 463 | pTask = Context; |
| 464 | pAd = pTask->priv; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 465 | |
| 466 | RtmpOSTaskCustomize(pTask); |
| 467 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 468 | while (!pTask->task_killed) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 469 | #ifdef KTHREAD_SUPPORT |
| 470 | RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); |
| 471 | #else |
| 472 | RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); |
| 473 | |
| 474 | /* unlock the device pointers */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 475 | if (status != 0) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 476 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); |
| 477 | break; |
| 478 | } |
| 479 | #endif |
| 480 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 481 | /* lock the device pointers , need to check if required */ |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 482 | /*down(&(pAd->usbdev_semaphore)); */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 483 | |
| 484 | if (!pAd->PM_FlgSuspend) |
| 485 | MlmeHandler(pAd); |
| 486 | } |
| 487 | |
| 488 | /* notify the exit routine that we're actually exiting now |
| 489 | * |
| 490 | * complete()/wait_for_completion() is similar to up()/down(), |
| 491 | * except that complete() is safe in the case where the structure |
| 492 | * is getting deleted in a parallel mode of execution (i.e. just |
| 493 | * after the down() -- that's necessary for the thread-shutdown |
| 494 | * case. |
| 495 | * |
| 496 | * complete_and_exit() goes even further than this -- it is safe in |
| 497 | * the case that the thread of the caller is going away (not just |
| 498 | * the structure) -- this is necessary for the module-remove case. |
| 499 | * This is important in preemption kernels, which transfer the flow |
| 500 | * of execution immediately upon a complete(). |
| 501 | */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 502 | DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __FUNCTION__)); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 503 | #ifndef KTHREAD_SUPPORT |
| 504 | pTask->taskPID = THREAD_PID_INIT_VALUE; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 505 | complete_and_exit(&pTask->taskComplete, 0); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 506 | #endif |
| 507 | return 0; |
| 508 | |
| 509 | } |
| 510 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 511 | /* |
| 512 | ======================================================================== |
| 513 | Routine Description: |
| 514 | USB command kernel thread. |
| 515 | |
| 516 | Arguments: |
| 517 | *Context the pAd, driver control block pointer |
| 518 | |
| 519 | Return Value: |
| 520 | 0 close the thread |
| 521 | |
| 522 | Note: |
| 523 | ======================================================================== |
| 524 | */ |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 525 | int RTUSBCmdThread(IN void *Context) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 526 | { |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 527 | struct rt_rtmp_adapter *pAd; |
| 528 | struct rt_rtmp_os_task *pTask; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 529 | int status; |
| 530 | status = 0; |
| 531 | |
Kulikov Vasiliy | ef7d8ba | 2010-06-29 14:16:12 +0400 | [diff] [blame] | 532 | pTask = Context; |
| 533 | pAd = pTask->priv; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 534 | |
| 535 | RtmpOSTaskCustomize(pTask); |
| 536 | |
| 537 | NdisAcquireSpinLock(&pAd->CmdQLock); |
| 538 | pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING; |
| 539 | NdisReleaseSpinLock(&pAd->CmdQLock); |
| 540 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 541 | while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 542 | #ifdef KTHREAD_SUPPORT |
| 543 | RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); |
| 544 | #else |
| 545 | /* lock the device pointers */ |
| 546 | RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); |
| 547 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 548 | if (status != 0) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 549 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); |
| 550 | break; |
| 551 | } |
| 552 | #endif |
| 553 | |
| 554 | if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED) |
| 555 | break; |
| 556 | |
| 557 | if (!pAd->PM_FlgSuspend) |
| 558 | CMDHandler(pAd); |
| 559 | } |
| 560 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 561 | if (pAd && !pAd->PM_FlgSuspend) { /* Clear the CmdQElements. */ |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 562 | struct rt_cmdqelmt *pCmdQElmt = NULL; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 563 | |
| 564 | NdisAcquireSpinLock(&pAd->CmdQLock); |
| 565 | pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 566 | while (pAd->CmdQ.size) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 567 | RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 568 | if (pCmdQElmt) { |
| 569 | if (pCmdQElmt->CmdFromNdis == TRUE) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 570 | if (pCmdQElmt->buffer != NULL) |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 571 | os_free_mem(pAd, |
| 572 | pCmdQElmt->buffer); |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 573 | os_free_mem(pAd, (u8 *)pCmdQElmt); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 574 | } else { |
| 575 | if ((pCmdQElmt->buffer != NULL) |
| 576 | && (pCmdQElmt->bufferlength != 0)) |
| 577 | os_free_mem(pAd, |
| 578 | pCmdQElmt->buffer); |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 579 | os_free_mem(pAd, (u8 *)pCmdQElmt); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 580 | } |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | NdisReleaseSpinLock(&pAd->CmdQLock); |
| 585 | } |
| 586 | /* notify the exit routine that we're actually exiting now |
| 587 | * |
| 588 | * complete()/wait_for_completion() is similar to up()/down(), |
| 589 | * except that complete() is safe in the case where the structure |
| 590 | * is getting deleted in a parallel mode of execution (i.e. just |
| 591 | * after the down() -- that's necessary for the thread-shutdown |
| 592 | * case. |
| 593 | * |
| 594 | * complete_and_exit() goes even further than this -- it is safe in |
| 595 | * the case that the thread of the caller is going away (not just |
| 596 | * the structure) -- this is necessary for the module-remove case. |
| 597 | * This is important in preemption kernels, which transfer the flow |
| 598 | * of execution immediately upon a complete(). |
| 599 | */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 600 | DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n")); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 601 | |
| 602 | #ifndef KTHREAD_SUPPORT |
| 603 | pTask->taskPID = THREAD_PID_INIT_VALUE; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 604 | complete_and_exit(&pTask->taskComplete, 0); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 605 | #endif |
| 606 | return 0; |
| 607 | |
| 608 | } |
| 609 | |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 610 | void RTUSBWatchDog(struct rt_rtmp_adapter *pAd) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 611 | { |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 612 | struct rt_ht_tx_context *pHTTXContext; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 613 | int idx; |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 614 | unsigned long irqFlags; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 615 | PURB pUrb; |
| 616 | BOOLEAN needDumpSeq = FALSE; |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 617 | u32 MACValue; |
| 618 | u32 TxRxQ_Pcnt; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 619 | |
| 620 | idx = 0; |
| 621 | RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 622 | if ((MACValue & 0xff) != 0) { |
| 623 | DBGPRINT(RT_DEBUG_TRACE, |
Sebastian Dalfuß | 06aea99 | 2009-11-07 17:31:12 +0100 | [diff] [blame] | 624 | ("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n", |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 625 | MACValue)); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 626 | RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 627 | while ((MACValue & 0xff) != 0 && (idx++ < 10)) { |
| 628 | RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); |
| 629 | RTMPusecDelay(1); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 630 | } |
| 631 | RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); |
| 632 | } |
| 633 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 634 | if (pAd->watchDogRxOverFlowCnt >= 2) { |
| 635 | DBGPRINT(RT_DEBUG_TRACE, |
| 636 | ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n")); |
| 637 | if ((!RTMP_TEST_FLAG |
| 638 | (pAd, |
| 639 | (fRTMP_ADAPTER_RESET_IN_PROGRESS | |
| 640 | fRTMP_ADAPTER_BULKIN_RESET | |
| 641 | fRTMP_ADAPTER_HALT_IN_PROGRESS | |
| 642 | fRTMP_ADAPTER_NIC_NOT_EXIST)))) { |
| 643 | DBGPRINT(RT_DEBUG_TRACE, |
| 644 | ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n")); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 645 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 646 | RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, |
| 647 | NULL, 0); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 648 | needDumpSeq = TRUE; |
| 649 | } |
| 650 | pAd->watchDogRxOverFlowCnt = 0; |
| 651 | } |
| 652 | |
| 653 | RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt); |
| 654 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 655 | for (idx = 0; idx < NUM_OF_TX_RING; idx++) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 656 | pUrb = NULL; |
| 657 | |
| 658 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 659 | if ((pAd->BulkOutPending[idx] == TRUE) |
| 660 | && pAd->watchDogTxPendingCnt) { |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 661 | int actual_length = 0, transfer_buffer_length = 0; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 662 | BOOLEAN isDataPacket = FALSE; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 663 | pAd->watchDogTxPendingCnt[idx]++; |
| 664 | |
| 665 | if ((pAd->watchDogTxPendingCnt[idx] > 2) && |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 666 | (!RTMP_TEST_FLAG |
| 667 | (pAd, |
| 668 | (fRTMP_ADAPTER_RESET_IN_PROGRESS | |
| 669 | fRTMP_ADAPTER_HALT_IN_PROGRESS | |
| 670 | fRTMP_ADAPTER_NIC_NOT_EXIST | |
| 671 | fRTMP_ADAPTER_BULKOUT_RESET))) |
| 672 | ) { |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 673 | /* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 674 | pHTTXContext = |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 675 | (struct rt_ht_tx_context *)(&pAd->TxContext[idx]); |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 676 | if (pHTTXContext->IRPPending) { /* Check TxContext. */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 677 | pUrb = pHTTXContext->pUrb; |
| 678 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 679 | actual_length = pUrb->actual_length; |
| 680 | transfer_buffer_length = |
| 681 | pUrb->transfer_buffer_length; |
| 682 | isDataPacket = TRUE; |
| 683 | } else if (idx == MGMTPIPEIDX) { |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 684 | struct rt_tx_context *pMLMEContext, *pNULLContext, |
| 685 | *pPsPollContext; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 686 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 687 | /*Check MgmtContext. */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 688 | pMLMEContext = |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 689 | (struct rt_tx_context *)(pAd->MgmtRing. |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 690 | Cell[pAd->MgmtRing. |
| 691 | TxDmaIdx]. |
| 692 | AllocVa); |
| 693 | pPsPollContext = |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 694 | (struct rt_tx_context *)(&pAd->PsPollContext); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 695 | pNULLContext = |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 696 | (struct rt_tx_context *)(&pAd->NullContext); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 697 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 698 | if (pMLMEContext->IRPPending) { |
| 699 | ASSERT(pMLMEContext-> |
| 700 | IRPPending); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 701 | pUrb = pMLMEContext->pUrb; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 702 | } else if (pNULLContext->IRPPending) { |
| 703 | ASSERT(pNULLContext-> |
| 704 | IRPPending); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 705 | pUrb = pNULLContext->pUrb; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 706 | } else if (pPsPollContext->IRPPending) { |
| 707 | ASSERT(pPsPollContext-> |
| 708 | IRPPending); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 709 | pUrb = pPsPollContext->pUrb; |
| 710 | } |
| 711 | } |
| 712 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 713 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], |
| 714 | irqFlags); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 715 | |
Bartlomiej Zolnierkiewicz | ca58fb3 | 2009-10-21 22:44:42 +0200 | [diff] [blame] | 716 | printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n", |
| 717 | idx, pAd->watchDogTxPendingCnt[idx], |
| 718 | pAd->TransferedLength[idx], |
| 719 | actual_length, transfer_buffer_length); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 720 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 721 | if (pUrb) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 722 | if ((isDataPacket |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 723 | && pAd->TransferedLength[idx] == |
| 724 | actual_length |
| 725 | && pAd->TransferedLength[idx] < |
| 726 | transfer_buffer_length |
| 727 | && actual_length != 0 |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 728 | /* && TxRxQ_Pcnt==0 */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 729 | && pAd->watchDogTxPendingCnt[idx] > |
| 730 | 3) |
| 731 | || isDataPacket == FALSE |
| 732 | || pAd->watchDogTxPendingCnt[idx] > |
| 733 | 6) { |
| 734 | DBGPRINT(RT_DEBUG_TRACE, |
| 735 | ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", |
| 736 | idx)); |
| 737 | DBGPRINT(RT_DEBUG_TRACE, |
| 738 | ("Unlink the pending URB!\n")); |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 739 | /* unlink it now */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 740 | RTUSB_UNLINK_URB(pUrb); |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 741 | /* Sleep 200 microseconds to give cancellation time to work */ |
| 742 | /*RTMPusecDelay(200); */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 743 | needDumpSeq = TRUE; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 744 | } |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 745 | } else { |
| 746 | DBGPRINT(RT_DEBUG_ERROR, |
Sebastian Dalfuß | 06aea99 | 2009-11-07 17:31:12 +0100 | [diff] [blame] | 747 | ("Unknown bulkOut URB maybe hanged!\n")); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 748 | } |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 749 | } else { |
| 750 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], |
| 751 | irqFlags); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 752 | } |
| 753 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 754 | if (isDataPacket == TRUE) |
| 755 | pAd->TransferedLength[idx] = actual_length; |
| 756 | } else { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 757 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); |
| 758 | } |
| 759 | } |
| 760 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 761 | /* For Sigma debug, dump the ba_reordering sequence. */ |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 762 | if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) { |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 763 | u16 Idx; |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 764 | struct rt_ba_rec_entry *pBAEntry = NULL; |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 765 | u8 count = 0; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 766 | struct reordering_mpdu *mpdu_blk; |
| 767 | |
| 768 | Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0]; |
| 769 | |
| 770 | pBAEntry = &pAd->BATable.BARecEntry[Idx]; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 771 | if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) { |
| 772 | DBGPRINT(RT_DEBUG_TRACE, |
| 773 | ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n")); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 774 | NdisAcquireSpinLock(&pBAEntry->RxReRingLock); |
| 775 | mpdu_blk = pBAEntry->list.next; |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 776 | while (mpdu_blk) { |
| 777 | DBGPRINT(RT_DEBUG_TRACE, |
| 778 | ("\t%d:Seq-%d, bAMSDU-%d!\n", count, |
| 779 | mpdu_blk->Sequence, |
| 780 | mpdu_blk->bAMSDU)); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 781 | mpdu_blk = mpdu_blk->next; |
| 782 | count++; |
| 783 | } |
| 784 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 785 | DBGPRINT(RT_DEBUG_TRACE, |
| 786 | ("\npBAEntry->LastIndSeq=%d!\n", |
| 787 | pBAEntry->LastIndSeq)); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 788 | NdisReleaseSpinLock(&pBAEntry->RxReRingLock); |
| 789 | } |
| 790 | } |
| 791 | } |
| 792 | |
| 793 | /* |
| 794 | ======================================================================== |
| 795 | Routine Description: |
| 796 | Release allocated resources. |
| 797 | |
| 798 | Arguments: |
| 799 | *dev Point to the PCI or USB device |
| 800 | pAd driver control block pointer |
| 801 | |
| 802 | Return Value: |
| 803 | None |
| 804 | |
| 805 | Note: |
| 806 | ======================================================================== |
| 807 | */ |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 808 | static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 809 | { |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 810 | DBGPRINT(RT_DEBUG_ERROR, |
| 811 | ("rtusb_disconnect: unregister usbnet usb-%s-%s\n", |
| 812 | dev->bus->bus_name, dev->devpath)); |
| 813 | if (!pAd) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 814 | usb_put_dev(dev); |
| 815 | printk("rtusb_disconnect: pAd == NULL!\n"); |
| 816 | return; |
| 817 | } |
| 818 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); |
| 819 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 820 | /* for debug, wait to show some messages to /proc system */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 821 | udelay(1); |
| 822 | |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 823 | RtmpPhyNetDevExit(pAd, pAd->net_dev); |
| 824 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 825 | /* FIXME: Shall we need following delay and flush the schedule?? */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 826 | udelay(1); |
| 827 | flush_scheduled_work(); |
| 828 | udelay(1); |
| 829 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 830 | /* free the root net_device */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 831 | RtmpOSNetDevFree(pAd->net_dev); |
| 832 | |
| 833 | RtmpRaDevCtrlExit(pAd); |
| 834 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 835 | /* release a use of the usb device structure */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 836 | usb_put_dev(dev); |
| 837 | udelay(1); |
| 838 | |
| 839 | DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n")); |
| 840 | } |
| 841 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 842 | static int __devinit rt2870_probe(IN struct usb_interface *intf, |
| 843 | IN struct usb_device *usb_dev, |
| 844 | IN const struct usb_device_id *dev_id, |
Trey Evans | a3327f0 | 2010-04-19 16:15:37 -0400 | [diff] [blame] | 845 | struct rt_rtmp_adapter **ppAd) |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 846 | { |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 847 | struct net_device *net_dev = NULL; |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 848 | struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL; |
Bartlomiej Zolnierkiewicz | 51126de | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 849 | int status, rv; |
| 850 | void *handle; |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 851 | struct rt_rtmp_os_netdev_op_hook netDevHook; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 852 | |
| 853 | DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n")); |
| 854 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 855 | /* Check chipset vendor/product ID */ |
| 856 | /*if (RT28XXChipsetCheck(_dev_p) == FALSE) */ |
| 857 | /* goto err_out; */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 858 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 859 | /*RtmpDevInit============================================= */ |
Bartlomiej Zolnierkiewicz | 62eb734 | 2009-12-11 12:23:16 -0800 | [diff] [blame] | 860 | /* Allocate struct rt_rtmp_adapter adapter structure */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 861 | handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 862 | if (handle == NULL) { |
| 863 | printk |
| 864 | ("rt2870_probe(): Allocate memory for os handle failed!\n"); |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 865 | return -ENOMEM; |
| 866 | } |
Bartlomiej Zolnierkiewicz | 8a10a54 | 2009-12-11 12:23:15 -0800 | [diff] [blame] | 867 | ((struct os_cookie *)handle)->pUsb_Dev = usb_dev; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 868 | |
| 869 | rv = RTMPAllocAdapterBlock(handle, &pAd); |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 870 | if (rv != NDIS_STATUS_SUCCESS) { |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 871 | kfree(handle); |
| 872 | goto err_out; |
| 873 | } |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 874 | /*USBDevInit============================================== */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 875 | if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE) |
| 876 | goto err_out_free_radev; |
| 877 | |
| 878 | RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB); |
| 879 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 880 | /*NetDevInit============================================== */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 881 | net_dev = RtmpPhyNetDevInit(pAd, &netDevHook); |
| 882 | if (net_dev == NULL) |
| 883 | goto err_out_free_radev; |
| 884 | |
Justin P. Mattock | 6ccb5d7 | 2010-11-08 13:41:46 -0800 | [diff] [blame^] | 885 | /* Here are the net_device structure with usb specific parameters. |
| 886 | * for supporting Network Manager. |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 887 | * Set the sysfs physical device reference for the network logical device if set prior to registration will |
| 888 | * cause a symlink during initialization. |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 889 | */ |
| 890 | SET_NETDEV_DEV(net_dev, &(usb_dev->dev)); |
| 891 | |
Bartlomiej Zolnierkiewicz | 66cd8d6 | 2009-12-11 12:23:13 -0800 | [diff] [blame] | 892 | pAd->StaCfg.OriDevType = net_dev->type; |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 893 | |
Bartlomiej Zolnierkiewicz | 9f548a2 | 2009-12-11 12:23:14 -0800 | [diff] [blame] | 894 | /*All done, it's time to register the net device to linux kernel. */ |
| 895 | /* Register this device */ |
Bartlomiej Zolnierkiewicz | ca97b83 | 2009-09-22 20:44:07 +0200 | [diff] [blame] | 896 | status = RtmpOSNetDevAttach(net_dev, &netDevHook); |
| 897 | if (status != 0) |
| 898 | goto err_out_free_netdev; |
| 899 | |
| 900 | #ifdef KTHREAD_SUPPORT |
| 901 | init_waitqueue_head(&pAd->mlmeTask.kthread_q); |
| 902 | init_waitqueue_head(&pAd->timerTask.kthread_q); |
| 903 | init_waitqueue_head(&pAd->cmdQTask.kthread_q); |
| 904 | #endif |
| 905 | |
| 906 | *ppAd = pAd; |
| 907 | |
| 908 | DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n")); |
| 909 | |
| 910 | return 0; |
| 911 | |
| 912 | /* --------------------------- ERROR HANDLE --------------------------- */ |
| 913 | err_out_free_netdev: |
| 914 | RtmpOSNetDevFree(net_dev); |
| 915 | |
| 916 | err_out_free_radev: |
| 917 | RTMPFreeAdapter(pAd); |
| 918 | |
| 919 | err_out: |
| 920 | *ppAd = NULL; |
| 921 | |
| 922 | return -1; |
| 923 | |
| 924 | } |