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 40 #include "usbatm.h" 41 42 #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands" 43 #define DRIVER_VERSION "0.2" 44 #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" 45 46 static const char cxacru_driver_name[] = "cxacru"; 47 48 #define CXACRU_EP_CMD 0x01 /* Bulk/interrupt in/out */ 49 #define CXACRU_EP_DATA 0x02 /* Bulk in/out */ 50 51 #define CMD_PACKET_SIZE 64 /* Should be maxpacket(ep)? */ 52 53 /* Addresses */ 54 #define PLLFCLK_ADDR 0x00350068 55 #define PLLBCLK_ADDR 0x0035006c 56 #define SDRAMEN_ADDR 0x00350010 57 #define FW_ADDR 0x00801000 58 #define BR_ADDR 0x00180600 59 #define SIG_ADDR 0x00180500 60 #define BR_STACK_ADDR 0x00187f10 61 62 /* Values */ 63 #define SDRAM_ENA 0x1 64 65 #define CMD_TIMEOUT 2000 /* msecs */ 66 #define POLL_INTERVAL 5000 /* msecs */ 67 68 /* commands for interaction with the modem through the control channel before 69 * firmware is loaded */ 70 enum cxacru_fw_request { 71 FW_CMD_ERR, 72 FW_GET_VER, 73 FW_READ_MEM, 74 FW_WRITE_MEM, 75 FW_RMW_MEM, 76 FW_CHECKSUM_MEM, 77 FW_GOTO_MEM, 78 }; 79 80 /* commands for interaction with the modem through the control channel once 81 * firmware is loaded */ 82 enum cxacru_cm_request { 83 CM_REQUEST_UNDEFINED = 0x80, 84 CM_REQUEST_TEST, 85 CM_REQUEST_CHIP_GET_MAC_ADDRESS, 86 CM_REQUEST_CHIP_GET_DP_VERSIONS, 87 CM_REQUEST_CHIP_ADSL_LINE_START, 88 CM_REQUEST_CHIP_ADSL_LINE_STOP, 89 CM_REQUEST_CHIP_ADSL_LINE_GET_STATUS, 90 CM_REQUEST_CHIP_ADSL_LINE_GET_SPEED, 91 CM_REQUEST_CARD_INFO_GET, 92 CM_REQUEST_CARD_DATA_GET, 93 CM_REQUEST_CARD_DATA_SET, 94 CM_REQUEST_COMMAND_HW_IO, 95 CM_REQUEST_INTERFACE_HW_IO, 96 CM_REQUEST_CARD_SERIAL_DATA_PATH_GET, 97 CM_REQUEST_CARD_SERIAL_DATA_PATH_SET, 98 CM_REQUEST_CARD_CONTROLLER_VERSION_GET, 99 CM_REQUEST_CARD_GET_STATUS, 100 CM_REQUEST_CARD_GET_MAC_ADDRESS, 101 CM_REQUEST_CARD_GET_DATA_LINK_STATUS, 102 CM_REQUEST_MAX, 103 }; 104 105 /* reply codes to the commands above */ 106 enum cxacru_cm_status { 107 CM_STATUS_UNDEFINED, 108 CM_STATUS_SUCCESS, 109 CM_STATUS_ERROR, 110 CM_STATUS_UNSUPPORTED, 111 CM_STATUS_UNIMPLEMENTED, 112 CM_STATUS_PARAMETER_ERROR, 113 CM_STATUS_DBG_LOOPBACK, 114 CM_STATUS_MAX, 115 }; 116 117 /* indices into CARD_INFO_GET return array */ 118 enum cxacru_info_idx { 119 CXINF_DOWNSTREAM_RATE, 120 CXINF_UPSTREAM_RATE, 121 CXINF_LINK_STATUS, 122 CXINF_LINE_STATUS, 123 CXINF_MAC_ADDRESS_HIGH, 124 CXINF_MAC_ADDRESS_LOW, 125 CXINF_UPSTREAM_SNR_MARGIN, 126 CXINF_DOWNSTREAM_SNR_MARGIN, 127 CXINF_UPSTREAM_ATTENUATION, 128 CXINF_DOWNSTREAM_ATTENUATION, 129 CXINF_TRANSMITTER_POWER, 130 CXINF_UPSTREAM_BITS_PER_FRAME, 131 CXINF_DOWNSTREAM_BITS_PER_FRAME, 132 CXINF_STARTUP_ATTEMPTS, 133 CXINF_UPSTREAM_CRC_ERRORS, 134 CXINF_DOWNSTREAM_CRC_ERRORS, 135 CXINF_UPSTREAM_FEC_ERRORS, 136 CXINF_DOWNSTREAM_FEC_ERRORS, 137 CXINF_UPSTREAM_HEC_ERRORS, 138 CXINF_DOWNSTREAM_HEC_ERRORS, 139 CXINF_LINE_STARTABLE, 140 CXINF_MODULATION, 141 CXINF_ADSL_HEADEND, 142 CXINF_ADSL_HEADEND_ENVIRONMENT, 143 CXINF_CONTROLLER_VERSION, 144 /* dunno what the missing two mean */ 145 CXINF_MAX = 0x1c, 146 }; 147 148 struct cxacru_modem_type { 149 u32 pll_f_clk; 150 u32 pll_b_clk; 151 int boot_rom_patch; 152 }; 153 154 struct cxacru_data { 155 struct usbatm_data *usbatm; 156 157 const struct cxacru_modem_type *modem_type; 158 159 int line_status; 160 struct work_struct poll_work; 161 162 /* contol handles */ 163 struct semaphore cm_serialize; 164 u8 *rcv_buf; 165 u8 *snd_buf; 166 struct urb *rcv_urb; 167 struct urb *snd_urb; 168 struct completion rcv_done; 169 struct completion snd_done; 170 }; 171 172 /* the following three functions are stolen from drivers/usb/core/message.c */ 173 static void cxacru_blocking_completion(struct urb *urb, struct pt_regs *regs) 174 { 175 complete((struct completion *)urb->context); 176 } 177 178 static void cxacru_timeout_kill(unsigned long data) 179 { 180 usb_unlink_urb((struct urb *) data); 181 } 182 183 static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, 184 int* actual_length) 185 { 186 struct timer_list timer; 187 int status; 188 189 init_timer(&timer); 190 timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); 191 timer.data = (unsigned long) urb; 192 timer.function = cxacru_timeout_kill; 193 add_timer(&timer); 194 wait_for_completion(done); 195 status = urb->status; 196 if (status == -ECONNRESET) 197 status = -ETIMEDOUT; 198 del_timer_sync(&timer); 199 200 if (actual_length) 201 *actual_length = urb->actual_length; 202 return status; 203 } 204 205 static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, 206 u8 *wdata, int wsize, u8 *rdata, int rsize) 207 { 208 int ret, actlen; 209 int offb, offd; 210 const int stride = CMD_PACKET_SIZE - 4; 211 u8 *wbuf = instance->snd_buf; 212 u8 *rbuf = instance->rcv_buf; 213 int wbuflen = ((wsize - 1) / stride + 1) * CMD_PACKET_SIZE; 214 int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE; 215 216 if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) { 217 dbg("too big transfer requested"); 218 ret = -ENOMEM; 219 goto fail; 220 } 221 222 down(&instance->cm_serialize); 223 224 /* submit reading urb before the writing one */ 225 init_completion(&instance->rcv_done); 226 ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL); 227 if (ret < 0) { 228 dbg("submitting read urb for cm %#x failed", cm); 229 ret = ret; 230 goto fail; 231 } 232 233 memset(wbuf, 0, wbuflen); 234 /* handle wsize == 0 */ 235 wbuf[0] = cm; 236 for (offb = offd = 0; offd < wsize; offd += stride, offb += CMD_PACKET_SIZE) { 237 wbuf[offb] = cm; 238 memcpy(wbuf + offb + 4, wdata + offd, min_t(int, stride, wsize - offd)); 239 } 240 241 instance->snd_urb->transfer_buffer_length = wbuflen; 242 init_completion(&instance->snd_done); 243 ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL); 244 if (ret < 0) { 245 dbg("submitting write urb for cm %#x failed", cm); 246 ret = ret; 247 goto fail; 248 } 249 250 ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL); 251 if (ret < 0) { 252 dbg("sending cm %#x failed", cm); 253 ret = ret; 254 goto fail; 255 } 256 257 ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen); 258 if (ret < 0) { 259 dbg("receiving cm %#x failed", cm); 260 ret = ret; 261 goto fail; 262 } 263 if (actlen % CMD_PACKET_SIZE || !actlen) { 264 dbg("response is not a positive multiple of %d: %#x", 265 CMD_PACKET_SIZE, actlen); 266 ret = -EIO; 267 goto fail; 268 } 269 270 /* check the return status and copy the data to the output buffer, if needed */ 271 for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) { 272 if (rbuf[offb] != cm) { 273 dbg("wrong cm %#x in response", rbuf[offb]); 274 ret = -EIO; 275 goto fail; 276 } 277 if (rbuf[offb + 1] != CM_STATUS_SUCCESS) { 278 dbg("response failed: %#x", rbuf[offb + 1]); 279 ret = -EIO; 280 goto fail; 281 } 282 if (offd >= rsize) 283 break; 284 memcpy(rdata + offd, rbuf + offb + 4, min_t(int, stride, rsize - offd)); 285 offd += stride; 286 } 287 288 ret = offd; 289 dbg("cm %#x", cm); 290 fail: 291 up(&instance->cm_serialize); 292 return ret; 293 } 294 295 static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_request cm, 296 u32 *data, int size) 297 { 298 int ret, len; 299 u32 *buf; 300 int offb, offd; 301 const int stride = CMD_PACKET_SIZE / (4 * 2) - 1; 302 int buflen = ((size - 1) / stride + 1 + size * 2) * 4; 303 304 buf = kmalloc(buflen, GFP_KERNEL); 305 if (!buf) 306 return -ENOMEM; 307 308 ret = cxacru_cm(instance, cm, NULL, 0, (u8 *) buf, buflen); 309 if (ret < 0) 310 goto cleanup; 311 312 /* len > 0 && len % 4 == 0 guaranteed by cxacru_cm() */ 313 len = ret / 4; 314 for (offb = 0; offb < len; ) { 315 int l = le32_to_cpu(buf[offb++]); 316 if (l > stride || l > (len - offb) / 2) { 317 dbg("wrong data length %#x in response", l); 318 ret = -EIO; 319 goto cleanup; 320 } 321 while (l--) { 322 offd = le32_to_cpu(buf[offb++]); 323 if (offd >= size) { 324 dbg("wrong index %#x in response", offd); 325 ret = -EIO; 326 goto cleanup; 327 } 328 data[offd] = le32_to_cpu(buf[offb++]); 329 } 330 } 331 332 ret = 0; 333 334 cleanup: 335 kfree(buf); 336 return ret; 337 } 338 339 static int cxacru_card_status(struct cxacru_data *instance) 340 { 341 int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); 342 if (ret < 0) { /* firmware not loaded */ 343 dbg("cxacru_adsl_start: CARD_GET_STATUS returned %d", ret); 344 return ret; 345 } 346 return 0; 347 } 348 349 static void cxacru_poll_status(struct cxacru_data *instance); 350 351 static int cxacru_atm_start(struct usbatm_data *usbatm_instance, 352 struct atm_dev *atm_dev) 353 { 354 struct cxacru_data *instance = usbatm_instance->driver_data; 355 struct device *dev = &usbatm_instance->usb_intf->dev; 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 dev_err(dev, "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 dev_err(dev, "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 device *dev = &instance->usbatm->usb_intf->dev; 387 struct atm_dev *atm_dev = instance->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 dev_warn(dev, "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 dev_info(dev, "ADSL line: down\n"); 404 break; 405 406 case 1: 407 atm_dev->signal = ATM_PHY_SIG_LOST; 408 dev_info(dev, "ADSL line: attemtping to activate\n"); 409 break; 410 411 case 2: 412 atm_dev->signal = ATM_PHY_SIG_LOST; 413 dev_info(dev, "ADSL line: training\n"); 414 break; 415 416 case 3: 417 atm_dev->signal = ATM_PHY_SIG_LOST; 418 dev_info(dev, "ADSL line: channel analysis\n"); 419 break; 420 421 case 4: 422 atm_dev->signal = ATM_PHY_SIG_LOST; 423 dev_info(dev, "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 dev_info(dev, "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 dev_info(dev, "ADSL line: waiting\n"); 437 break; 438 439 case 7: 440 atm_dev->signal = ATM_PHY_SIG_LOST; 441 dev_info(dev, "ADSL line: initializing\n"); 442 break; 443 444 default: 445 atm_dev->signal = ATM_PHY_SIG_UNKNOWN; 446 dev_info(dev, "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 usb_device *usb_dev = instance->usbatm->usb_dev; 508 struct device *dev = &instance->usbatm->usb_intf->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 dev_err(dev, "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 dev_err(dev, "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 dev_err(dev, "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 dev_err(dev, "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 dev_err(dev, "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 dev_err(dev, "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 dev_err(dev, "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 dev_err(dev, "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 dev_err(dev, "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 device *dev = &instance->usbatm->usb_intf->dev; 612 char buf[16]; 613 614 sprintf(buf, "cxacru-%s.bin", phase); 615 dbg("cxacru_find_firmware: looking for %s", buf); 616 617 if (request_firmware(fw_p, buf, dev)) { 618 dev_dbg(dev, "no stage %s firmware found\n", phase); 619 return -ENOENT; 620 } 621 622 dev_info(dev, "found firmware %s\n", buf); 623 624 return 0; 625 } 626 627 static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, 628 struct usb_interface *usb_intf) 629 { 630 struct device *dev = &usbatm_instance->usb_intf->dev; 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 dev_warn(dev, "firmware (cxacru-fw.bin) unavailable (hotplug misconfiguration?)\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 dev_warn(dev, "boot ROM patch (cxacru-bp.bin) unavailable (hotplug misconfiguration?)\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 int *need_heavy_init) 672 { 673 struct cxacru_data *instance; 674 struct usb_device *usb_dev = interface_to_usbdev(intf); 675 int ret; 676 677 /* instance init */ 678 instance = kmalloc(sizeof(*instance), GFP_KERNEL); 679 if (!instance) { 680 dbg("cxacru_bind: no memory for instance data"); 681 return -ENOMEM; 682 } 683 684 memset(instance, 0, sizeof(*instance)); 685 686 instance->usbatm = usbatm_instance; 687 instance->modem_type = (struct cxacru_modem_type *) id->driver_info; 688 689 instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); 690 if (!instance->rcv_buf) { 691 dbg("cxacru_bind: no memory for rcv_buf"); 692 ret = -ENOMEM; 693 goto fail; 694 } 695 instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL); 696 if (!instance->snd_buf) { 697 dbg("cxacru_bind: no memory for snd_buf"); 698 ret = -ENOMEM; 699 goto fail; 700 } 701 instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL); 702 if (!instance->rcv_urb) { 703 dbg("cxacru_bind: no memory for rcv_urb"); 704 ret = -ENOMEM; 705 goto fail; 706 } 707 instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL); 708 if (!instance->snd_urb) { 709 dbg("cxacru_bind: no memory for snd_urb"); 710 ret = -ENOMEM; 711 goto fail; 712 } 713 714 usb_fill_int_urb(instance->rcv_urb, 715 usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), 716 instance->rcv_buf, PAGE_SIZE, 717 cxacru_blocking_completion, &instance->rcv_done, 1); 718 719 usb_fill_int_urb(instance->snd_urb, 720 usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), 721 instance->snd_buf, PAGE_SIZE, 722 cxacru_blocking_completion, &instance->snd_done, 4); 723 724 init_MUTEX(&instance->cm_serialize); 725 726 INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance); 727 728 usbatm_instance->driver_data = instance; 729 730 *need_heavy_init = cxacru_card_status(instance); 731 732 return 0; 733 734 fail: 735 free_page((unsigned long) instance->snd_buf); 736 free_page((unsigned long) instance->rcv_buf); 737 usb_free_urb(instance->snd_urb); 738 usb_free_urb(instance->rcv_urb); 739 kfree(instance); 740 741 return ret; 742 } 743 744 static void cxacru_unbind(struct usbatm_data *usbatm_instance, 745 struct usb_interface *intf) 746 { 747 struct cxacru_data *instance = usbatm_instance->driver_data; 748 749 dbg("cxacru_unbind entered"); 750 751 if (!instance) { 752 dbg("cxacru_unbind: NULL instance!"); 753 return; 754 } 755 756 while (!cancel_delayed_work(&instance->poll_work)) 757 flush_scheduled_work(); 758 759 usb_kill_urb(instance->snd_urb); 760 usb_kill_urb(instance->rcv_urb); 761 usb_free_urb(instance->snd_urb); 762 usb_free_urb(instance->rcv_urb); 763 764 free_page((unsigned long) instance->snd_buf); 765 free_page((unsigned long) instance->rcv_buf); 766 kfree(instance); 767 768 usbatm_instance->driver_data = NULL; 769 } 770 771 static const struct cxacru_modem_type cxacru_cafe = { 772 .pll_f_clk = 0x02d874df, 773 .pll_b_clk = 0x0196a51a, 774 .boot_rom_patch = 1, 775 }; 776 777 static const struct cxacru_modem_type cxacru_cb00 = { 778 .pll_f_clk = 0x5, 779 .pll_b_clk = 0x3, 780 .boot_rom_patch = 0, 781 }; 782 783 static const struct usb_device_id cxacru_usb_ids[] = { 784 { /* V = Conexant P = ADSL modem (Euphrates project) */ 785 USB_DEVICE(0x0572, 0xcafe), .driver_info = (unsigned long) &cxacru_cafe 786 }, 787 { /* V = Conexant P = ADSL modem (Hasbani project) */ 788 USB_DEVICE(0x0572, 0xcb00), .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, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 795 }, 796 { /* V = Conexant P = ADSL modem */ 797 USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00 798 }, 799 { /* V = Olitec P = ADSL modem version 2 */ 800 USB_DEVICE(0x08e3, 0x0100), .driver_info = (unsigned long) &cxacru_cafe 801 }, 802 { /* V = Olitec P = ADSL modem version 3 */ 803 USB_DEVICE(0x08e3, 0x0102), .driver_info = (unsigned long) &cxacru_cb00 804 }, 805 { /* V = Trust/Amigo Technology Co. P = AMX-CA86U */ 806 USB_DEVICE(0x0eb0, 0x3457), .driver_info = (unsigned long) &cxacru_cafe 807 }, 808 { /* V = Zoom P = 5510 */ 809 USB_DEVICE(0x1803, 0x5510), .driver_info = (unsigned long) &cxacru_cb00 810 }, 811 { /* V = Draytek P = Vigor 318 */ 812 USB_DEVICE(0x0675, 0x0200), .driver_info = (unsigned long) &cxacru_cb00 813 }, 814 { /* V = Zyxel P = 630-C1 aka OMNI ADSL USB (Annex A) */ 815 USB_DEVICE(0x0586, 0x330a), .driver_info = (unsigned long) &cxacru_cb00 816 }, 817 { /* V = Zyxel P = 630-C3 aka OMNI ADSL USB (Annex B) */ 818 USB_DEVICE(0x0586, 0x330b), .driver_info = (unsigned long) &cxacru_cb00 819 }, 820 { /* V = Aethra P = Starmodem UM1020 */ 821 USB_DEVICE(0x0659, 0x0020), .driver_info = (unsigned long) &cxacru_cb00 822 }, 823 { /* V = Aztech Systems P = ? AKA Pirelli AUA-010 */ 824 USB_DEVICE(0x0509, 0x0812), .driver_info = (unsigned long) &cxacru_cb00 825 }, 826 { /* V = Netopia P = Cayman 3341(Annex A)/3351(Annex B) */ 827 USB_DEVICE(0x100d, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 828 }, 829 { /* V = Netopia P = Cayman 3342(Annex A)/3352(Annex B) */ 830 USB_DEVICE(0x100d, 0x3342), .driver_info = (unsigned long) &cxacru_cb00 831 }, 832 {} 833 }; 834 835 MODULE_DEVICE_TABLE(usb, cxacru_usb_ids); 836 837 static struct usbatm_driver cxacru_driver = { 838 .owner = THIS_MODULE, 839 .driver_name = cxacru_driver_name, 840 .bind = cxacru_bind, 841 .heavy_init = cxacru_heavy_init, 842 .unbind = cxacru_unbind, 843 .atm_start = cxacru_atm_start, 844 .in = CXACRU_EP_DATA, 845 .out = CXACRU_EP_DATA, 846 .rx_padding = 3, 847 .tx_padding = 11, 848 }; 849 850 static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) 851 { 852 return usbatm_usb_probe(intf, id, &cxacru_driver); 853 } 854 855 static struct usb_driver cxacru_usb_driver = { 856 .name = cxacru_driver_name, 857 .probe = cxacru_usb_probe, 858 .disconnect = usbatm_usb_disconnect, 859 .id_table = cxacru_usb_ids 860 }; 861 862 static int __init cxacru_init(void) 863 { 864 return usb_register(&cxacru_usb_driver); 865 } 866 867 static void __exit cxacru_cleanup(void) 868 { 869 usb_deregister(&cxacru_usb_driver); 870 } 871 872 module_init(cxacru_init); 873 module_exit(cxacru_cleanup); 874 875 MODULE_AUTHOR(DRIVER_AUTHOR); 876 MODULE_DESCRIPTION(DRIVER_DESC); 877 MODULE_LICENSE("GPL"); 878 MODULE_VERSION(DRIVER_VERSION); 879