1141 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3/*4 * Linux device driver for USB based Prism545 *6 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>7 *8 * Based on the islsm (softmac prism54) driver, which is:9 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.10 */11 12#include <linux/usb.h>13#include <linux/pci.h>14#include <linux/slab.h>15#include <linux/firmware.h>16#include <linux/etherdevice.h>17#include <linux/delay.h>18#include <linux/crc32.h>19#include <linux/module.h>20#include <net/mac80211.h>21 22#include "p54.h"23#include "lmac.h"24#include "p54usb.h"25 26MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");27MODULE_DESCRIPTION("Prism54 USB wireless driver");28MODULE_LICENSE("GPL");29MODULE_ALIAS("prism54usb");30MODULE_FIRMWARE("isl3886usb");31MODULE_FIRMWARE("isl3887usb");32 33static struct usb_driver p54u_driver;34 35/*36 * Note:37 *38 * Always update our wiki's device list (located at:39 * http://wireless.wiki.kernel.org/en/users/Drivers/p54/devices ),40 * whenever you add a new device.41 */42 43static const struct usb_device_id p54u_table[] = {44 /* Version 1 devices (pci chip + net2280) */45 {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */46 {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */47 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */48 {USB_DEVICE(0x0675, 0x0530)}, /* DrayTek Vigor 530 */49 {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */50 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */51 {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */52 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */53 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */54 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */55 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */56 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */57 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */58 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */59 {USB_DEVICE(0x0bf8, 0x1007)}, /* Fujitsu E-5400 USB */60 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */61 {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */62 {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */63 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */64 {USB_DEVICE(0x124a, 0x4026)}, /* AirVasT USB wireless device */65 {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */66 {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */67 {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */68 {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */69 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */70 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */71 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */72 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */73 {USB_DEVICE(0x2001, 0x3762)}, /* Conceptronic C54U */74 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */75 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */76 77 /* Version 2 devices (3887) */78 {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */79 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */80 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */81 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */82 {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */83 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */84 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */85 {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */86 {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */87 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */88 {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */89 {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */90 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */91 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */92 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */93 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */94 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/95 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/96 /* {USB_DEVICE(0x0cde, 0x0006)}, * Medion MD40900 already listed above,97 * just noting it here for clarity */98 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */99 {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */100 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */101 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */102 {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */103 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */104 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */105 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */106 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */107 /* {USB_DEVICE(0x15a9, 0x0002)}, * Also SparkLAN WL-682 with 3887 */108 {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */109 {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */110 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */111 {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */112 {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */113 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */114 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */115 {}116};117 118MODULE_DEVICE_TABLE(usb, p54u_table);119 120static const struct {121 u32 intf;122 enum p54u_hw_type type;123 const char *fw;124 char hw[20];125} p54u_fwlist[__NUM_P54U_HWTYPES] = {126 {127 .type = P54U_NET2280,128 .intf = FW_LM86,129 .fw = "isl3886usb",130 .hw = "ISL3886 + net2280",131 },132 {133 .type = P54U_3887,134 .intf = FW_LM87,135 .fw = "isl3887usb",136 .hw = "ISL3887",137 },138};139 140static void p54u_rx_cb(struct urb *urb)141{142 struct sk_buff *skb = (struct sk_buff *) urb->context;143 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;144 struct ieee80211_hw *dev = info->dev;145 struct p54u_priv *priv = dev->priv;146 147 skb_unlink(skb, &priv->rx_queue);148 149 if (unlikely(urb->status)) {150 dev_kfree_skb_irq(skb);151 return;152 }153 154 skb_put(skb, urb->actual_length);155 156 if (priv->hw_type == P54U_NET2280)157 skb_pull(skb, priv->common.tx_hdr_len);158 if (priv->common.fw_interface == FW_LM87) {159 skb_pull(skb, 4);160 skb_put(skb, 4);161 }162 163 if (p54_rx(dev, skb)) {164 skb = dev_alloc_skb(priv->common.rx_mtu + 32);165 if (unlikely(!skb)) {166 /* TODO check rx queue length and refill *somewhere* */167 return;168 }169 170 info = (struct p54u_rx_info *) skb->cb;171 info->urb = urb;172 info->dev = dev;173 urb->transfer_buffer = skb_tail_pointer(skb);174 urb->context = skb;175 } else {176 if (priv->hw_type == P54U_NET2280)177 skb_push(skb, priv->common.tx_hdr_len);178 if (priv->common.fw_interface == FW_LM87) {179 skb_push(skb, 4);180 skb_put(skb, 4);181 }182 skb_reset_tail_pointer(skb);183 skb_trim(skb, 0);184 urb->transfer_buffer = skb_tail_pointer(skb);185 }186 skb_queue_tail(&priv->rx_queue, skb);187 usb_anchor_urb(urb, &priv->submitted);188 if (usb_submit_urb(urb, GFP_ATOMIC)) {189 skb_unlink(skb, &priv->rx_queue);190 usb_unanchor_urb(urb);191 dev_kfree_skb_irq(skb);192 }193}194 195static void p54u_tx_cb(struct urb *urb)196{197 struct sk_buff *skb = urb->context;198 struct ieee80211_hw *dev =199 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));200 201 p54_free_skb(dev, skb);202}203 204static void p54u_tx_dummy_cb(struct urb *urb) { }205 206static void p54u_free_urbs(struct ieee80211_hw *dev)207{208 struct p54u_priv *priv = dev->priv;209 usb_kill_anchored_urbs(&priv->submitted);210}211 212static void p54u_stop(struct ieee80211_hw *dev)213{214 /*215 * TODO: figure out how to reliably stop the 3887 and net2280 so216 * the hardware is still usable next time we want to start it.217 * until then, we just stop listening to the hardware..218 */219 p54u_free_urbs(dev);220}221 222static int p54u_init_urbs(struct ieee80211_hw *dev)223{224 struct p54u_priv *priv = dev->priv;225 struct urb *entry = NULL;226 struct sk_buff *skb;227 struct p54u_rx_info *info;228 int ret = 0;229 230 while (skb_queue_len(&priv->rx_queue) < 32) {231 skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);232 if (!skb) {233 ret = -ENOMEM;234 goto err;235 }236 entry = usb_alloc_urb(0, GFP_KERNEL);237 if (!entry) {238 ret = -ENOMEM;239 goto err;240 }241 242 usb_fill_bulk_urb(entry, priv->udev,243 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),244 skb_tail_pointer(skb),245 priv->common.rx_mtu + 32, p54u_rx_cb, skb);246 info = (struct p54u_rx_info *) skb->cb;247 info->urb = entry;248 info->dev = dev;249 skb_queue_tail(&priv->rx_queue, skb);250 251 usb_anchor_urb(entry, &priv->submitted);252 ret = usb_submit_urb(entry, GFP_KERNEL);253 if (ret) {254 skb_unlink(skb, &priv->rx_queue);255 usb_unanchor_urb(entry);256 goto err;257 }258 usb_free_urb(entry);259 entry = NULL;260 }261 262 return 0;263 264 err:265 usb_free_urb(entry);266 kfree_skb(skb);267 p54u_free_urbs(dev);268 return ret;269}270 271static int p54u_open(struct ieee80211_hw *dev)272{273 /*274 * TODO: Because we don't know how to reliably stop the 3887 and275 * the isl3886+net2280, other than brutally cut off all276 * communications. We have to reinitialize the urbs on every start.277 */278 return p54u_init_urbs(dev);279}280 281static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)282{283 u32 chk = 0;284 285 length >>= 2;286 while (length--) {287 chk ^= le32_to_cpu(*data++);288 chk = (chk >> 5) ^ (chk << 3);289 }290 291 return cpu_to_le32(chk);292}293 294static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)295{296 struct p54u_priv *priv = dev->priv;297 struct urb *data_urb;298 struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);299 300 data_urb = usb_alloc_urb(0, GFP_ATOMIC);301 if (!data_urb) {302 p54_free_skb(dev, skb);303 return;304 }305 306 hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);307 hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;308 309 usb_fill_bulk_urb(data_urb, priv->udev,310 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),311 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?312 p54u_tx_cb : p54u_tx_dummy_cb, skb);313 data_urb->transfer_flags |= URB_ZERO_PACKET;314 315 usb_anchor_urb(data_urb, &priv->submitted);316 if (usb_submit_urb(data_urb, GFP_ATOMIC)) {317 usb_unanchor_urb(data_urb);318 p54_free_skb(dev, skb);319 }320 usb_free_urb(data_urb);321}322 323static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)324{325 struct p54u_priv *priv = dev->priv;326 struct urb *int_urb = NULL, *data_urb = NULL;327 struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);328 struct net2280_reg_write *reg = NULL;329 int err = -ENOMEM;330 331 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);332 if (!reg)333 goto out;334 335 int_urb = usb_alloc_urb(0, GFP_ATOMIC);336 if (!int_urb)337 goto out;338 339 data_urb = usb_alloc_urb(0, GFP_ATOMIC);340 if (!data_urb)341 goto out;342 343 reg->port = cpu_to_le16(NET2280_DEV_U32);344 reg->addr = cpu_to_le32(P54U_DEV_BASE);345 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);346 347 memset(hdr, 0, sizeof(*hdr));348 hdr->len = cpu_to_le16(skb->len);349 hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;350 351 usb_fill_bulk_urb(int_urb, priv->udev,352 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),353 p54u_tx_dummy_cb, dev);354 355 /*356 * URB_FREE_BUFFER triggers a code path in the USB subsystem that will357 * free what is inside the transfer_buffer after the last reference to358 * the int_urb is dropped.359 */360 int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;361 reg = NULL;362 363 usb_fill_bulk_urb(data_urb, priv->udev,364 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),365 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?366 p54u_tx_cb : p54u_tx_dummy_cb, skb);367 data_urb->transfer_flags |= URB_ZERO_PACKET;368 369 usb_anchor_urb(int_urb, &priv->submitted);370 err = usb_submit_urb(int_urb, GFP_ATOMIC);371 if (err) {372 usb_unanchor_urb(int_urb);373 goto out;374 }375 376 usb_anchor_urb(data_urb, &priv->submitted);377 err = usb_submit_urb(data_urb, GFP_ATOMIC);378 if (err) {379 usb_unanchor_urb(data_urb);380 goto out;381 }382out:383 usb_free_urb(int_urb);384 usb_free_urb(data_urb);385 386 if (err) {387 kfree(reg);388 p54_free_skb(dev, skb);389 }390}391 392static int p54u_write(struct p54u_priv *priv,393 struct net2280_reg_write *buf,394 enum net2280_op_type type,395 __le32 addr, __le32 val)396{397 unsigned int ep;398 int alen;399 400 if (type & 0x0800)401 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);402 else403 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);404 405 buf->port = cpu_to_le16(type);406 buf->addr = addr;407 buf->val = val;408 409 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);410}411 412static int p54u_read(struct p54u_priv *priv, void *buf,413 enum net2280_op_type type,414 __le32 addr, __le32 *val)415{416 struct net2280_reg_read *read = buf;417 __le32 *reg = buf;418 unsigned int ep;419 int alen, err;420 421 if (type & 0x0800)422 ep = P54U_PIPE_DEV;423 else424 ep = P54U_PIPE_BRG;425 426 read->port = cpu_to_le16(type);427 read->addr = addr;428 429 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),430 read, sizeof(*read), &alen, 1000);431 if (err)432 return err;433 434 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),435 reg, sizeof(*reg), &alen, 1000);436 if (err)437 return err;438 439 *val = *reg;440 return 0;441}442 443static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,444 void *data, size_t len)445{446 int alen;447 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),448 data, len, &alen, 2000);449}450 451static int p54u_device_reset(struct ieee80211_hw *dev)452{453 struct p54u_priv *priv = dev->priv;454 int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);455 456 if (lock) {457 ret = usb_lock_device_for_reset(priv->udev, priv->intf);458 if (ret < 0) {459 dev_err(&priv->udev->dev, "(p54usb) unable to lock "460 "device for reset (%d)!\n", ret);461 return ret;462 }463 }464 465 ret = usb_reset_device(priv->udev);466 if (lock)467 usb_unlock_device(priv->udev);468 469 if (ret)470 dev_err(&priv->udev->dev, "(p54usb) unable to reset "471 "device (%d)!\n", ret);472 473 return ret;474}475 476static const char p54u_romboot_3887[] = "~~~~";477static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)478{479 struct p54u_priv *priv = dev->priv;480 u8 *buf;481 int ret;482 483 buf = kmemdup(p54u_romboot_3887, 4, GFP_KERNEL);484 if (!buf)485 return -ENOMEM;486 ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,487 buf, 4);488 kfree(buf);489 if (ret)490 dev_err(&priv->udev->dev, "(p54usb) unable to jump to "491 "boot ROM (%d)!\n", ret);492 493 return ret;494}495 496static const char p54u_firmware_upload_3887[] = "<\r";497static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)498{499 struct p54u_priv *priv = dev->priv;500 int err, alen;501 u8 carry = 0;502 u8 *buf, *tmp;503 const u8 *data;504 unsigned int left, remains, block_size;505 struct x2_header *hdr;506 unsigned long timeout;507 508 err = p54u_firmware_reset_3887(dev);509 if (err)510 return err;511 512 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);513 if (!buf)514 return -ENOMEM;515 516 left = block_size = min_t(size_t, P54U_FW_BLOCK, priv->fw->size);517 strcpy(buf, p54u_firmware_upload_3887);518 left -= strlen(p54u_firmware_upload_3887);519 tmp += strlen(p54u_firmware_upload_3887);520 521 data = priv->fw->data;522 remains = priv->fw->size;523 524 hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));525 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);526 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);527 hdr->fw_length = cpu_to_le32(priv->fw->size);528 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,529 sizeof(u32)*2));530 left -= sizeof(*hdr);531 tmp += sizeof(*hdr);532 533 while (remains) {534 while (left--) {535 if (carry) {536 *tmp++ = carry;537 carry = 0;538 remains--;539 continue;540 }541 switch (*data) {542 case '~':543 *tmp++ = '}';544 carry = '^';545 break;546 case '}':547 *tmp++ = '}';548 carry = ']';549 break;550 default:551 *tmp++ = *data;552 remains--;553 break;554 }555 data++;556 }557 558 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);559 if (err) {560 dev_err(&priv->udev->dev, "(p54usb) firmware "561 "upload failed!\n");562 goto err_upload_failed;563 }564 565 tmp = buf;566 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);567 }568 569 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data,570 priv->fw->size));571 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));572 if (err) {573 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");574 goto err_upload_failed;575 }576 timeout = jiffies + msecs_to_jiffies(1000);577 while (!(err = usb_bulk_msg(priv->udev,578 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {579 if (alen > 2 && !memcmp(buf, "OK", 2))580 break;581 582 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {583 err = -EINVAL;584 break;585 }586 587 if (time_after(jiffies, timeout)) {588 dev_err(&priv->udev->dev, "(p54usb) firmware boot "589 "timed out!\n");590 err = -ETIMEDOUT;591 break;592 }593 }594 if (err) {595 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");596 goto err_upload_failed;597 }598 599 buf[0] = 'g';600 buf[1] = '\r';601 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);602 if (err) {603 dev_err(&priv->udev->dev, "(p54usb) firmware boot failed!\n");604 goto err_upload_failed;605 }606 607 timeout = jiffies + msecs_to_jiffies(1000);608 while (!(err = usb_bulk_msg(priv->udev,609 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {610 if (alen > 0 && buf[0] == 'g')611 break;612 613 if (time_after(jiffies, timeout)) {614 err = -ETIMEDOUT;615 break;616 }617 }618 if (err)619 goto err_upload_failed;620 621err_upload_failed:622 kfree(buf);623 return err;624}625 626static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)627{628 struct p54u_priv *priv = dev->priv;629 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;630 int err, alen;631 void *buf;632 __le32 reg;633 unsigned int remains, offset;634 const u8 *data;635 636 buf = kmalloc(512, GFP_KERNEL);637 if (!buf)638 return -ENOMEM;639 640#define P54U_WRITE(type, addr, data) \641 do {\642 err = p54u_write(priv, buf, type,\643 cpu_to_le32((u32)(unsigned long)addr), data);\644 if (err) \645 goto fail;\646 } while (0)647 648#define P54U_READ(type, addr) \649 do {\650 err = p54u_read(priv, buf, type,\651 cpu_to_le32((u32)(unsigned long)addr), ®);\652 if (err)\653 goto fail;\654 } while (0)655 656 /* power down net2280 bridge */657 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);658 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);659 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);660 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);661 662 mdelay(100);663 664 /* power up bridge */665 reg |= cpu_to_le32(P54U_BRG_POWER_UP);666 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);667 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);668 669 mdelay(100);670 671 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,672 cpu_to_le32(NET2280_CLK_30Mhz |673 NET2280_PCI_ENABLE |674 NET2280_PCI_SOFT_RESET));675 676 mdelay(20);677 678 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,679 cpu_to_le32(PCI_COMMAND_MEMORY |680 PCI_COMMAND_MASTER));681 682 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,683 cpu_to_le32(NET2280_BASE));684 685 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);686 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);687 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);688 689 // TODO: we really need this?690 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);691 692 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,693 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));694 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,695 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));696 697 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,698 cpu_to_le32(NET2280_BASE2));699 700 /* finally done setting up the bridge */701 702 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,703 cpu_to_le32(PCI_COMMAND_MEMORY |704 PCI_COMMAND_MASTER));705 706 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);707 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,708 cpu_to_le32(P54U_DEV_BASE));709 710 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);711 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,712 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));713 714 /* do romboot */715 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);716 717 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);718 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);719 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);720 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);721 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);722 723 mdelay(20);724 725 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);726 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);727 728 mdelay(20);729 730 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);731 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);732 733 mdelay(100);734 735 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);736 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);737 738 /* finally, we can upload firmware now! */739 remains = priv->fw->size;740 data = priv->fw->data;741 offset = ISL38XX_DEV_FIRMWARE_ADDR;742 743 while (remains) {744 unsigned int block_len = min(remains, (unsigned int)512);745 memcpy(buf, data, block_len);746 747 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);748 if (err) {749 dev_err(&priv->udev->dev, "(p54usb) firmware block "750 "upload failed\n");751 goto fail;752 }753 754 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,755 cpu_to_le32(0xc0000f00));756 757 P54U_WRITE(NET2280_DEV_U32,758 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);759 P54U_WRITE(NET2280_DEV_U32,760 0x0020 | (unsigned long)&devreg->direct_mem_win,761 cpu_to_le32(1));762 763 P54U_WRITE(NET2280_DEV_U32,764 0x0024 | (unsigned long)&devreg->direct_mem_win,765 cpu_to_le32(block_len));766 P54U_WRITE(NET2280_DEV_U32,767 0x0028 | (unsigned long)&devreg->direct_mem_win,768 cpu_to_le32(offset));769 770 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,771 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));772 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,773 cpu_to_le32(block_len >> 2));774 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,775 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));776 777 mdelay(10);778 779 P54U_READ(NET2280_DEV_U32,780 0x002C | (unsigned long)&devreg->direct_mem_win);781 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||782 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {783 dev_err(&priv->udev->dev, "(p54usb) firmware DMA "784 "transfer failed\n");785 goto fail;786 }787 788 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,789 cpu_to_le32(NET2280_FIFO_FLUSH));790 791 remains -= block_len;792 data += block_len;793 offset += block_len;794 }795 796 /* do ramboot */797 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);798 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);799 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);800 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);801 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);802 803 mdelay(20);804 805 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);806 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);807 808 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);809 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);810 811 mdelay(100);812 813 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);814 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);815 816 /* start up the firmware */817 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,818 cpu_to_le32(ISL38XX_INT_IDENT_INIT));819 820 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,821 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));822 823 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,824 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |825 NET2280_USB_INTERRUPT_ENABLE));826 827 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,828 cpu_to_le32(ISL38XX_DEV_INT_RESET));829 830 err = usb_interrupt_msg(priv->udev,831 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),832 buf, sizeof(__le32), &alen, 1000);833 if (err || alen != sizeof(__le32))834 goto fail;835 836 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);837 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);838 839 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))840 err = -EINVAL;841 842 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);843 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,844 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));845 846#undef P54U_WRITE847#undef P54U_READ848 849fail:850 kfree(buf);851 return err;852}853 854static int p54_find_type(struct p54u_priv *priv)855{856 int i;857 858 for (i = 0; i < __NUM_P54U_HWTYPES; i++)859 if (p54u_fwlist[i].type == priv->hw_type)860 break;861 if (i == __NUM_P54U_HWTYPES)862 return -EOPNOTSUPP;863 864 return i;865}866 867static int p54u_start_ops(struct p54u_priv *priv)868{869 struct ieee80211_hw *dev = priv->common.hw;870 int ret;871 872 ret = p54_parse_firmware(dev, priv->fw);873 if (ret)874 goto err_out;875 876 ret = p54_find_type(priv);877 if (ret < 0)878 goto err_out;879 880 if (priv->common.fw_interface != p54u_fwlist[ret].intf) {881 dev_err(&priv->udev->dev, "wrong firmware, please get "882 "a firmware for \"%s\" and try again.\n",883 p54u_fwlist[ret].hw);884 ret = -ENODEV;885 goto err_out;886 }887 888 ret = priv->upload_fw(dev);889 if (ret)890 goto err_out;891 892 ret = p54u_open(dev);893 if (ret)894 goto err_out;895 896 ret = p54_read_eeprom(dev);897 if (ret)898 goto err_stop;899 900 p54u_stop(dev);901 902 ret = p54_register_common(dev, &priv->udev->dev);903 if (ret)904 goto err_stop;905 906 return 0;907 908err_stop:909 p54u_stop(dev);910 911err_out:912 /*913 * p54u_disconnect will do the rest of the914 * cleanup915 */916 return ret;917}918 919static void p54u_load_firmware_cb(const struct firmware *firmware,920 void *context)921{922 struct p54u_priv *priv = context;923 struct usb_device *udev = priv->udev;924 struct usb_interface *intf = priv->intf;925 int err;926 927 if (firmware) {928 priv->fw = firmware;929 err = p54u_start_ops(priv);930 } else {931 err = -ENOENT;932 dev_err(&udev->dev, "Firmware not found.\n");933 }934 935 complete(&priv->fw_wait_load);936 /*937 * At this point p54u_disconnect may have already freed938 * the "priv" context. Do not use it anymore!939 */940 priv = NULL;941 942 if (err) {943 dev_err(&intf->dev, "failed to initialize device (%d)\n", err);944 945 usb_lock_device(udev);946 usb_driver_release_interface(&p54u_driver, intf);947 usb_unlock_device(udev);948 }949 950 usb_put_intf(intf);951}952 953static int p54u_load_firmware(struct ieee80211_hw *dev,954 struct usb_interface *intf)955{956 struct usb_device *udev = interface_to_usbdev(intf);957 struct p54u_priv *priv = dev->priv;958 struct device *device = &udev->dev;959 int err, i;960 961 BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES);962 963 init_completion(&priv->fw_wait_load);964 i = p54_find_type(priv);965 if (i < 0)966 return i;967 968 dev_info(&priv->udev->dev, "Loading firmware file %s\n",969 p54u_fwlist[i].fw);970 971 usb_get_intf(intf);972 err = request_firmware_nowait(THIS_MODULE, 1, p54u_fwlist[i].fw,973 device, GFP_KERNEL, priv,974 p54u_load_firmware_cb);975 if (err) {976 dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "977 "(%d)!\n", p54u_fwlist[i].fw, err);978 usb_put_intf(intf);979 }980 981 return err;982}983 984static int p54u_probe(struct usb_interface *intf,985 const struct usb_device_id *id)986{987 struct usb_device *udev = interface_to_usbdev(intf);988 struct ieee80211_hw *dev;989 struct p54u_priv *priv;990 int err;991 unsigned int i, recognized_pipes;992 993 dev = p54_init_common(sizeof(*priv));994 995 if (!dev) {996 dev_err(&udev->dev, "(p54usb) ieee80211 alloc failed\n");997 return -ENOMEM;998 }999 1000 priv = dev->priv;1001 priv->hw_type = P54U_INVALID_HW;1002 1003 SET_IEEE80211_DEV(dev, &intf->dev);1004 usb_set_intfdata(intf, dev);1005 priv->udev = udev;1006 priv->intf = intf;1007 skb_queue_head_init(&priv->rx_queue);1008 init_usb_anchor(&priv->submitted);1009 1010 /* really lazy and simple way of figuring out if we're a 3887 */1011 /* TODO: should just stick the identification in the device table */1012 i = intf->altsetting->desc.bNumEndpoints;1013 recognized_pipes = 0;1014 while (i--) {1015 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {1016 case P54U_PIPE_DATA:1017 case P54U_PIPE_MGMT:1018 case P54U_PIPE_BRG:1019 case P54U_PIPE_DEV:1020 case P54U_PIPE_DATA | USB_DIR_IN:1021 case P54U_PIPE_MGMT | USB_DIR_IN:1022 case P54U_PIPE_BRG | USB_DIR_IN:1023 case P54U_PIPE_DEV | USB_DIR_IN:1024 case P54U_PIPE_INT | USB_DIR_IN:1025 recognized_pipes++;1026 }1027 }1028 priv->common.open = p54u_open;1029 priv->common.stop = p54u_stop;1030 if (recognized_pipes < P54U_PIPE_NUMBER) {1031#ifdef CONFIG_PM1032 /* ISL3887 needs a full reset on resume */1033 udev->reset_resume = 1;1034#endif /* CONFIG_PM */1035 err = p54u_device_reset(dev);1036 1037 priv->hw_type = P54U_3887;1038 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);1039 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);1040 priv->common.tx = p54u_tx_lm87;1041 priv->upload_fw = p54u_upload_firmware_3887;1042 } else {1043 priv->hw_type = P54U_NET2280;1044 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);1045 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);1046 priv->common.tx = p54u_tx_net2280;1047 priv->upload_fw = p54u_upload_firmware_net2280;1048 }1049 err = p54u_load_firmware(dev, intf);1050 if (err)1051 p54_free_common(dev);1052 return err;1053}1054 1055static void p54u_disconnect(struct usb_interface *intf)1056{1057 struct ieee80211_hw *dev = usb_get_intfdata(intf);1058 struct p54u_priv *priv;1059 1060 if (!dev)1061 return;1062 1063 priv = dev->priv;1064 wait_for_completion(&priv->fw_wait_load);1065 p54_unregister_common(dev);1066 1067 release_firmware(priv->fw);1068 p54_free_common(dev);1069}1070 1071static int p54u_pre_reset(struct usb_interface *intf)1072{1073 struct ieee80211_hw *dev = usb_get_intfdata(intf);1074 1075 if (!dev)1076 return -ENODEV;1077 1078 p54u_stop(dev);1079 return 0;1080}1081 1082static int p54u_resume(struct usb_interface *intf)1083{1084 struct ieee80211_hw *dev = usb_get_intfdata(intf);1085 struct p54u_priv *priv;1086 1087 if (!dev)1088 return -ENODEV;1089 1090 priv = dev->priv;1091 if (unlikely(!(priv->upload_fw && priv->fw)))1092 return 0;1093 1094 return priv->upload_fw(dev);1095}1096 1097static int p54u_post_reset(struct usb_interface *intf)1098{1099 struct ieee80211_hw *dev = usb_get_intfdata(intf);1100 struct p54u_priv *priv;1101 int err;1102 1103 err = p54u_resume(intf);1104 if (err)1105 return err;1106 1107 /* reinitialize old device state */1108 priv = dev->priv;1109 if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED)1110 ieee80211_restart_hw(dev);1111 1112 return 0;1113}1114 1115#ifdef CONFIG_PM1116 1117static int p54u_suspend(struct usb_interface *intf, pm_message_t message)1118{1119 return p54u_pre_reset(intf);1120}1121 1122#endif /* CONFIG_PM */1123 1124static struct usb_driver p54u_driver = {1125 .name = "p54usb",1126 .id_table = p54u_table,1127 .probe = p54u_probe,1128 .disconnect = p54u_disconnect,1129 .pre_reset = p54u_pre_reset,1130 .post_reset = p54u_post_reset,1131#ifdef CONFIG_PM1132 .suspend = p54u_suspend,1133 .resume = p54u_resume,1134 .reset_resume = p54u_resume,1135#endif /* CONFIG_PM */1136 .soft_unbind = 1,1137 .disable_hub_initiated_lpm = 1,1138};1139 1140module_usb_driver(p54u_driver);1141