1 /****************************************************************************** 2 * cxacru.c - driver for USB ADSL modems based on 3 * Conexant AccessRunner chipset 4 * 5 * Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan 6 * Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru) 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program; if not, write to the Free Software Foundation, Inc., 59 20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 * 22 ******************************************************************************/ 23 24 /* 25 * Credit is due for Josep Comas, who created the original patch to speedtch.c 26 * to support the different padding used by the AccessRunner (now generalized 27 * into usbatm), and the userspace firmware loading utility. 28 */ 29 30 #include <linux/module.h> 31 #include <linux/moduleparam.h> 32 #include <linux/kernel.h> 33 #include <linux/timer.h> 34 #include <linux/errno.h> 35 #include <linux/slab.h> 36 #include <linux/init.h> 37 #include <linux/device.h> /* FIXME: linux/firmware.h should include it itself */ 38 #include <linux/firmware.h> 39 #include <linux/mutex.h> 40 41 #include "usbatm.h" 42 43 #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands" 44 #define DRIVER_VERSION "0.2" 45 #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" 46 47 static const char cxacru_driver_name[] = "cxacru"; 48 49 #define CXACRU_EP_CMD 0x01 /* Bulk/interrupt in/out */ 50 #define CXACRU_EP_DATA 0x02 /* Bulk in/out */ 51 52 #define CMD_PACKET_SIZE 64 /* Should be maxpacket(ep)? */ 53 54 /* Addresses */ 55 #define PLLFCLK_ADDR 0x00350068 56 #define PLLBCLK_ADDR 0x0035006c 57 #define SDRAMEN_ADDR 0x00350010 58 #define FW_ADDR 0x00801000 59 #define BR_ADDR 0x00180600 60 #define SIG_ADDR 0x00180500 61 #define BR_STACK_ADDR 0x00187f10 62 63 /* Values */ 64 #define SDRAM_ENA 0x1 65 66 #define CMD_TIMEOUT 2000 /* msecs */ 67 #define POLL_INTERVAL 5000 /* msecs */ 68 69 /* commands for interaction with the modem through the control channel before 70 * firmware is loaded */ 71 enum cxacru_fw_request { 72 FW_CMD_ERR, 73 FW_GET_VER, 74 FW_READ_MEM, 75 FW_WRITE_MEM, 76 FW_RMW_MEM, 77 FW_CHECKSUM_MEM, 78 FW_GOTO_MEM, 79 }; 80 81 /* commands for interaction with the modem through the control channel once 82 * firmware is loaded */ 83 enum cxacru_cm_request { 84 CM_REQUEST_UNDEFINED = 0x80, 85 CM_REQUEST_TEST, 86 CM_REQUEST_CHIP_GET_MAC_ADDRESS, 87 CM_REQUEST_CHIP_GET_DP_VERSIONS, 88 CM_REQUEST_CHIP_ADSL_LINE_START, 89 CM_REQUEST_CHIP_ADSL_LINE_STOP, 90 CM_REQUEST_CHIP_ADSL_LINE_GET_STATUS, 91 CM_REQUEST_CHIP_ADSL_LINE_GET_SPEED, 92 CM_REQUEST_CARD_INFO_GET, 93 CM_REQUEST_CARD_DATA_GET, 94 CM_REQUEST_CARD_DATA_SET, 95 CM_REQUEST_COMMAND_HW_IO, 96 CM_REQUEST_INTERFACE_HW_IO, 97 CM_REQUEST_CARD_SERIAL_DATA_PATH_GET, 98 CM_REQUEST_CARD_SERIAL_DATA_PATH_SET, 99 CM_REQUEST_CARD_CONTROLLER_VERSION_GET, 100 CM_REQUEST_CARD_GET_STATUS, 101 CM_REQUEST_CARD_GET_MAC_ADDRESS, 102 CM_REQUEST_CARD_GET_DATA_LINK_STATUS, 103 CM_REQUEST_MAX, 104 }; 105 106 /* reply codes to the commands above */ 107 enum cxacru_cm_status { 108 CM_STATUS_UNDEFINED, 109 CM_STATUS_SUCCESS, 110 CM_STATUS_ERROR, 111 CM_STATUS_UNSUPPORTED, 112 CM_STATUS_UNIMPLEMENTED, 113 CM_STATUS_PARAMETER_ERROR, 114 CM_STATUS_DBG_LOOPBACK, 115 CM_STATUS_MAX, 116 }; 117 118 /* indices into CARD_INFO_GET return array */ 119 enum cxacru_info_idx { 120 CXINF_DOWNSTREAM_RATE, 121 CXINF_UPSTREAM_RATE, 122 CXINF_LINK_STATUS, 123 CXINF_LINE_STATUS, 124 CXINF_MAC_ADDRESS_HIGH, 125 CXINF_MAC_ADDRESS_LOW, 126 CXINF_UPSTREAM_SNR_MARGIN, 127 CXINF_DOWNSTREAM_SNR_MARGIN, 128 CXINF_UPSTREAM_ATTENUATION, 129 CXINF_DOWNSTREAM_ATTENUATION, 130 CXINF_TRANSMITTER_POWER, 131 CXINF_UPSTREAM_BITS_PER_FRAME, 132 CXINF_DOWNSTREAM_BITS_PER_FRAME, 133 CXINF_STARTUP_ATTEMPTS, 134 CXINF_UPSTREAM_CRC_ERRORS, 135 CXINF_DOWNSTREAM_CRC_ERRORS, 136 CXINF_UPSTREAM_FEC_ERRORS, 137 CXINF_DOWNSTREAM_FEC_ERRORS, 138 CXINF_UPSTREAM_HEC_ERRORS, 139 CXINF_DOWNSTREAM_HEC_ERRORS, 140 CXINF_LINE_STARTABLE, 141 CXINF_MODULATION, 142 CXINF_ADSL_HEADEND, 143 CXINF_ADSL_HEADEND_ENVIRONMENT, 144 CXINF_CONTROLLER_VERSION, 145 /* dunno what the missing two mean */ 146 CXINF_MAX = 0x1c, 147 }; 148 149 struct cxacru_modem_type { 150 u32 pll_f_clk; 151 u32 pll_b_clk; 152 int boot_rom_patch; 153 }; 154 155 struct cxacru_data { 156 struct usbatm_data *usbatm; 157 158 const struct cxacru_modem_type *modem_type; 159 160 int line_status; 161 struct delayed_work poll_work; 162 163 /* contol handles */ 164 struct mutex cm_serialize; 165 u8 *rcv_buf; 166 u8 *snd_buf; 167 struct urb *rcv_urb; 168 struct urb *snd_urb; 169 struct completion rcv_done; 170 struct completion snd_done; 171 }; 172 173 /* the following three functions are stolen from drivers/usb/core/message.c */ 174 static void cxacru_blocking_completion(struct urb *urb) 175 { 176 complete((struct completion *)urb->context); 177 } 178 179 static void cxacru_timeout_kill(unsigned long data) 180 { 181 usb_unlink_urb((struct urb *) data); 182 } 183 184 static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, 185 int* actual_length) 186 { 187 struct timer_list timer; 188 int status; 189 190 init_timer(&timer); 191 timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); 192 timer.data = (unsigned long) urb; 193 timer.function = cxacru_timeout_kill; 194 add_timer(&timer); 195 wait_for_completion(done); 196 status = urb->status; 197 if (status == -ECONNRESET) 198 status = -ETIMEDOUT; 199 del_timer_sync(&timer); 200 201 if (actual_length) 202 *actual_length = urb->actual_length; 203 return status; 204 } 205 206 static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, 207 u8 *wdata, int wsize, u8 *rdata, int rsize) 208 { 209 int ret, actlen; 210 int offb, offd; 211 const int stride = CMD_PACKET_SIZE - 4; 212 u8 *wbuf = instance->snd_buf; 213 u8 *rbuf = instance->rcv_buf; 214 int wbuflen = ((wsize - 1) / stride + 1) * CMD_PACKET_SIZE; 215 int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE; 216 217 if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) { 218 dbg("too big transfer requested"); 219 ret = -ENOMEM; 220 goto fail; 221 } 222 223 mutex_lock(&instance->cm_serialize); 224 225 /* submit reading urb before the writing one */ 226 init_completion(&instance->rcv_done); 227 ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL); 228 if (ret < 0) { 229 dbg("submitting read urb for cm %#x failed", cm); 230 ret = ret; 231 goto fail; 232 } 233 234 memset(wbuf, 0, wbuflen); 235 /* handle wsize == 0 */ 236 wbuf[0] = cm; 237 for (offb = offd = 0; offd < wsize; offd += stride, offb += CMD_PACKET_SIZE) { 238 wbuf[offb] = cm; 239 memcpy(wbuf + offb + 4, wdata + offd, min_t(int, stride, wsize - offd)); 240 } 241 242 instance->snd_urb->transfer_buffer_length = wbuflen; 243 init_completion(&instance->snd_done); 244 ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL); 245 if (ret < 0) { 246 dbg("submitting write urb for cm %#x failed", cm); 247 ret = ret; 248 goto fail; 249 } 250 251 ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL); 252 if (ret < 0) { 253 dbg("sending cm %#x failed", cm); 254 ret = ret; 255 goto fail; 256 } 257 258 ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen); 259 if (ret < 0) { 260 dbg("receiving cm %#x failed", cm); 261 ret = ret; 262 goto fail; 263 } 264 if (actlen % CMD_PACKET_SIZE || !actlen) { 265 dbg("response is not a positive multiple of %d: %#x", 266 CMD_PACKET_SIZE, actlen); 267 ret = -EIO; 268 goto fail; 269 } 270 271 /* check the return status and copy the data to the output buffer, if needed */ 272 for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) { 273 if (rbuf[offb] != cm) { 274 dbg("wrong cm %#x in response", rbuf[offb]); 275 ret = -EIO; 276 goto fail; 277 } 278 if (rbuf[offb + 1] != CM_STATUS_SUCCESS) { 279 dbg("response failed: %#x", rbuf[offb + 1]); 280 ret = -EIO; 281 goto fail; 282 } 283 if (offd >= rsize) 284 break; 285 memcpy(rdata + offd, rbuf + offb + 4, min_t(int, stride, rsize - offd)); 286 offd += stride; 287 } 288 289 ret = offd; 290 dbg("cm %#x", cm); 291 fail: 292 mutex_unlock(&instance->cm_serialize); 293 return ret; 294 } 295 296 static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_request cm, 297 u32 *data, int size) 298 { 299 int ret, len; 300 u32 *buf; 301 int offb, offd; 302 const int stride = CMD_PACKET_SIZE / (4 * 2) - 1; 303 int buflen = ((size - 1) / stride + 1 + size * 2) * 4; 304 305 buf = kmalloc(buflen, GFP_KERNEL); 306 if (!buf) 307 return -ENOMEM; 308 309 ret = cxacru_cm(instance, cm, NULL, 0, (u8 *) buf, buflen); 310 if (ret < 0) 311 goto cleanup; 312 313 /* len > 0 && len % 4 == 0 guaranteed by cxacru_cm() */ 314 len = ret / 4; 315 for (offb = 0; offb < len; ) { 316 int l = le32_to_cpu(buf[offb++]); 317 if (l > stride || l > (len - offb) / 2) { 318 dbg("wrong data length %#x in response", l); 319 ret = -EIO; 320 goto cleanup; 321 } 322 while (l--) { 323 offd = le32_to_cpu(buf[offb++]); 324 if (offd >= size) { 325 dbg("wrong index %#x in response", offd); 326 ret = -EIO; 327 goto cleanup; 328 } 329 data[offd] = le32_to_cpu(buf[offb++]); 330 } 331 } 332 333 ret = 0; 334 335 cleanup: 336 kfree(buf); 337 return ret; 338 } 339 340 static int cxacru_card_status(struct cxacru_data *instance) 341 { 342 int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); 343 if (ret < 0) { /* firmware not loaded */ 344 dbg("cxacru_adsl_start: CARD_GET_STATUS returned %d", ret); 345 return ret; 346 } 347 return 0; 348 } 349 350 static void cxacru_poll_status(struct work_struct *work); 351 352 static int cxacru_atm_start(struct usbatm_data *usbatm_instance, 353 struct atm_dev *atm_dev) 354 { 355 struct cxacru_data *instance = usbatm_instance->driver_data; 356 /* 357 struct atm_dev *atm_dev = usbatm_instance->atm_dev; 358 */ 359 int ret; 360 361 dbg("cxacru_atm_start"); 362 363 /* Read MAC address */ 364 ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0, 365 atm_dev->esi, sizeof(atm_dev->esi)); 366 if (ret < 0) { 367 atm_err(usbatm_instance, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret); 368 return ret; 369 } 370 371 /* start ADSL */ 372 ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); 373 if (ret < 0) { 374 atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret); 375 return ret; 376 } 377 378 /* Start status polling */ 379 cxacru_poll_status(&instance->poll_work.work); 380 return 0; 381 } 382 383 static void cxacru_poll_status(struct work_struct *work) 384 { 385 struct cxacru_data *instance = 386 container_of(work, struct cxacru_data, poll_work.work); 387 u32 buf[CXINF_MAX] = {}; 388 struct usbatm_data *usbatm = instance->usbatm; 389 struct atm_dev *atm_dev = usbatm->atm_dev; 390 int ret; 391 392 ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX); 393 if (ret < 0) { 394 atm_warn(usbatm, "poll status: error %d\n", ret); 395 goto reschedule; 396 } 397 398 if (instance->line_status == buf[CXINF_LINE_STATUS]) 399 goto reschedule; 400 401 instance->line_status = buf[CXINF_LINE_STATUS]; 402 switch (instance->line_status) { 403 case 0: 404 atm_dev->signal = ATM_PHY_SIG_LOST; 405 atm_info(usbatm, "ADSL line: down\n"); 406 break; 407 408 case 1: 409 atm_dev->signal = ATM_PHY_SIG_LOST; 410 atm_info(usbatm, "ADSL line: attempting to activate\n"); 411 break; 412 413 case 2: 414 atm_dev->signal = ATM_PHY_SIG_LOST; 415 atm_info(usbatm, "ADSL line: training\n"); 416 break; 417 418 case 3: 419 atm_dev->signal = ATM_PHY_SIG_LOST; 420 atm_info(usbatm, "ADSL line: channel analysis\n"); 421 break; 422 423 case 4: 424 atm_dev->signal = ATM_PHY_SIG_LOST; 425 atm_info(usbatm, "ADSL line: exchange\n"); 426 break; 427 428 case 5: 429 atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; 430 atm_dev->signal = ATM_PHY_SIG_FOUND; 431 432 atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n", 433 buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]); 434 break; 435 436 case 6: 437 atm_dev->signal = ATM_PHY_SIG_LOST; 438 atm_info(usbatm, "ADSL line: waiting\n"); 439 break; 440 441 case 7: 442 atm_dev->signal = ATM_PHY_SIG_LOST; 443 atm_info(usbatm, "ADSL line: initializing\n"); 444 break; 445 446 default: 447 atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 448 atm_info(usbatm, "Unknown line state %02x\n", instance->line_status); 449 break; 450 } 451 reschedule: 452 schedule_delayed_work(&instance->poll_work, msecs_to_jiffies(POLL_INTERVAL)); 453 } 454 455 static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw, 456 u8 code1, u8 code2, u32 addr, u8 *data, int size) 457 { 458 int ret; 459 u8 *buf; 460 int offd, offb; 461 const int stride = CMD_PACKET_SIZE - 8; 462 463 buf = (u8 *) __get_free_page(GFP_KERNEL); 464 if (!buf) 465 return -ENOMEM; 466 467 offb = offd = 0; 468 do { 469 int l = min_t(int, stride, size - offd); 470 buf[offb++] = fw; 471 buf[offb++] = l; 472 buf[offb++] = code1; 473 buf[offb++] = code2; 474 *((u32 *) (buf + offb)) = cpu_to_le32(addr); 475 offb += 4; 476 addr += l; 477 if(l) 478 memcpy(buf + offb, data + offd, l); 479 if (l < stride) 480 memset(buf + offb + l, 0, stride - l); 481 offb += stride; 482 offd += stride; 483 if ((offb >= PAGE_SIZE) || (offd >= size)) { 484 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD), 485 buf, offb, NULL, CMD_TIMEOUT); 486 if (ret < 0) { 487 dbg("sending fw %#x failed", fw); 488 goto cleanup; 489 } 490 offb = 0; 491 } 492 } while(offd < size); 493 dbg("sent fw %#x", fw); 494 495 ret = 0; 496 497 cleanup: 498 free_page((unsigned long) buf); 499 return ret; 500 } 501 502 static void cxacru_upload_firmware(struct cxacru_data *instance, 503 const struct firmware *fw, 504 const struct firmware *bp, 505 const struct firmware *cf) 506 { 507 int ret; 508 int off; 509 struct usbatm_data *usbatm = instance->usbatm; 510 struct usb_device *usb_dev = usbatm->usb_dev; 511 u16 signature[] = { usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct }; 512 u32 val; 513 514 dbg("cxacru_upload_firmware"); 515 516 /* FirmwarePllFClkValue */ 517 val = cpu_to_le32(instance->modem_type->pll_f_clk); 518 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4); 519 if (ret) { 520 usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret); 521 return; 522 } 523 524 /* FirmwarePllBClkValue */ 525 val = cpu_to_le32(instance->modem_type->pll_b_clk); 526 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4); 527 if (ret) { 528 usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret); 529 return; 530 } 531 532 /* Enable SDRAM */ 533 val = cpu_to_le32(SDRAM_ENA); 534 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4); 535 if (ret) { 536 usb_err(usbatm, "Enable SDRAM failed: %d\n", ret); 537 return; 538 } 539 540 /* Firmware */ 541 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); 542 if (ret) { 543 usb_err(usbatm, "Firmware upload failed: %d\n", ret); 544 return; 545 } 546 547 /* Boot ROM patch */ 548 if (instance->modem_type->boot_rom_patch) { 549 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); 550 if (ret) { 551 usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); 552 return; 553 } 554 } 555 556 /* Signature */ 557 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4); 558 if (ret) { 559 usb_err(usbatm, "Signature storing failed: %d\n", ret); 560 return; 561 } 562 563 if (instance->modem_type->boot_rom_patch) { 564 val = cpu_to_le32(BR_ADDR); 565 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); 566 } 567 else { 568 ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0); 569 } 570 if (ret) { 571 usb_err(usbatm, "Passing control to firmware failed: %d\n", ret); 572 return; 573 } 574 575 /* Delay to allow firmware to start up. */ 576 msleep_interruptible(1000); 577 578 usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD)); 579 usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD)); 580 usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA)); 581 usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA)); 582 583 ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); 584 if (ret < 0) { 585 usb_err(usbatm, "modem failed to initialize: %d\n", ret); 586 return; 587 } 588 589 /* Load config data (le32), doing one packet at a time */ 590 if (cf) 591 for (off = 0; off < cf->size / 4; ) { 592 u32 buf[CMD_PACKET_SIZE / 4 - 1]; 593 int i, len = min_t(int, cf->size / 4 - off, CMD_PACKET_SIZE / 4 / 2 - 1); 594 buf[0] = cpu_to_le32(len); 595 for (i = 0; i < len; i++, off++) { 596 buf[i * 2 + 1] = cpu_to_le32(off); 597 memcpy(buf + i * 2 + 2, cf->data + off * 4, 4); 598 } 599 ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET, 600 (u8 *) buf, len, NULL, 0); 601 if (ret < 0) { 602 usb_err(usbatm, "load config data failed: %d\n", ret); 603 return; 604 } 605 } 606 607 msleep_interruptible(4000); 608 } 609 610 static int cxacru_find_firmware(struct cxacru_data *instance, 611 char* phase, const struct firmware **fw_p) 612 { 613 struct usbatm_data *usbatm = instance->usbatm; 614 struct device *dev = &usbatm->usb_intf->dev; 615 char buf[16]; 616 617 sprintf(buf, "cxacru-%s.bin", phase); 618 dbg("cxacru_find_firmware: looking for %s", buf); 619 620 if (request_firmware(fw_p, buf, dev)) { 621 usb_dbg(usbatm, "no stage %s firmware found\n", phase); 622 return -ENOENT; 623 } 624 625 usb_info(usbatm, "found firmware %s\n", buf); 626 627 return 0; 628 } 629 630 static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, 631 struct usb_interface *usb_intf) 632 { 633 const struct firmware *fw, *bp, *cf; 634 struct cxacru_data *instance = usbatm_instance->driver_data; 635 636 int ret = cxacru_find_firmware(instance, "fw", &fw); 637 if (ret) { 638 usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n"); 639 return ret; 640 } 641 642 if (instance->modem_type->boot_rom_patch) { 643 ret = cxacru_find_firmware(instance, "bp", &bp); 644 if (ret) { 645 usb_warn(usbatm_instance, "boot ROM patch (cxacru-bp.bin) unavailable (system misconfigured?)\n"); 646 release_firmware(fw); 647 return ret; 648 } 649 } 650 651 if (cxacru_find_firmware(instance, "cf", &cf)) /* optional */ 652 cf = NULL; 653 654 cxacru_upload_firmware(instance, fw, bp, cf); 655 656 if (cf) 657 release_firmware(cf); 658 if (instance->modem_type->boot_rom_patch) 659 release_firmware(bp); 660 release_firmware(fw); 661 662 ret = cxacru_card_status(instance); 663 if (ret) 664 dbg("modem initialisation failed"); 665 else 666 dbg("done setting up the modem"); 667 668 return ret; 669 } 670 671 static int cxacru_bind(struct usbatm_data *usbatm_instance, 672 struct usb_interface *intf, const struct usb_device_id *id) 673 { 674 struct cxacru_data *instance; 675 struct usb_device *usb_dev = interface_to_usbdev(intf); 676 int ret; 677 678 /* instance init */ 679 instance = kzalloc(sizeof(*instance), GFP_KERNEL); 680 if (!instance) { 681 dbg("cxacru_bind: no memory for instance data"); 682 return -ENOMEM; 683 } 684 685 instance->usbatm = usbatm_instance; 686 instance->modem_type = (struct cxacru_modem_type *) id->driver_info; 687 688 instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); 689 if (!instance->rcv_buf) { 690 dbg("cxacru_bind: no memory for rcv_buf"); 691 ret = -ENOMEM; 692 goto fail; 693 } 694 instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL); 695 if (!instance->snd_buf) { 696 dbg("cxacru_bind: no memory for snd_buf"); 697 ret = -ENOMEM; 698 goto fail; 699 } 700 instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL); 701 if (!instance->rcv_urb) { 702 dbg("cxacru_bind: no memory for rcv_urb"); 703 ret = -ENOMEM; 704 goto fail; 705 } 706 instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL); 707 if (!instance->snd_urb) { 708 dbg("cxacru_bind: no memory for snd_urb"); 709 ret = -ENOMEM; 710 goto fail; 711 } 712 713 usb_fill_int_urb(instance->rcv_urb, 714 usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), 715 instance->rcv_buf, PAGE_SIZE, 716 cxacru_blocking_completion, &instance->rcv_done, 1); 717 718 usb_fill_int_urb(instance->snd_urb, 719 usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), 720 instance->snd_buf, PAGE_SIZE, 721 cxacru_blocking_completion, &instance->snd_done, 4); 722 723 mutex_init(&instance->cm_serialize); 724 725 INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status); 726 727 usbatm_instance->driver_data = instance; 728 729 usbatm_instance->flags = (cxacru_card_status(instance) ? 0 : UDSL_SKIP_HEAVY_INIT); 730 731 return 0; 732 733 fail: 734 free_page((unsigned long) instance->snd_buf); 735 free_page((unsigned long) instance->rcv_buf); 736 usb_free_urb(instance->snd_urb); 737 usb_free_urb(instance->rcv_urb); 738 kfree(instance); 739 740 return ret; 741 } 742 743 static void cxacru_unbind(struct usbatm_data *usbatm_instance, 744 struct usb_interface *intf) 745 { 746 struct cxacru_data *instance = usbatm_instance->driver_data; 747 748 dbg("cxacru_unbind entered"); 749 750 if (!instance) { 751 dbg("cxacru_unbind: NULL instance!"); 752 return; 753 } 754 755 while (!cancel_delayed_work(&instance->poll_work)) 756 flush_scheduled_work(); 757 758 usb_kill_urb(instance->snd_urb); 759 usb_kill_urb(instance->rcv_urb); 760 usb_free_urb(instance->snd_urb); 761 usb_free_urb(instance->rcv_urb); 762 763 free_page((unsigned long) instance->snd_buf); 764 free_page((unsigned long) instance->rcv_buf); 765 kfree(instance); 766 767 usbatm_instance->driver_data = NULL; 768 } 769 770 static const struct cxacru_modem_type cxacru_cafe = { 771 .pll_f_clk = 0x02d874df, 772 .pll_b_clk = 0x0196a51a, 773 .boot_rom_patch = 1, 774 }; 775 776 static const struct cxacru_modem_type cxacru_cb00 = { 777 .pll_f_clk = 0x5, 778 .pll_b_clk = 0x3, 779 .boot_rom_patch = 0, 780 }; 781 782 static const struct usb_device_id cxacru_usb_ids[] = { 783 { /* V = Conexant P = ADSL modem (Euphrates project) */ 784 USB_DEVICE(0x0572, 0xcafe), .driver_info = (unsigned long) &cxacru_cafe 785 }, 786 { /* V = Conexant P = ADSL modem (Hasbani project) */ 787 USB_DEVICE(0x0572, 0xcb00), .driver_info = (unsigned long) &cxacru_cb00 788 }, 789 { /* V = Conexant P = ADSL modem */ 790 USB_DEVICE(0x0572, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 791 }, 792 { /* V = Conexant P = ADSL modem (Well PTI-800) */ 793 USB_DEVICE(0x0572, 0xcb02), .driver_info = (unsigned long) &cxacru_cb00 794 }, 795 { /* V = Conexant P = ADSL modem */ 796 USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00 797 }, 798 { /* V = Conexant P = ADSL modem (ZTE ZXDSL 852) */ 799 USB_DEVICE(0x0572, 0xcb07), .driver_info = (unsigned long) &cxacru_cb00 800 }, 801 { /* V = Olitec P = ADSL modem version 2 */ 802 USB_DEVICE(0x08e3, 0x0100), .driver_info = (unsigned long) &cxacru_cafe 803 }, 804 { /* V = Olitec P = ADSL modem version 3 */ 805 USB_DEVICE(0x08e3, 0x0102), .driver_info = (unsigned long) &cxacru_cb00 806 }, 807 { /* V = Trust/Amigo Technology Co. P = AMX-CA86U */ 808 USB_DEVICE(0x0eb0, 0x3457), .driver_info = (unsigned long) &cxacru_cafe 809 }, 810 { /* V = Zoom P = 5510 */ 811 USB_DEVICE(0x1803, 0x5510), .driver_info = (unsigned long) &cxacru_cb00 812 }, 813 { /* V = Draytek P = Vigor 318 */ 814 USB_DEVICE(0x0675, 0x0200), .driver_info = (unsigned long) &cxacru_cb00 815 }, 816 { /* V = Zyxel P = 630-C1 aka OMNI ADSL USB (Annex A) */ 817 USB_DEVICE(0x0586, 0x330a), .driver_info = (unsigned long) &cxacru_cb00 818 }, 819 { /* V = Zyxel P = 630-C3 aka OMNI ADSL USB (Annex B) */ 820 USB_DEVICE(0x0586, 0x330b), .driver_info = (unsigned long) &cxacru_cb00 821 }, 822 { /* V = Aethra P = Starmodem UM1020 */ 823 USB_DEVICE(0x0659, 0x0020), .driver_info = (unsigned long) &cxacru_cb00 824 }, 825 { /* V = Aztech Systems P = ? AKA Pirelli AUA-010 */ 826 USB_DEVICE(0x0509, 0x0812), .driver_info = (unsigned long) &cxacru_cb00 827 }, 828 { /* V = Netopia P = Cayman 3341(Annex A)/3351(Annex B) */ 829 USB_DEVICE(0x100d, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 830 }, 831 { /* V = Netopia P = Cayman 3342(Annex A)/3352(Annex B) */ 832 USB_DEVICE(0x100d, 0x3342), .driver_info = (unsigned long) &cxacru_cb00 833 }, 834 {} 835 }; 836 837 MODULE_DEVICE_TABLE(usb, cxacru_usb_ids); 838 839 static struct usbatm_driver cxacru_driver = { 840 .driver_name = cxacru_driver_name, 841 .bind = cxacru_bind, 842 .heavy_init = cxacru_heavy_init, 843 .unbind = cxacru_unbind, 844 .atm_start = cxacru_atm_start, 845 .bulk_in = CXACRU_EP_DATA, 846 .bulk_out = CXACRU_EP_DATA, 847 .rx_padding = 3, 848 .tx_padding = 11, 849 }; 850 851 static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) 852 { 853 return usbatm_usb_probe(intf, id, &cxacru_driver); 854 } 855 856 static struct usb_driver cxacru_usb_driver = { 857 .name = cxacru_driver_name, 858 .probe = cxacru_usb_probe, 859 .disconnect = usbatm_usb_disconnect, 860 .id_table = cxacru_usb_ids 861 }; 862 863 static int __init cxacru_init(void) 864 { 865 return usb_register(&cxacru_usb_driver); 866 } 867 868 static void __exit cxacru_cleanup(void) 869 { 870 usb_deregister(&cxacru_usb_driver); 871 } 872 873 module_init(cxacru_init); 874 module_exit(cxacru_cleanup); 875 876 MODULE_AUTHOR(DRIVER_AUTHOR); 877 MODULE_DESCRIPTION(DRIVER_DESC); 878 MODULE_LICENSE("GPL"); 879 MODULE_VERSION(DRIVER_VERSION); 880