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 work_struct 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, struct pt_regs *regs) 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 cxacru_data *instance); 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); 380 return 0; 381 } 382 383 static void cxacru_poll_status(struct cxacru_data *instance) 384 { 385 u32 buf[CXINF_MAX] = {}; 386 struct usbatm_data *usbatm = instance->usbatm; 387 struct atm_dev *atm_dev = usbatm->atm_dev; 388 int ret; 389 390 ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX); 391 if (ret < 0) { 392 atm_warn(usbatm, "poll status: error %d\n", ret); 393 goto reschedule; 394 } 395 396 if (instance->line_status == buf[CXINF_LINE_STATUS]) 397 goto reschedule; 398 399 instance->line_status = buf[CXINF_LINE_STATUS]; 400 switch (instance->line_status) { 401 case 0: 402 atm_dev->signal = ATM_PHY_SIG_LOST; 403 atm_info(usbatm, "ADSL line: down\n"); 404 break; 405 406 case 1: 407 atm_dev->signal = ATM_PHY_SIG_LOST; 408 atm_info(usbatm, "ADSL line: attempting to activate\n"); 409 break; 410 411 case 2: 412 atm_dev->signal = ATM_PHY_SIG_LOST; 413 atm_info(usbatm, "ADSL line: training\n"); 414 break; 415 416 case 3: 417 atm_dev->signal = ATM_PHY_SIG_LOST; 418 atm_info(usbatm, "ADSL line: channel analysis\n"); 419 break; 420 421 case 4: 422 atm_dev->signal = ATM_PHY_SIG_LOST; 423 atm_info(usbatm, "ADSL line: exchange\n"); 424 break; 425 426 case 5: 427 atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; 428 atm_dev->signal = ATM_PHY_SIG_FOUND; 429 430 atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n", 431 buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]); 432 break; 433 434 case 6: 435 atm_dev->signal = ATM_PHY_SIG_LOST; 436 atm_info(usbatm, "ADSL line: waiting\n"); 437 break; 438 439 case 7: 440 atm_dev->signal = ATM_PHY_SIG_LOST; 441 atm_info(usbatm, "ADSL line: initializing\n"); 442 break; 443 444 default: 445 atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 446 atm_info(usbatm, "Unknown line state %02x\n", instance->line_status); 447 break; 448 } 449 reschedule: 450 schedule_delayed_work(&instance->poll_work, msecs_to_jiffies(POLL_INTERVAL)); 451 } 452 453 static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw, 454 u8 code1, u8 code2, u32 addr, u8 *data, int size) 455 { 456 int ret; 457 u8 *buf; 458 int offd, offb; 459 const int stride = CMD_PACKET_SIZE - 8; 460 461 buf = (u8 *) __get_free_page(GFP_KERNEL); 462 if (!buf) 463 return -ENOMEM; 464 465 offb = offd = 0; 466 do { 467 int l = min_t(int, stride, size - offd); 468 buf[offb++] = fw; 469 buf[offb++] = l; 470 buf[offb++] = code1; 471 buf[offb++] = code2; 472 *((u32 *) (buf + offb)) = cpu_to_le32(addr); 473 offb += 4; 474 addr += l; 475 if(l) 476 memcpy(buf + offb, data + offd, l); 477 if (l < stride) 478 memset(buf + offb + l, 0, stride - l); 479 offb += stride; 480 offd += stride; 481 if ((offb >= PAGE_SIZE) || (offd >= size)) { 482 ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD), 483 buf, offb, NULL, CMD_TIMEOUT); 484 if (ret < 0) { 485 dbg("sending fw %#x failed", fw); 486 goto cleanup; 487 } 488 offb = 0; 489 } 490 } while(offd < size); 491 dbg("sent fw %#x", fw); 492 493 ret = 0; 494 495 cleanup: 496 free_page((unsigned long) buf); 497 return ret; 498 } 499 500 static void cxacru_upload_firmware(struct cxacru_data *instance, 501 const struct firmware *fw, 502 const struct firmware *bp, 503 const struct firmware *cf) 504 { 505 int ret; 506 int off; 507 struct usbatm_data *usbatm = instance->usbatm; 508 struct usb_device *usb_dev = usbatm->usb_dev; 509 u16 signature[] = { usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct }; 510 u32 val; 511 512 dbg("cxacru_upload_firmware"); 513 514 /* FirmwarePllFClkValue */ 515 val = cpu_to_le32(instance->modem_type->pll_f_clk); 516 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4); 517 if (ret) { 518 usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret); 519 return; 520 } 521 522 /* FirmwarePllBClkValue */ 523 val = cpu_to_le32(instance->modem_type->pll_b_clk); 524 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4); 525 if (ret) { 526 usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret); 527 return; 528 } 529 530 /* Enable SDRAM */ 531 val = cpu_to_le32(SDRAM_ENA); 532 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4); 533 if (ret) { 534 usb_err(usbatm, "Enable SDRAM failed: %d\n", ret); 535 return; 536 } 537 538 /* Firmware */ 539 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); 540 if (ret) { 541 usb_err(usbatm, "Firmware upload failed: %d\n", ret); 542 return; 543 } 544 545 /* Boot ROM patch */ 546 if (instance->modem_type->boot_rom_patch) { 547 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); 548 if (ret) { 549 usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); 550 return; 551 } 552 } 553 554 /* Signature */ 555 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4); 556 if (ret) { 557 usb_err(usbatm, "Signature storing failed: %d\n", ret); 558 return; 559 } 560 561 if (instance->modem_type->boot_rom_patch) { 562 val = cpu_to_le32(BR_ADDR); 563 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); 564 } 565 else { 566 ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0); 567 } 568 if (ret) { 569 usb_err(usbatm, "Passing control to firmware failed: %d\n", ret); 570 return; 571 } 572 573 /* Delay to allow firmware to start up. */ 574 msleep_interruptible(1000); 575 576 usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD)); 577 usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD)); 578 usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA)); 579 usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA)); 580 581 ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); 582 if (ret < 0) { 583 usb_err(usbatm, "modem failed to initialize: %d\n", ret); 584 return; 585 } 586 587 /* Load config data (le32), doing one packet at a time */ 588 if (cf) 589 for (off = 0; off < cf->size / 4; ) { 590 u32 buf[CMD_PACKET_SIZE / 4 - 1]; 591 int i, len = min_t(int, cf->size / 4 - off, CMD_PACKET_SIZE / 4 / 2 - 1); 592 buf[0] = cpu_to_le32(len); 593 for (i = 0; i < len; i++, off++) { 594 buf[i * 2 + 1] = cpu_to_le32(off); 595 memcpy(buf + i * 2 + 2, cf->data + off * 4, 4); 596 } 597 ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET, 598 (u8 *) buf, len, NULL, 0); 599 if (ret < 0) { 600 usb_err(usbatm, "load config data failed: %d\n", ret); 601 return; 602 } 603 } 604 605 msleep_interruptible(4000); 606 } 607 608 static int cxacru_find_firmware(struct cxacru_data *instance, 609 char* phase, const struct firmware **fw_p) 610 { 611 struct usbatm_data *usbatm = instance->usbatm; 612 struct device *dev = &usbatm->usb_intf->dev; 613 char buf[16]; 614 615 sprintf(buf, "cxacru-%s.bin", phase); 616 dbg("cxacru_find_firmware: looking for %s", buf); 617 618 if (request_firmware(fw_p, buf, dev)) { 619 usb_dbg(usbatm, "no stage %s firmware found\n", phase); 620 return -ENOENT; 621 } 622 623 usb_info(usbatm, "found firmware %s\n", buf); 624 625 return 0; 626 } 627 628 static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, 629 struct usb_interface *usb_intf) 630 { 631 const struct firmware *fw, *bp, *cf; 632 struct cxacru_data *instance = usbatm_instance->driver_data; 633 634 int ret = cxacru_find_firmware(instance, "fw", &fw); 635 if (ret) { 636 usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n"); 637 return ret; 638 } 639 640 if (instance->modem_type->boot_rom_patch) { 641 ret = cxacru_find_firmware(instance, "bp", &bp); 642 if (ret) { 643 usb_warn(usbatm_instance, "boot ROM patch (cxacru-bp.bin) unavailable (system misconfigured?)\n"); 644 release_firmware(fw); 645 return ret; 646 } 647 } 648 649 if (cxacru_find_firmware(instance, "cf", &cf)) /* optional */ 650 cf = NULL; 651 652 cxacru_upload_firmware(instance, fw, bp, cf); 653 654 if (cf) 655 release_firmware(cf); 656 if (instance->modem_type->boot_rom_patch) 657 release_firmware(bp); 658 release_firmware(fw); 659 660 ret = cxacru_card_status(instance); 661 if (ret) 662 dbg("modem initialisation failed"); 663 else 664 dbg("done setting up the modem"); 665 666 return ret; 667 } 668 669 static int cxacru_bind(struct usbatm_data *usbatm_instance, 670 struct usb_interface *intf, const struct usb_device_id *id) 671 { 672 struct cxacru_data *instance; 673 struct usb_device *usb_dev = interface_to_usbdev(intf); 674 int ret; 675 676 /* instance init */ 677 instance = kzalloc(sizeof(*instance), GFP_KERNEL); 678 if (!instance) { 679 dbg("cxacru_bind: no memory for instance data"); 680 return -ENOMEM; 681 } 682 683 instance->usbatm = usbatm_instance; 684 instance->modem_type = (struct cxacru_modem_type *) id->driver_info; 685 686 instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); 687 if (!instance->rcv_buf) { 688 dbg("cxacru_bind: no memory for rcv_buf"); 689 ret = -ENOMEM; 690 goto fail; 691 } 692 instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL); 693 if (!instance->snd_buf) { 694 dbg("cxacru_bind: no memory for snd_buf"); 695 ret = -ENOMEM; 696 goto fail; 697 } 698 instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL); 699 if (!instance->rcv_urb) { 700 dbg("cxacru_bind: no memory for rcv_urb"); 701 ret = -ENOMEM; 702 goto fail; 703 } 704 instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL); 705 if (!instance->snd_urb) { 706 dbg("cxacru_bind: no memory for snd_urb"); 707 ret = -ENOMEM; 708 goto fail; 709 } 710 711 usb_fill_int_urb(instance->rcv_urb, 712 usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), 713 instance->rcv_buf, PAGE_SIZE, 714 cxacru_blocking_completion, &instance->rcv_done, 1); 715 716 usb_fill_int_urb(instance->snd_urb, 717 usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), 718 instance->snd_buf, PAGE_SIZE, 719 cxacru_blocking_completion, &instance->snd_done, 4); 720 721 mutex_init(&instance->cm_serialize); 722 723 INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance); 724 725 usbatm_instance->driver_data = instance; 726 727 usbatm_instance->flags = (cxacru_card_status(instance) ? 0 : UDSL_SKIP_HEAVY_INIT); 728 729 return 0; 730 731 fail: 732 free_page((unsigned long) instance->snd_buf); 733 free_page((unsigned long) instance->rcv_buf); 734 usb_free_urb(instance->snd_urb); 735 usb_free_urb(instance->rcv_urb); 736 kfree(instance); 737 738 return ret; 739 } 740 741 static void cxacru_unbind(struct usbatm_data *usbatm_instance, 742 struct usb_interface *intf) 743 { 744 struct cxacru_data *instance = usbatm_instance->driver_data; 745 746 dbg("cxacru_unbind entered"); 747 748 if (!instance) { 749 dbg("cxacru_unbind: NULL instance!"); 750 return; 751 } 752 753 while (!cancel_delayed_work(&instance->poll_work)) 754 flush_scheduled_work(); 755 756 usb_kill_urb(instance->snd_urb); 757 usb_kill_urb(instance->rcv_urb); 758 usb_free_urb(instance->snd_urb); 759 usb_free_urb(instance->rcv_urb); 760 761 free_page((unsigned long) instance->snd_buf); 762 free_page((unsigned long) instance->rcv_buf); 763 kfree(instance); 764 765 usbatm_instance->driver_data = NULL; 766 } 767 768 static const struct cxacru_modem_type cxacru_cafe = { 769 .pll_f_clk = 0x02d874df, 770 .pll_b_clk = 0x0196a51a, 771 .boot_rom_patch = 1, 772 }; 773 774 static const struct cxacru_modem_type cxacru_cb00 = { 775 .pll_f_clk = 0x5, 776 .pll_b_clk = 0x3, 777 .boot_rom_patch = 0, 778 }; 779 780 static const struct usb_device_id cxacru_usb_ids[] = { 781 { /* V = Conexant P = ADSL modem (Euphrates project) */ 782 USB_DEVICE(0x0572, 0xcafe), .driver_info = (unsigned long) &cxacru_cafe 783 }, 784 { /* V = Conexant P = ADSL modem (Hasbani project) */ 785 USB_DEVICE(0x0572, 0xcb00), .driver_info = (unsigned long) &cxacru_cb00 786 }, 787 { /* V = Conexant P = ADSL modem */ 788 USB_DEVICE(0x0572, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 789 }, 790 { /* V = Conexant P = ADSL modem (Well PTI-800) */ 791 USB_DEVICE(0x0572, 0xcb02), .driver_info = (unsigned long) &cxacru_cb00 792 }, 793 { /* V = Conexant P = ADSL modem */ 794 USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00 795 }, 796 { /* V = Olitec P = ADSL modem version 2 */ 797 USB_DEVICE(0x08e3, 0x0100), .driver_info = (unsigned long) &cxacru_cafe 798 }, 799 { /* V = Olitec P = ADSL modem version 3 */ 800 USB_DEVICE(0x08e3, 0x0102), .driver_info = (unsigned long) &cxacru_cb00 801 }, 802 { /* V = Trust/Amigo Technology Co. P = AMX-CA86U */ 803 USB_DEVICE(0x0eb0, 0x3457), .driver_info = (unsigned long) &cxacru_cafe 804 }, 805 { /* V = Zoom P = 5510 */ 806 USB_DEVICE(0x1803, 0x5510), .driver_info = (unsigned long) &cxacru_cb00 807 }, 808 { /* V = Draytek P = Vigor 318 */ 809 USB_DEVICE(0x0675, 0x0200), .driver_info = (unsigned long) &cxacru_cb00 810 }, 811 { /* V = Zyxel P = 630-C1 aka OMNI ADSL USB (Annex A) */ 812 USB_DEVICE(0x0586, 0x330a), .driver_info = (unsigned long) &cxacru_cb00 813 }, 814 { /* V = Zyxel P = 630-C3 aka OMNI ADSL USB (Annex B) */ 815 USB_DEVICE(0x0586, 0x330b), .driver_info = (unsigned long) &cxacru_cb00 816 }, 817 { /* V = Aethra P = Starmodem UM1020 */ 818 USB_DEVICE(0x0659, 0x0020), .driver_info = (unsigned long) &cxacru_cb00 819 }, 820 { /* V = Aztech Systems P = ? AKA Pirelli AUA-010 */ 821 USB_DEVICE(0x0509, 0x0812), .driver_info = (unsigned long) &cxacru_cb00 822 }, 823 { /* V = Netopia P = Cayman 3341(Annex A)/3351(Annex B) */ 824 USB_DEVICE(0x100d, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 825 }, 826 { /* V = Netopia P = Cayman 3342(Annex A)/3352(Annex B) */ 827 USB_DEVICE(0x100d, 0x3342), .driver_info = (unsigned long) &cxacru_cb00 828 }, 829 {} 830 }; 831 832 MODULE_DEVICE_TABLE(usb, cxacru_usb_ids); 833 834 static struct usbatm_driver cxacru_driver = { 835 .driver_name = cxacru_driver_name, 836 .bind = cxacru_bind, 837 .heavy_init = cxacru_heavy_init, 838 .unbind = cxacru_unbind, 839 .atm_start = cxacru_atm_start, 840 .bulk_in = CXACRU_EP_DATA, 841 .bulk_out = CXACRU_EP_DATA, 842 .rx_padding = 3, 843 .tx_padding = 11, 844 }; 845 846 static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) 847 { 848 return usbatm_usb_probe(intf, id, &cxacru_driver); 849 } 850 851 static struct usb_driver cxacru_usb_driver = { 852 .name = cxacru_driver_name, 853 .probe = cxacru_usb_probe, 854 .disconnect = usbatm_usb_disconnect, 855 .id_table = cxacru_usb_ids 856 }; 857 858 static int __init cxacru_init(void) 859 { 860 return usb_register(&cxacru_usb_driver); 861 } 862 863 static void __exit cxacru_cleanup(void) 864 { 865 usb_deregister(&cxacru_usb_driver); 866 } 867 868 module_init(cxacru_init); 869 module_exit(cxacru_cleanup); 870 871 MODULE_AUTHOR(DRIVER_AUTHOR); 872 MODULE_DESCRIPTION(DRIVER_DESC); 873 MODULE_LICENSE("GPL"); 874 MODULE_VERSION(DRIVER_VERSION); 875