Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include "hfa384x_usb.c"
0003 #include "prism2mgmt.c"
0004 #include "prism2mib.c"
0005 #include "prism2sta.c"
0006 #include "prism2fw.c"
0007 
0008 #define PRISM_DEV(vid, pid, name)       \
0009     { USB_DEVICE(vid, pid),         \
0010     .driver_info = (unsigned long)name }
0011 
0012 static const struct usb_device_id usb_prism_tbl[] = {
0013     PRISM_DEV(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS"),
0014     PRISM_DEV(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11"),
0015     PRISM_DEV(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter"),
0016     PRISM_DEV(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter"),
0017     PRISM_DEV(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter"),
0018     PRISM_DEV(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter"),
0019     PRISM_DEV(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter"),
0020     PRISM_DEV(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter"),
0021     PRISM_DEV(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter"),
0022     PRISM_DEV(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter"),
0023     PRISM_DEV(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter"),
0024     PRISM_DEV(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter"),
0025     PRISM_DEV(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter"),
0026     PRISM_DEV(0x0967, 0x0204, "Acer Warplink USB Adapter"),
0027     PRISM_DEV(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated"),
0028     PRISM_DEV(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter"),
0029     PRISM_DEV(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter"),
0030     PRISM_DEV(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter"),
0031     PRISM_DEV(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter"),
0032     PRISM_DEV(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter"),
0033     PRISM_DEV(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter"),
0034     PRISM_DEV(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter"),
0035     PRISM_DEV(0x0846, 0x4110, "NetGear MA111"),
0036     PRISM_DEV(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter"),
0037     PRISM_DEV(0x2821, 0x3300, "ASUS-WL140 / Hawking HighDB Wireless USB Adapter"),
0038     PRISM_DEV(0x2001, 0x3700, "DWL-122 Wireless USB Adapter"),
0039     PRISM_DEV(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter"),
0040     PRISM_DEV(0x50c2, 0x4013, "Averatec USB WLAN Adapter"),
0041     PRISM_DEV(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter"),
0042     PRISM_DEV(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter"),
0043     PRISM_DEV(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter"),
0044     PRISM_DEV(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter"),
0045     PRISM_DEV(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter"),
0046     PRISM_DEV(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter"),
0047     PRISM_DEV(0x0bb2, 0x0302, "Ambit Microsystems Corp."),
0048     PRISM_DEV(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter"),
0049     PRISM_DEV(0x0543, 0x0f01,
0050           "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)"),
0051     PRISM_DEV(0x067c, 0x1022,
0052           "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter"),
0053     PRISM_DEV(0x049f, 0x0033,
0054           "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter"),
0055     { } /* terminator */
0056 };
0057 MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
0058 
0059 static int prism2sta_probe_usb(struct usb_interface *interface,
0060                    const struct usb_device_id *id)
0061 {
0062     struct usb_device *dev;
0063     struct usb_endpoint_descriptor *bulk_in, *bulk_out;
0064     struct usb_host_interface *iface_desc = interface->cur_altsetting;
0065     struct wlandevice *wlandev = NULL;
0066     struct hfa384x *hw = NULL;
0067     int result = 0;
0068 
0069     result = usb_find_common_endpoints(iface_desc, &bulk_in, &bulk_out, NULL, NULL);
0070     if (result)
0071         goto failed;
0072 
0073     dev = interface_to_usbdev(interface);
0074     wlandev = create_wlan();
0075     if (!wlandev) {
0076         dev_err(&interface->dev, "Memory allocation failure.\n");
0077         result = -EIO;
0078         goto failed;
0079     }
0080     hw = wlandev->priv;
0081 
0082     if (wlan_setup(wlandev, &interface->dev) != 0) {
0083         dev_err(&interface->dev, "wlan_setup() failed.\n");
0084         result = -EIO;
0085         goto failed;
0086     }
0087 
0088     /* Initialize the hw data */
0089     hw->endp_in = usb_rcvbulkpipe(dev, bulk_in->bEndpointAddress);
0090     hw->endp_out = usb_sndbulkpipe(dev, bulk_out->bEndpointAddress);
0091     hfa384x_create(hw, dev);
0092     hw->wlandev = wlandev;
0093 
0094     /* Register the wlandev, this gets us a name and registers the
0095      * linux netdevice.
0096      */
0097     SET_NETDEV_DEV(wlandev->netdev, &interface->dev);
0098 
0099     /* Do a chip-level reset on the MAC */
0100     if (prism2_doreset) {
0101         result = hfa384x_corereset(hw,
0102                        prism2_reset_holdtime,
0103                        prism2_reset_settletime, 0);
0104         if (result != 0) {
0105             result = -EIO;
0106             dev_err(&interface->dev,
0107                 "hfa384x_corereset() failed.\n");
0108             goto failed_reset;
0109         }
0110     }
0111 
0112     usb_get_dev(dev);
0113 
0114     wlandev->msdstate = WLAN_MSD_HWPRESENT;
0115 
0116     /* Try and load firmware, then enable card before we register */
0117     prism2_fwtry(dev, wlandev);
0118     prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);
0119 
0120     if (register_wlandev(wlandev) != 0) {
0121         dev_err(&interface->dev, "register_wlandev() failed.\n");
0122         result = -EIO;
0123         goto failed_register;
0124     }
0125 
0126     goto done;
0127 
0128 failed_register:
0129     usb_put_dev(dev);
0130 failed_reset:
0131     wlan_unsetup(wlandev);
0132 failed:
0133     kfree(wlandev);
0134     kfree(hw);
0135     wlandev = NULL;
0136 
0137 done:
0138     usb_set_intfdata(interface, wlandev);
0139     return result;
0140 }
0141 
0142 static void prism2sta_disconnect_usb(struct usb_interface *interface)
0143 {
0144     struct wlandevice *wlandev;
0145 
0146     wlandev = usb_get_intfdata(interface);
0147     if (wlandev) {
0148         LIST_HEAD(cleanlist);
0149         struct hfa384x_usbctlx *ctlx, *temp;
0150         unsigned long flags;
0151 
0152         struct hfa384x *hw = wlandev->priv;
0153 
0154         if (!hw)
0155             goto exit;
0156 
0157         spin_lock_irqsave(&hw->ctlxq.lock, flags);
0158 
0159         p80211netdev_hwremoved(wlandev);
0160         list_splice_init(&hw->ctlxq.reapable, &cleanlist);
0161         list_splice_init(&hw->ctlxq.completing, &cleanlist);
0162         list_splice_init(&hw->ctlxq.pending, &cleanlist);
0163         list_splice_init(&hw->ctlxq.active, &cleanlist);
0164 
0165         spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
0166 
0167         /* There's no hardware to shutdown, but the driver
0168          * might have some tasks that must be stopped before
0169          * we can tear everything down.
0170          */
0171         prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
0172 
0173         del_singleshot_timer_sync(&hw->throttle);
0174         del_singleshot_timer_sync(&hw->reqtimer);
0175         del_singleshot_timer_sync(&hw->resptimer);
0176 
0177         /* Unlink all the URBs. This "removes the wheels"
0178          * from the entire CTLX handling mechanism.
0179          */
0180         usb_kill_urb(&hw->rx_urb);
0181         usb_kill_urb(&hw->tx_urb);
0182         usb_kill_urb(&hw->ctlx_urb);
0183 
0184         cancel_work_sync(&hw->completion_bh);
0185         cancel_work_sync(&hw->reaper_bh);
0186 
0187         cancel_work_sync(&hw->link_bh);
0188         cancel_work_sync(&hw->commsqual_bh);
0189         cancel_work_sync(&hw->usb_work);
0190 
0191         /* Now we complete any outstanding commands
0192          * and tell everyone who is waiting for their
0193          * responses that we have shut down.
0194          */
0195         list_for_each_entry(ctlx, &cleanlist, list)
0196             complete(&ctlx->done);
0197 
0198         /* Give any outstanding synchronous commands
0199          * a chance to complete. All they need to do
0200          * is "wake up", so that's easy.
0201          * (I'd like a better way to do this, really.)
0202          */
0203         msleep(100);
0204 
0205         /* Now delete the CTLXs, because no-one else can now. */
0206         list_for_each_entry_safe(ctlx, temp, &cleanlist, list)
0207             kfree(ctlx);
0208 
0209         /* Unhook the wlandev */
0210         unregister_wlandev(wlandev);
0211         wlan_unsetup(wlandev);
0212 
0213         usb_put_dev(hw->usb);
0214 
0215         hfa384x_destroy(hw);
0216         kfree(hw);
0217 
0218         kfree(wlandev);
0219     }
0220 
0221 exit:
0222     usb_set_intfdata(interface, NULL);
0223 }
0224 
0225 #ifdef CONFIG_PM
0226 static int prism2sta_suspend(struct usb_interface *interface,
0227                  pm_message_t message)
0228 {
0229     struct hfa384x *hw = NULL;
0230     struct wlandevice *wlandev;
0231 
0232     wlandev = usb_get_intfdata(interface);
0233     if (!wlandev)
0234         return -ENODEV;
0235 
0236     hw = wlandev->priv;
0237     if (!hw)
0238         return -ENODEV;
0239 
0240     prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
0241 
0242     usb_kill_urb(&hw->rx_urb);
0243     usb_kill_urb(&hw->tx_urb);
0244     usb_kill_urb(&hw->ctlx_urb);
0245 
0246     return 0;
0247 }
0248 
0249 static int prism2sta_resume(struct usb_interface *interface)
0250 {
0251     int result = 0;
0252     struct hfa384x *hw = NULL;
0253     struct wlandevice *wlandev;
0254 
0255     wlandev = usb_get_intfdata(interface);
0256     if (!wlandev)
0257         return -ENODEV;
0258 
0259     hw = wlandev->priv;
0260     if (!hw)
0261         return -ENODEV;
0262 
0263     /* Do a chip-level reset on the MAC */
0264     if (prism2_doreset) {
0265         result = hfa384x_corereset(hw,
0266                        prism2_reset_holdtime,
0267                        prism2_reset_settletime, 0);
0268         if (result != 0) {
0269             unregister_wlandev(wlandev);
0270             hfa384x_destroy(hw);
0271             dev_err(&interface->dev, "hfa384x_corereset() failed.\n");
0272             kfree(wlandev);
0273             kfree(hw);
0274             wlandev = NULL;
0275             return -ENODEV;
0276         }
0277     }
0278 
0279     prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);
0280 
0281     return 0;
0282 }
0283 #else
0284 #define prism2sta_suspend NULL
0285 #define prism2sta_resume NULL
0286 #endif /* CONFIG_PM */
0287 
0288 static struct usb_driver prism2_usb_driver = {
0289     .name = "prism2_usb",
0290     .probe = prism2sta_probe_usb,
0291     .disconnect = prism2sta_disconnect_usb,
0292     .id_table = usb_prism_tbl,
0293     .suspend = prism2sta_suspend,
0294     .resume = prism2sta_resume,
0295     .reset_resume = prism2sta_resume,
0296     /* fops, minor? */
0297 };
0298 
0299 module_usb_driver(prism2_usb_driver);