linux/drivers/usb/atm/cxacru.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/******************************************************************************
   3 *  cxacru.c  -  driver for USB ADSL modems based on
   4 *               Conexant AccessRunner chipset
   5 *
   6 *  Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan
   7 *  Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru)
   8 *  Copyright (C) 2007 Simon Arlott
   9 *  Copyright (C) 2009 Simon Arlott
  10 ******************************************************************************/
  11
  12/*
  13 *  Credit is due for Josep Comas, who created the original patch to speedtch.c
  14 *  to support the different padding used by the AccessRunner (now generalized
  15 *  into usbatm), and the userspace firmware loading utility.
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/moduleparam.h>
  20#include <linux/kernel.h>
  21#include <linux/timer.h>
  22#include <linux/errno.h>
  23#include <linux/slab.h>
  24#include <linux/device.h>
  25#include <linux/firmware.h>
  26#include <linux/mutex.h>
  27#include <asm/unaligned.h>
  28
  29#include "usbatm.h"
  30
  31#define DRIVER_AUTHOR   "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott"
  32#define DRIVER_DESC     "Conexant AccessRunner ADSL USB modem driver"
  33
  34static const char cxacru_driver_name[] = "cxacru";
  35
  36#define CXACRU_EP_CMD           0x01    /* Bulk/interrupt in/out */
  37#define CXACRU_EP_DATA          0x02    /* Bulk in/out */
  38
  39#define CMD_PACKET_SIZE         64      /* Should be maxpacket(ep)? */
  40#define CMD_MAX_CONFIG          ((CMD_PACKET_SIZE / 4 - 1) / 2)
  41
  42/* Addresses */
  43#define PLLFCLK_ADDR    0x00350068
  44#define PLLBCLK_ADDR    0x0035006c
  45#define SDRAMEN_ADDR    0x00350010
  46#define FW_ADDR         0x00801000
  47#define BR_ADDR         0x00180600
  48#define SIG_ADDR        0x00180500
  49#define BR_STACK_ADDR   0x00187f10
  50
  51/* Values */
  52#define SDRAM_ENA       0x1
  53
  54#define CMD_TIMEOUT     2000    /* msecs */
  55#define POLL_INTERVAL   1       /* secs */
  56
  57/* commands for interaction with the modem through the control channel before
  58 * firmware is loaded  */
  59enum cxacru_fw_request {
  60        FW_CMD_ERR,
  61        FW_GET_VER,
  62        FW_READ_MEM,
  63        FW_WRITE_MEM,
  64        FW_RMW_MEM,
  65        FW_CHECKSUM_MEM,
  66        FW_GOTO_MEM,
  67};
  68
  69/* commands for interaction with the modem through the control channel once
  70 * firmware is loaded  */
  71enum cxacru_cm_request {
  72        CM_REQUEST_UNDEFINED = 0x80,
  73        CM_REQUEST_TEST,
  74        CM_REQUEST_CHIP_GET_MAC_ADDRESS,
  75        CM_REQUEST_CHIP_GET_DP_VERSIONS,
  76        CM_REQUEST_CHIP_ADSL_LINE_START,
  77        CM_REQUEST_CHIP_ADSL_LINE_STOP,
  78        CM_REQUEST_CHIP_ADSL_LINE_GET_STATUS,
  79        CM_REQUEST_CHIP_ADSL_LINE_GET_SPEED,
  80        CM_REQUEST_CARD_INFO_GET,
  81        CM_REQUEST_CARD_DATA_GET,
  82        CM_REQUEST_CARD_DATA_SET,
  83        CM_REQUEST_COMMAND_HW_IO,
  84        CM_REQUEST_INTERFACE_HW_IO,
  85        CM_REQUEST_CARD_SERIAL_DATA_PATH_GET,
  86        CM_REQUEST_CARD_SERIAL_DATA_PATH_SET,
  87        CM_REQUEST_CARD_CONTROLLER_VERSION_GET,
  88        CM_REQUEST_CARD_GET_STATUS,
  89        CM_REQUEST_CARD_GET_MAC_ADDRESS,
  90        CM_REQUEST_CARD_GET_DATA_LINK_STATUS,
  91        CM_REQUEST_MAX,
  92};
  93
  94/* commands for interaction with the flash memory
  95 *
  96 * read:  response is the contents of the first 60 bytes of flash memory
  97 * write: request contains the 60 bytes of data to write to flash memory
  98 *        response is the contents of the first 60 bytes of flash memory
  99 *
 100 * layout: PP PP VV VV  MM MM MM MM  MM MM ?? ??  SS SS SS SS  SS SS SS SS
 101 *         SS SS SS SS  SS SS SS SS  00 00 00 00  00 00 00 00  00 00 00 00
 102 *         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
 103 *
 104 *   P: le16  USB Product ID
 105 *   V: le16  USB Vendor ID
 106 *   M: be48  MAC Address
 107 *   S: le16  ASCII Serial Number
 108 */
 109enum cxacru_cm_flash {
 110        CM_FLASH_READ = 0xa1,
 111        CM_FLASH_WRITE = 0xa2
 112};
 113
 114/* reply codes to the commands above */
 115enum cxacru_cm_status {
 116        CM_STATUS_UNDEFINED,
 117        CM_STATUS_SUCCESS,
 118        CM_STATUS_ERROR,
 119        CM_STATUS_UNSUPPORTED,
 120        CM_STATUS_UNIMPLEMENTED,
 121        CM_STATUS_PARAMETER_ERROR,
 122        CM_STATUS_DBG_LOOPBACK,
 123        CM_STATUS_MAX,
 124};
 125
 126/* indices into CARD_INFO_GET return array */
 127enum cxacru_info_idx {
 128        CXINF_DOWNSTREAM_RATE,
 129        CXINF_UPSTREAM_RATE,
 130        CXINF_LINK_STATUS,
 131        CXINF_LINE_STATUS,
 132        CXINF_MAC_ADDRESS_HIGH,
 133        CXINF_MAC_ADDRESS_LOW,
 134        CXINF_UPSTREAM_SNR_MARGIN,
 135        CXINF_DOWNSTREAM_SNR_MARGIN,
 136        CXINF_UPSTREAM_ATTENUATION,
 137        CXINF_DOWNSTREAM_ATTENUATION,
 138        CXINF_TRANSMITTER_POWER,
 139        CXINF_UPSTREAM_BITS_PER_FRAME,
 140        CXINF_DOWNSTREAM_BITS_PER_FRAME,
 141        CXINF_STARTUP_ATTEMPTS,
 142        CXINF_UPSTREAM_CRC_ERRORS,
 143        CXINF_DOWNSTREAM_CRC_ERRORS,
 144        CXINF_UPSTREAM_FEC_ERRORS,
 145        CXINF_DOWNSTREAM_FEC_ERRORS,
 146        CXINF_UPSTREAM_HEC_ERRORS,
 147        CXINF_DOWNSTREAM_HEC_ERRORS,
 148        CXINF_LINE_STARTABLE,
 149        CXINF_MODULATION,
 150        CXINF_ADSL_HEADEND,
 151        CXINF_ADSL_HEADEND_ENVIRONMENT,
 152        CXINF_CONTROLLER_VERSION,
 153        /* dunno what the missing two mean */
 154        CXINF_MAX = 0x1c,
 155};
 156
 157enum cxacru_poll_state {
 158        CXPOLL_STOPPING,
 159        CXPOLL_STOPPED,
 160        CXPOLL_POLLING,
 161        CXPOLL_SHUTDOWN
 162};
 163
 164struct cxacru_modem_type {
 165        u32 pll_f_clk;
 166        u32 pll_b_clk;
 167        int boot_rom_patch;
 168};
 169
 170struct cxacru_data {
 171        struct usbatm_data *usbatm;
 172
 173        const struct cxacru_modem_type *modem_type;
 174
 175        int line_status;
 176        struct mutex adsl_state_serialize;
 177        int adsl_status;
 178        struct delayed_work poll_work;
 179        u32 card_info[CXINF_MAX];
 180        struct mutex poll_state_serialize;
 181        enum cxacru_poll_state poll_state;
 182
 183        /* contol handles */
 184        struct mutex cm_serialize;
 185        u8 *rcv_buf;
 186        u8 *snd_buf;
 187        struct urb *rcv_urb;
 188        struct urb *snd_urb;
 189        struct completion rcv_done;
 190        struct completion snd_done;
 191};
 192
 193static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
 194        u8 *wdata, int wsize, u8 *rdata, int rsize);
 195static void cxacru_poll_status(struct work_struct *work);
 196
 197/* Card info exported through sysfs */
 198#define CXACRU__ATTR_INIT(_name) \
 199static DEVICE_ATTR(_name, S_IRUGO, cxacru_sysfs_show_##_name, NULL)
 200
 201#define CXACRU_CMD_INIT(_name) \
 202static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \
 203        cxacru_sysfs_show_##_name, cxacru_sysfs_store_##_name)
 204
 205#define CXACRU_SET_INIT(_name) \
 206static DEVICE_ATTR(_name, S_IWUSR, \
 207        NULL, cxacru_sysfs_store_##_name)
 208
 209#define CXACRU_ATTR_INIT(_value, _type, _name) \
 210static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \
 211        struct device_attribute *attr, char *buf) \
 212{ \
 213        struct cxacru_data *instance = to_usbatm_driver_data(\
 214                to_usb_interface(dev)); \
 215\
 216        if (instance == NULL) \
 217                return -ENODEV; \
 218\
 219        return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \
 220} \
 221CXACRU__ATTR_INIT(_name)
 222
 223#define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name)
 224#define CXACRU_CMD_CREATE(_name)          CXACRU_DEVICE_CREATE_FILE(_name)
 225#define CXACRU_SET_CREATE(_name)          CXACRU_DEVICE_CREATE_FILE(_name)
 226#define CXACRU__ATTR_CREATE(_name)        CXACRU_DEVICE_CREATE_FILE(_name)
 227
 228#define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name)
 229#define CXACRU_CMD_REMOVE(_name)          CXACRU_DEVICE_REMOVE_FILE(_name)
 230#define CXACRU_SET_REMOVE(_name)          CXACRU_DEVICE_REMOVE_FILE(_name)
 231#define CXACRU__ATTR_REMOVE(_name)        CXACRU_DEVICE_REMOVE_FILE(_name)
 232
 233static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf)
 234{
 235        return snprintf(buf, PAGE_SIZE, "%u\n", value);
 236}
 237
 238static ssize_t cxacru_sysfs_showattr_s8(s8 value, char *buf)
 239{
 240        return snprintf(buf, PAGE_SIZE, "%d\n", value);
 241}
 242
 243static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf)
 244{
 245        if (likely(value >= 0)) {
 246                return snprintf(buf, PAGE_SIZE, "%u.%02u\n",
 247                                        value / 100, value % 100);
 248        } else {
 249                value = -value;
 250                return snprintf(buf, PAGE_SIZE, "-%u.%02u\n",
 251                                        value / 100, value % 100);
 252        }
 253}
 254
 255static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf)
 256{
 257        static char *str[] = { "no", "yes" };
 258
 259        if (unlikely(value >= ARRAY_SIZE(str)))
 260                return snprintf(buf, PAGE_SIZE, "%u\n", value);
 261        return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 262}
 263
 264static ssize_t cxacru_sysfs_showattr_LINK(u32 value, char *buf)
 265{
 266        static char *str[] = { NULL, "not connected", "connected", "lost" };
 267
 268        if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
 269                return snprintf(buf, PAGE_SIZE, "%u\n", value);
 270        return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 271}
 272
 273static ssize_t cxacru_sysfs_showattr_LINE(u32 value, char *buf)
 274{
 275        static char *str[] = { "down", "attempting to activate",
 276                "training", "channel analysis", "exchange", "up",
 277                "waiting", "initialising"
 278        };
 279        if (unlikely(value >= ARRAY_SIZE(str)))
 280                return snprintf(buf, PAGE_SIZE, "%u\n", value);
 281        return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 282}
 283
 284static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf)
 285{
 286        static char *str[] = {
 287                        "",
 288                        "ANSI T1.413",
 289                        "ITU-T G.992.1 (G.DMT)",
 290                        "ITU-T G.992.2 (G.LITE)"
 291        };
 292        if (unlikely(value >= ARRAY_SIZE(str)))
 293                return snprintf(buf, PAGE_SIZE, "%u\n", value);
 294        return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 295}
 296
 297/*
 298 * This could use MAC_ADDRESS_HIGH and MAC_ADDRESS_LOW, but since
 299 * this data is already in atm_dev there's no point.
 300 *
 301 * MAC_ADDRESS_HIGH = 0x????5544
 302 * MAC_ADDRESS_LOW  = 0x33221100
 303 * Where 00-55 are bytes 0-5 of the MAC.
 304 */
 305static ssize_t cxacru_sysfs_show_mac_address(struct device *dev,
 306        struct device_attribute *attr, char *buf)
 307{
 308        struct cxacru_data *instance = to_usbatm_driver_data(
 309                        to_usb_interface(dev));
 310
 311        if (instance == NULL || instance->usbatm->atm_dev == NULL)
 312                return -ENODEV;
 313
 314        return snprintf(buf, PAGE_SIZE, "%pM\n",
 315                instance->usbatm->atm_dev->esi);
 316}
 317
 318static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev,
 319        struct device_attribute *attr, char *buf)
 320{
 321        static char *str[] = { "running", "stopped" };
 322        struct cxacru_data *instance = to_usbatm_driver_data(
 323                        to_usb_interface(dev));
 324        u32 value;
 325
 326        if (instance == NULL)
 327                return -ENODEV;
 328
 329        value = instance->card_info[CXINF_LINE_STARTABLE];
 330        if (unlikely(value >= ARRAY_SIZE(str)))
 331                return snprintf(buf, PAGE_SIZE, "%u\n", value);
 332        return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
 333}
 334
 335static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev,
 336        struct device_attribute *attr, const char *buf, size_t count)
 337{
 338        struct cxacru_data *instance = to_usbatm_driver_data(
 339                        to_usb_interface(dev));
 340        int ret;
 341        int poll = -1;
 342        char str_cmd[8];
 343        int len = strlen(buf);
 344
 345        if (!capable(CAP_NET_ADMIN))
 346                return -EACCES;
 347
 348        ret = sscanf(buf, "%7s", str_cmd);
 349        if (ret != 1)
 350                return -EINVAL;
 351        ret = 0;
 352
 353        if (instance == NULL)
 354                return -ENODEV;
 355
 356        if (mutex_lock_interruptible(&instance->adsl_state_serialize))
 357                return -ERESTARTSYS;
 358
 359        if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) {
 360                ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0);
 361                if (ret < 0) {
 362                        atm_err(instance->usbatm, "change adsl state:"
 363                                " CHIP_ADSL_LINE_STOP returned %d\n", ret);
 364
 365                        ret = -EIO;
 366                } else {
 367                        ret = len;
 368                        poll = CXPOLL_STOPPED;
 369                }
 370        }
 371
 372        /* Line status is only updated every second
 373         * and the device appears to only react to
 374         * START/STOP every second too. Wait 1.5s to
 375         * be sure that restart will have an effect. */
 376        if (!strcmp(str_cmd, "restart"))
 377                msleep(1500);
 378
 379        if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) {
 380                ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
 381                if (ret < 0) {
 382                        atm_err(instance->usbatm, "change adsl state:"
 383                                " CHIP_ADSL_LINE_START returned %d\n", ret);
 384
 385                        ret = -EIO;
 386                } else {
 387                        ret = len;
 388                        poll = CXPOLL_POLLING;
 389                }
 390        }
 391
 392        if (!strcmp(str_cmd, "poll")) {
 393                ret = len;
 394                poll = CXPOLL_POLLING;
 395        }
 396
 397        if (ret == 0) {
 398                ret = -EINVAL;
 399                poll = -1;
 400        }
 401
 402        if (poll == CXPOLL_POLLING) {
 403                mutex_lock(&instance->poll_state_serialize);
 404                switch (instance->poll_state) {
 405                case CXPOLL_STOPPED:
 406                        /* start polling */
 407                        instance->poll_state = CXPOLL_POLLING;
 408                        break;
 409
 410                case CXPOLL_STOPPING:
 411                        /* abort stop request */
 412                        instance->poll_state = CXPOLL_POLLING;
 413                        /* fall through */
 414                case CXPOLL_POLLING:
 415                case CXPOLL_SHUTDOWN:
 416                        /* don't start polling */
 417                        poll = -1;
 418                }
 419                mutex_unlock(&instance->poll_state_serialize);
 420        } else if (poll == CXPOLL_STOPPED) {
 421                mutex_lock(&instance->poll_state_serialize);
 422                /* request stop */
 423                if (instance->poll_state == CXPOLL_POLLING)
 424                        instance->poll_state = CXPOLL_STOPPING;
 425                mutex_unlock(&instance->poll_state_serialize);
 426        }
 427
 428        mutex_unlock(&instance->adsl_state_serialize);
 429
 430        if (poll == CXPOLL_POLLING)
 431                cxacru_poll_status(&instance->poll_work.work);
 432
 433        return ret;
 434}
 435
 436/* CM_REQUEST_CARD_DATA_GET times out, so no show attribute */
 437
 438static ssize_t cxacru_sysfs_store_adsl_config(struct device *dev,
 439        struct device_attribute *attr, const char *buf, size_t count)
 440{
 441        struct cxacru_data *instance = to_usbatm_driver_data(
 442                        to_usb_interface(dev));
 443        int len = strlen(buf);
 444        int ret, pos, num;
 445        __le32 data[CMD_PACKET_SIZE / 4];
 446
 447        if (!capable(CAP_NET_ADMIN))
 448                return -EACCES;
 449
 450        if (instance == NULL)
 451                return -ENODEV;
 452
 453        pos = 0;
 454        num = 0;
 455        while (pos < len) {
 456                int tmp;
 457                u32 index;
 458                u32 value;
 459
 460                ret = sscanf(buf + pos, "%x=%x%n", &index, &value, &tmp);
 461                if (ret < 2)
 462                        return -EINVAL;
 463                if (index > 0x7f)
 464                        return -EINVAL;
 465                if (tmp < 0 || tmp > len - pos)
 466                        return -EINVAL;
 467                pos += tmp;
 468
 469                /* skip trailing newline */
 470                if (buf[pos] == '\n' && pos == len-1)
 471                        pos++;
 472
 473                data[num * 2 + 1] = cpu_to_le32(index);
 474                data[num * 2 + 2] = cpu_to_le32(value);
 475                num++;
 476
 477                /* send config values when data buffer is full
 478                 * or no more data
 479                 */
 480                if (pos >= len || num >= CMD_MAX_CONFIG) {
 481                        char log[CMD_MAX_CONFIG * 12 + 1]; /* %02x=%08x */
 482
 483                        data[0] = cpu_to_le32(num);
 484                        ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET,
 485                                (u8 *) data, 4 + num * 8, NULL, 0);
 486                        if (ret < 0) {
 487                                atm_err(instance->usbatm,
 488                                        "set card data returned %d\n", ret);
 489                                return -EIO;
 490                        }
 491
 492                        for (tmp = 0; tmp < num; tmp++)
 493                                snprintf(log + tmp*12, 13, " %02x=%08x",
 494                                        le32_to_cpu(data[tmp * 2 + 1]),
 495                                        le32_to_cpu(data[tmp * 2 + 2]));
 496                        atm_info(instance->usbatm, "config%s\n", log);
 497                        num = 0;
 498                }
 499        }
 500
 501        return len;
 502}
 503
 504/*
 505 * All device attributes are included in CXACRU_ALL_FILES
 506 * so that the same list can be used multiple times:
 507 *     INIT   (define the device attributes)
 508 *     CREATE (create all the device files)
 509 *     REMOVE (remove all the device files)
 510 *
 511 * With the last two being defined as needed in the functions
 512 * they are used in before calling CXACRU_ALL_FILES()
 513 */
 514#define CXACRU_ALL_FILES(_action) \
 515CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_RATE,           u32,  downstream_rate); \
 516CXACRU_ATTR_##_action(CXINF_UPSTREAM_RATE,             u32,  upstream_rate); \
 517CXACRU_ATTR_##_action(CXINF_LINK_STATUS,               LINK, link_status); \
 518CXACRU_ATTR_##_action(CXINF_LINE_STATUS,               LINE, line_status); \
 519CXACRU__ATTR_##_action(                                      mac_address); \
 520CXACRU_ATTR_##_action(CXINF_UPSTREAM_SNR_MARGIN,       dB,   upstream_snr_margin); \
 521CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_SNR_MARGIN,     dB,   downstream_snr_margin); \
 522CXACRU_ATTR_##_action(CXINF_UPSTREAM_ATTENUATION,      dB,   upstream_attenuation); \
 523CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_ATTENUATION,    dB,   downstream_attenuation); \
 524CXACRU_ATTR_##_action(CXINF_TRANSMITTER_POWER,         s8,   transmitter_power); \
 525CXACRU_ATTR_##_action(CXINF_UPSTREAM_BITS_PER_FRAME,   u32,  upstream_bits_per_frame); \
 526CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_BITS_PER_FRAME, u32,  downstream_bits_per_frame); \
 527CXACRU_ATTR_##_action(CXINF_STARTUP_ATTEMPTS,          u32,  startup_attempts); \
 528CXACRU_ATTR_##_action(CXINF_UPSTREAM_CRC_ERRORS,       u32,  upstream_crc_errors); \
 529CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_CRC_ERRORS,     u32,  downstream_crc_errors); \
 530CXACRU_ATTR_##_action(CXINF_UPSTREAM_FEC_ERRORS,       u32,  upstream_fec_errors); \
 531CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_FEC_ERRORS,     u32,  downstream_fec_errors); \
 532CXACRU_ATTR_##_action(CXINF_UPSTREAM_HEC_ERRORS,       u32,  upstream_hec_errors); \
 533CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_HEC_ERRORS,     u32,  downstream_hec_errors); \
 534CXACRU_ATTR_##_action(CXINF_LINE_STARTABLE,            bool, line_startable); \
 535CXACRU_ATTR_##_action(CXINF_MODULATION,                MODU, modulation); \
 536CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND,              u32,  adsl_headend); \
 537CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT,  u32,  adsl_headend_environment); \
 538CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION,        u32,  adsl_controller_version); \
 539CXACRU_CMD_##_action(                                        adsl_state); \
 540CXACRU_SET_##_action(                                        adsl_config);
 541
 542CXACRU_ALL_FILES(INIT);
 543
 544/* the following three functions are stolen from drivers/usb/core/message.c */
 545static void cxacru_blocking_completion(struct urb *urb)
 546{
 547        complete(urb->context);
 548}
 549
 550struct cxacru_timer {
 551        struct timer_list timer;
 552        struct urb *urb;
 553};
 554
 555static void cxacru_timeout_kill(struct timer_list *t)
 556{
 557        struct cxacru_timer *timer = from_timer(timer, t, timer);
 558
 559        usb_unlink_urb(timer->urb);
 560}
 561
 562static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
 563                                 int *actual_length)
 564{
 565        struct cxacru_timer timer = {
 566                .urb = urb,
 567        };
 568
 569        timer_setup_on_stack(&timer.timer, cxacru_timeout_kill, 0);
 570        mod_timer(&timer.timer, jiffies + msecs_to_jiffies(CMD_TIMEOUT));
 571        wait_for_completion(done);
 572        del_timer_sync(&timer.timer);
 573        destroy_timer_on_stack(&timer.timer);
 574
 575        if (actual_length)
 576                *actual_length = urb->actual_length;
 577        return urb->status; /* must read status after completion */
 578}
 579
 580static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
 581                     u8 *wdata, int wsize, u8 *rdata, int rsize)
 582{
 583        int ret, actlen;
 584        int offb, offd;
 585        const int stride = CMD_PACKET_SIZE - 4;
 586        u8 *wbuf = instance->snd_buf;
 587        u8 *rbuf = instance->rcv_buf;
 588        int wbuflen = ((wsize - 1) / stride + 1) * CMD_PACKET_SIZE;
 589        int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE;
 590
 591        if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) {
 592                if (printk_ratelimit())
 593                        usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n",
 594                                wbuflen, rbuflen);
 595                ret = -ENOMEM;
 596                goto err;
 597        }
 598
 599        mutex_lock(&instance->cm_serialize);
 600
 601        /* submit reading urb before the writing one */
 602        init_completion(&instance->rcv_done);
 603        ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL);
 604        if (ret < 0) {
 605                if (printk_ratelimit())
 606                        usb_err(instance->usbatm, "submit of read urb for cm %#x failed (%d)\n",
 607                                cm, ret);
 608                goto fail;
 609        }
 610
 611        memset(wbuf, 0, wbuflen);
 612        /* handle wsize == 0 */
 613        wbuf[0] = cm;
 614        for (offb = offd = 0; offd < wsize; offd += stride, offb += CMD_PACKET_SIZE) {
 615                wbuf[offb] = cm;
 616                memcpy(wbuf + offb + 4, wdata + offd, min_t(int, stride, wsize - offd));
 617        }
 618
 619        instance->snd_urb->transfer_buffer_length = wbuflen;
 620        init_completion(&instance->snd_done);
 621        ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL);
 622        if (ret < 0) {
 623                if (printk_ratelimit())
 624                        usb_err(instance->usbatm, "submit of write urb for cm %#x failed (%d)\n",
 625                                cm, ret);
 626                goto fail;
 627        }
 628
 629        ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL);
 630        if (ret < 0) {
 631                if (printk_ratelimit())
 632                        usb_err(instance->usbatm, "send of cm %#x failed (%d)\n", cm, ret);
 633                goto fail;
 634        }
 635
 636        ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen);
 637        if (ret < 0) {
 638                if (printk_ratelimit())
 639                        usb_err(instance->usbatm, "receive of cm %#x failed (%d)\n", cm, ret);
 640                goto fail;
 641        }
 642        if (actlen % CMD_PACKET_SIZE || !actlen) {
 643                if (printk_ratelimit())
 644                        usb_err(instance->usbatm, "invalid response length to cm %#x: %d\n",
 645                                cm, actlen);
 646                ret = -EIO;
 647                goto fail;
 648        }
 649
 650        /* check the return status and copy the data to the output buffer, if needed */
 651        for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) {
 652                if (rbuf[offb] != cm) {
 653                        if (printk_ratelimit())
 654                                usb_err(instance->usbatm, "wrong cm %#x in response to cm %#x\n",
 655                                        rbuf[offb], cm);
 656                        ret = -EIO;
 657                        goto fail;
 658                }
 659                if (rbuf[offb + 1] != CM_STATUS_SUCCESS) {
 660                        if (printk_ratelimit())
 661                                usb_err(instance->usbatm, "response to cm %#x failed: %#x\n",
 662                                        cm, rbuf[offb + 1]);
 663                        ret = -EIO;
 664                        goto fail;
 665                }
 666                if (offd >= rsize)
 667                        break;
 668                memcpy(rdata + offd, rbuf + offb + 4, min_t(int, stride, rsize - offd));
 669                offd += stride;
 670        }
 671
 672        ret = offd;
 673        usb_dbg(instance->usbatm, "cm %#x\n", cm);
 674fail:
 675        mutex_unlock(&instance->cm_serialize);
 676err:
 677        return ret;
 678}
 679
 680static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_request cm,
 681                               u32 *data, int size)
 682{
 683        int ret, len;
 684        __le32 *buf;
 685        int offb;
 686        unsigned int offd;
 687        const int stride = CMD_PACKET_SIZE / (4 * 2) - 1;
 688        int buflen =  ((size - 1) / stride + 1 + size * 2) * 4;
 689
 690        buf = kmalloc(buflen, GFP_KERNEL);
 691        if (!buf)
 692                return -ENOMEM;
 693
 694        ret = cxacru_cm(instance, cm, NULL, 0, (u8 *) buf, buflen);
 695        if (ret < 0)
 696                goto cleanup;
 697
 698        /* len > 0 && len % 4 == 0 guaranteed by cxacru_cm() */
 699        len = ret / 4;
 700        for (offb = 0; offb < len; ) {
 701                int l = le32_to_cpu(buf[offb++]);
 702
 703                if (l < 0 || l > stride || l > (len - offb) / 2) {
 704                        if (printk_ratelimit())
 705                                usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n",
 706                                        cm, l);
 707                        ret = -EIO;
 708                        goto cleanup;
 709                }
 710                while (l--) {
 711                        offd = le32_to_cpu(buf[offb++]);
 712                        if (offd >= size) {
 713                                if (printk_ratelimit())
 714                                        usb_err(instance->usbatm, "wrong index %#x in response to cm %#x\n",
 715                                                offd, cm);
 716                                ret = -EIO;
 717                                goto cleanup;
 718                        }
 719                        data[offd] = le32_to_cpu(buf[offb++]);
 720                }
 721        }
 722
 723        ret = 0;
 724
 725cleanup:
 726        kfree(buf);
 727        return ret;
 728}
 729
 730static int cxacru_card_status(struct cxacru_data *instance)
 731{
 732        int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
 733
 734        if (ret < 0) {          /* firmware not loaded */
 735                usb_dbg(instance->usbatm, "cxacru_adsl_start: CARD_GET_STATUS returned %d\n", ret);
 736                return ret;
 737        }
 738        return 0;
 739}
 740
 741static void cxacru_remove_device_files(struct usbatm_data *usbatm_instance,
 742                struct atm_dev *atm_dev)
 743{
 744        struct usb_interface *intf = usbatm_instance->usb_intf;
 745
 746        #define CXACRU_DEVICE_REMOVE_FILE(_name) \
 747                device_remove_file(&intf->dev, &dev_attr_##_name);
 748        CXACRU_ALL_FILES(REMOVE);
 749        #undef CXACRU_DEVICE_REMOVE_FILE
 750}
 751
 752static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
 753                struct atm_dev *atm_dev)
 754{
 755        struct cxacru_data *instance = usbatm_instance->driver_data;
 756        struct usb_interface *intf = usbatm_instance->usb_intf;
 757        int ret;
 758        int start_polling = 1;
 759
 760        dev_dbg(&intf->dev, "%s\n", __func__);
 761
 762        /* Read MAC address */
 763        ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0,
 764                        atm_dev->esi, sizeof(atm_dev->esi));
 765        if (ret < 0) {
 766                atm_err(usbatm_instance, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret);
 767                return ret;
 768        }
 769
 770        #define CXACRU_DEVICE_CREATE_FILE(_name) \
 771                ret = device_create_file(&intf->dev, &dev_attr_##_name); \
 772                if (unlikely(ret)) \
 773                        goto fail_sysfs;
 774        CXACRU_ALL_FILES(CREATE);
 775        #undef CXACRU_DEVICE_CREATE_FILE
 776
 777        /* start ADSL */
 778        mutex_lock(&instance->adsl_state_serialize);
 779        ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
 780        if (ret < 0)
 781                atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
 782
 783        /* Start status polling */
 784        mutex_lock(&instance->poll_state_serialize);
 785        switch (instance->poll_state) {
 786        case CXPOLL_STOPPED:
 787                /* start polling */
 788                instance->poll_state = CXPOLL_POLLING;
 789                break;
 790
 791        case CXPOLL_STOPPING:
 792                /* abort stop request */
 793                instance->poll_state = CXPOLL_POLLING;
 794                /* fall through */
 795        case CXPOLL_POLLING:
 796        case CXPOLL_SHUTDOWN:
 797                /* don't start polling */
 798                start_polling = 0;
 799        }
 800        mutex_unlock(&instance->poll_state_serialize);
 801        mutex_unlock(&instance->adsl_state_serialize);
 802
 803        printk(KERN_INFO "%s%d: %s %pM\n", atm_dev->type, atm_dev->number,
 804                        usbatm_instance->description, atm_dev->esi);
 805
 806        if (start_polling)
 807                cxacru_poll_status(&instance->poll_work.work);
 808        return 0;
 809
 810fail_sysfs:
 811        usb_err(usbatm_instance, "cxacru_atm_start: device_create_file failed (%d)\n", ret);
 812        cxacru_remove_device_files(usbatm_instance, atm_dev);
 813        return ret;
 814}
 815
 816static void cxacru_poll_status(struct work_struct *work)
 817{
 818        struct cxacru_data *instance =
 819                container_of(work, struct cxacru_data, poll_work.work);
 820        u32 buf[CXINF_MAX] = {};
 821        struct usbatm_data *usbatm = instance->usbatm;
 822        struct atm_dev *atm_dev = usbatm->atm_dev;
 823        int keep_polling = 1;
 824        int ret;
 825
 826        ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX);
 827        if (ret < 0) {
 828                if (ret != -ESHUTDOWN)
 829                        atm_warn(usbatm, "poll status: error %d\n", ret);
 830
 831                mutex_lock(&instance->poll_state_serialize);
 832                if (instance->poll_state != CXPOLL_SHUTDOWN) {
 833                        instance->poll_state = CXPOLL_STOPPED;
 834
 835                        if (ret != -ESHUTDOWN)
 836                                atm_warn(usbatm, "polling disabled, set adsl_state"
 837                                                " to 'start' or 'poll' to resume\n");
 838                }
 839                mutex_unlock(&instance->poll_state_serialize);
 840                goto reschedule;
 841        }
 842
 843        memcpy(instance->card_info, buf, sizeof(instance->card_info));
 844
 845        if (instance->adsl_status != buf[CXINF_LINE_STARTABLE]) {
 846                instance->adsl_status = buf[CXINF_LINE_STARTABLE];
 847
 848                switch (instance->adsl_status) {
 849                case 0:
 850                        atm_printk(KERN_INFO, usbatm, "ADSL state: running\n");
 851                        break;
 852
 853                case 1:
 854                        atm_printk(KERN_INFO, usbatm, "ADSL state: stopped\n");
 855                        break;
 856
 857                default:
 858                        atm_printk(KERN_INFO, usbatm, "Unknown adsl status %02x\n", instance->adsl_status);
 859                        break;
 860                }
 861        }
 862
 863        if (instance->line_status == buf[CXINF_LINE_STATUS])
 864                goto reschedule;
 865
 866        instance->line_status = buf[CXINF_LINE_STATUS];
 867        switch (instance->line_status) {
 868        case 0:
 869                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
 870                atm_info(usbatm, "ADSL line: down\n");
 871                break;
 872
 873        case 1:
 874                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
 875                atm_info(usbatm, "ADSL line: attempting to activate\n");
 876                break;
 877
 878        case 2:
 879                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
 880                atm_info(usbatm, "ADSL line: training\n");
 881                break;
 882
 883        case 3:
 884                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
 885                atm_info(usbatm, "ADSL line: channel analysis\n");
 886                break;
 887
 888        case 4:
 889                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
 890                atm_info(usbatm, "ADSL line: exchange\n");
 891                break;
 892
 893        case 5:
 894                atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424;
 895                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_FOUND);
 896
 897                atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n",
 898                     buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]);
 899                break;
 900
 901        case 6:
 902                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
 903                atm_info(usbatm, "ADSL line: waiting\n");
 904                break;
 905
 906        case 7:
 907                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
 908                atm_info(usbatm, "ADSL line: initializing\n");
 909                break;
 910
 911        default:
 912                atm_dev_signal_change(atm_dev, ATM_PHY_SIG_UNKNOWN);
 913                atm_info(usbatm, "Unknown line state %02x\n", instance->line_status);
 914                break;
 915        }
 916reschedule:
 917
 918        mutex_lock(&instance->poll_state_serialize);
 919        if (instance->poll_state == CXPOLL_STOPPING &&
 920                                instance->adsl_status == 1 && /* stopped */
 921                                instance->line_status == 0) /* down */
 922                instance->poll_state = CXPOLL_STOPPED;
 923
 924        if (instance->poll_state == CXPOLL_STOPPED)
 925                keep_polling = 0;
 926        mutex_unlock(&instance->poll_state_serialize);
 927
 928        if (keep_polling)
 929                schedule_delayed_work(&instance->poll_work,
 930                                round_jiffies_relative(POLL_INTERVAL*HZ));
 931}
 932
 933static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw,
 934                     u8 code1, u8 code2, u32 addr, const u8 *data, int size)
 935{
 936        int ret;
 937        u8 *buf;
 938        int offd, offb;
 939        const int stride = CMD_PACKET_SIZE - 8;
 940
 941        buf = (u8 *) __get_free_page(GFP_KERNEL);
 942        if (!buf)
 943                return -ENOMEM;
 944
 945        offb = offd = 0;
 946        do {
 947                int l = min_t(int, stride, size - offd);
 948
 949                buf[offb++] = fw;
 950                buf[offb++] = l;
 951                buf[offb++] = code1;
 952                buf[offb++] = code2;
 953                put_unaligned(cpu_to_le32(addr), (__le32 *)(buf + offb));
 954                offb += 4;
 955                addr += l;
 956                if (l)
 957                        memcpy(buf + offb, data + offd, l);
 958                if (l < stride)
 959                        memset(buf + offb + l, 0, stride - l);
 960                offb += stride;
 961                offd += stride;
 962                if ((offb >= PAGE_SIZE) || (offd >= size)) {
 963                        ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD),
 964                                           buf, offb, NULL, CMD_TIMEOUT);
 965                        if (ret < 0) {
 966                                dev_dbg(&usb_dev->dev, "sending fw %#x failed\n", fw);
 967                                goto cleanup;
 968                        }
 969                        offb = 0;
 970                }
 971        } while (offd < size);
 972        dev_dbg(&usb_dev->dev, "sent fw %#x\n", fw);
 973
 974        ret = 0;
 975
 976cleanup:
 977        free_page((unsigned long) buf);
 978        return ret;
 979}
 980
 981static void cxacru_upload_firmware(struct cxacru_data *instance,
 982                                   const struct firmware *fw,
 983                                   const struct firmware *bp)
 984{
 985        int ret;
 986        struct usbatm_data *usbatm = instance->usbatm;
 987        struct usb_device *usb_dev = usbatm->usb_dev;
 988        __le16 signature[] = { usb_dev->descriptor.idVendor,
 989                               usb_dev->descriptor.idProduct };
 990        __le32 val;
 991
 992        usb_dbg(usbatm, "%s\n", __func__);
 993
 994        /* FirmwarePllFClkValue */
 995        val = cpu_to_le32(instance->modem_type->pll_f_clk);
 996        ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
 997        if (ret) {
 998                usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret);
 999                return;
1000        }
1001
1002        /* FirmwarePllBClkValue */
1003        val = cpu_to_le32(instance->modem_type->pll_b_clk);
1004        ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
1005        if (ret) {
1006                usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret);
1007                return;
1008        }
1009
1010        /* Enable SDRAM */
1011        val = cpu_to_le32(SDRAM_ENA);
1012        ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
1013        if (ret) {
1014                usb_err(usbatm, "Enable SDRAM failed: %d\n", ret);
1015                return;
1016        }
1017
1018        /* Firmware */
1019        usb_info(usbatm, "loading firmware\n");
1020        ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
1021        if (ret) {
1022                usb_err(usbatm, "Firmware upload failed: %d\n", ret);
1023                return;
1024        }
1025
1026        /* Boot ROM patch */
1027        if (instance->modem_type->boot_rom_patch) {
1028                usb_info(usbatm, "loading boot ROM patch\n");
1029                ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size);
1030                if (ret) {
1031                        usb_err(usbatm, "Boot ROM patching failed: %d\n", ret);
1032                        return;
1033                }
1034        }
1035
1036        /* Signature */
1037        ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4);
1038        if (ret) {
1039                usb_err(usbatm, "Signature storing failed: %d\n", ret);
1040                return;
1041        }
1042
1043        usb_info(usbatm, "starting device\n");
1044        if (instance->modem_type->boot_rom_patch) {
1045                val = cpu_to_le32(BR_ADDR);
1046                ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
1047        } else {
1048                ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
1049        }
1050        if (ret) {
1051                usb_err(usbatm, "Passing control to firmware failed: %d\n", ret);
1052                return;
1053        }
1054
1055        /* Delay to allow firmware to start up. */
1056        msleep_interruptible(1000);
1057
1058        usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD));
1059        usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD));
1060        usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA));
1061        usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA));
1062
1063        ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
1064        if (ret < 0) {
1065                usb_err(usbatm, "modem failed to initialize: %d\n", ret);
1066                return;
1067        }
1068}
1069
1070static int cxacru_find_firmware(struct cxacru_data *instance,
1071                                char *phase, const struct firmware **fw_p)
1072{
1073        struct usbatm_data *usbatm = instance->usbatm;
1074        struct device *dev = &usbatm->usb_intf->dev;
1075        char buf[16];
1076
1077        sprintf(buf, "cxacru-%s.bin", phase);
1078        usb_dbg(usbatm, "cxacru_find_firmware: looking for %s\n", buf);
1079
1080        if (request_firmware(fw_p, buf, dev)) {
1081                usb_dbg(usbatm, "no stage %s firmware found\n", phase);
1082                return -ENOENT;
1083        }
1084
1085        usb_info(usbatm, "found firmware %s\n", buf);
1086
1087        return 0;
1088}
1089
1090static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
1091                             struct usb_interface *usb_intf)
1092{
1093        const struct firmware *fw, *bp;
1094        struct cxacru_data *instance = usbatm_instance->driver_data;
1095        int ret = cxacru_find_firmware(instance, "fw", &fw);
1096
1097        if (ret) {
1098                usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n");
1099                return ret;
1100        }
1101
1102        if (instance->modem_type->boot_rom_patch) {
1103                ret = cxacru_find_firmware(instance, "bp", &bp);
1104                if (ret) {
1105                        usb_warn(usbatm_instance, "boot ROM patch (cxacru-bp.bin) unavailable (system misconfigured?)\n");
1106                        release_firmware(fw);
1107                        return ret;
1108                }
1109        }
1110
1111        cxacru_upload_firmware(instance, fw, bp);
1112
1113        if (instance->modem_type->boot_rom_patch)
1114                release_firmware(bp);
1115        release_firmware(fw);
1116
1117        ret = cxacru_card_status(instance);
1118        if (ret)
1119                usb_dbg(usbatm_instance, "modem initialisation failed\n");
1120        else
1121                usb_dbg(usbatm_instance, "done setting up the modem\n");
1122
1123        return ret;
1124}
1125
1126static int cxacru_bind(struct usbatm_data *usbatm_instance,
1127                       struct usb_interface *intf, const struct usb_device_id *id)
1128{
1129        struct cxacru_data *instance;
1130        struct usb_device *usb_dev = interface_to_usbdev(intf);
1131        struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD];
1132        int ret;
1133
1134        /* instance init */
1135        instance = kzalloc(sizeof(*instance), GFP_KERNEL);
1136        if (!instance)
1137                return -ENOMEM;
1138
1139        instance->usbatm = usbatm_instance;
1140        instance->modem_type = (struct cxacru_modem_type *) id->driver_info;
1141
1142        mutex_init(&instance->poll_state_serialize);
1143        instance->poll_state = CXPOLL_STOPPED;
1144        instance->line_status = -1;
1145        instance->adsl_status = -1;
1146
1147        mutex_init(&instance->adsl_state_serialize);
1148
1149        instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL);
1150        if (!instance->rcv_buf) {
1151                usb_dbg(usbatm_instance, "cxacru_bind: no memory for rcv_buf\n");
1152                ret = -ENOMEM;
1153                goto fail;
1154        }
1155        instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL);
1156        if (!instance->snd_buf) {
1157                usb_dbg(usbatm_instance, "cxacru_bind: no memory for snd_buf\n");
1158                ret = -ENOMEM;
1159                goto fail;
1160        }
1161        instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL);
1162        if (!instance->rcv_urb) {
1163                ret = -ENOMEM;
1164                goto fail;
1165        }
1166        instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL);
1167        if (!instance->snd_urb) {
1168                ret = -ENOMEM;
1169                goto fail;
1170        }
1171
1172        if (!cmd_ep) {
1173                usb_dbg(usbatm_instance, "cxacru_bind: no command endpoint\n");
1174                ret = -ENODEV;
1175                goto fail;
1176        }
1177
1178        if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1179                        == USB_ENDPOINT_XFER_INT) {
1180                usb_fill_int_urb(instance->rcv_urb,
1181                        usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
1182                        instance->rcv_buf, PAGE_SIZE,
1183                        cxacru_blocking_completion, &instance->rcv_done, 1);
1184
1185                usb_fill_int_urb(instance->snd_urb,
1186                        usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
1187                        instance->snd_buf, PAGE_SIZE,
1188                        cxacru_blocking_completion, &instance->snd_done, 4);
1189        } else {
1190                usb_fill_bulk_urb(instance->rcv_urb,
1191                        usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD),
1192                        instance->rcv_buf, PAGE_SIZE,
1193                        cxacru_blocking_completion, &instance->rcv_done);
1194
1195                usb_fill_bulk_urb(instance->snd_urb,
1196                        usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD),
1197                        instance->snd_buf, PAGE_SIZE,
1198                        cxacru_blocking_completion, &instance->snd_done);
1199        }
1200
1201        mutex_init(&instance->cm_serialize);
1202
1203        INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status);
1204
1205        usbatm_instance->driver_data = instance;
1206
1207        usbatm_instance->flags = (cxacru_card_status(instance) ? 0 : UDSL_SKIP_HEAVY_INIT);
1208
1209        return 0;
1210
1211 fail:
1212        free_page((unsigned long) instance->snd_buf);
1213        free_page((unsigned long) instance->rcv_buf);
1214        usb_free_urb(instance->snd_urb);
1215        usb_free_urb(instance->rcv_urb);
1216        kfree(instance);
1217
1218        return ret;
1219}
1220
1221static void cxacru_unbind(struct usbatm_data *usbatm_instance,
1222                struct usb_interface *intf)
1223{
1224        struct cxacru_data *instance = usbatm_instance->driver_data;
1225        int is_polling = 1;
1226
1227        usb_dbg(usbatm_instance, "cxacru_unbind entered\n");
1228
1229        if (!instance) {
1230                usb_dbg(usbatm_instance, "cxacru_unbind: NULL instance!\n");
1231                return;
1232        }
1233
1234        mutex_lock(&instance->poll_state_serialize);
1235        BUG_ON(instance->poll_state == CXPOLL_SHUTDOWN);
1236
1237        /* ensure that status polling continues unless
1238         * it has already stopped */
1239        if (instance->poll_state == CXPOLL_STOPPED)
1240                is_polling = 0;
1241
1242        /* stop polling from being stopped or started */
1243        instance->poll_state = CXPOLL_SHUTDOWN;
1244        mutex_unlock(&instance->poll_state_serialize);
1245
1246        if (is_polling)
1247                cancel_delayed_work_sync(&instance->poll_work);
1248
1249        usb_kill_urb(instance->snd_urb);
1250        usb_kill_urb(instance->rcv_urb);
1251        usb_free_urb(instance->snd_urb);
1252        usb_free_urb(instance->rcv_urb);
1253
1254        free_page((unsigned long) instance->snd_buf);
1255        free_page((unsigned long) instance->rcv_buf);
1256
1257        kfree(instance);
1258
1259        usbatm_instance->driver_data = NULL;
1260}
1261
1262static const struct cxacru_modem_type cxacru_cafe = {
1263        .pll_f_clk = 0x02d874df,
1264        .pll_b_clk = 0x0196a51a,
1265        .boot_rom_patch = 1,
1266};
1267
1268static const struct cxacru_modem_type cxacru_cb00 = {
1269        .pll_f_clk = 0x5,
1270        .pll_b_clk = 0x3,
1271        .boot_rom_patch = 0,
1272};
1273
1274static const struct usb_device_id cxacru_usb_ids[] = {
1275        { /* V = Conexant                       P = ADSL modem (Euphrates project)      */
1276                USB_DEVICE(0x0572, 0xcafe),     .driver_info = (unsigned long) &cxacru_cafe
1277        },
1278        { /* V = Conexant                       P = ADSL modem (Hasbani project)        */
1279                USB_DEVICE(0x0572, 0xcb00),     .driver_info = (unsigned long) &cxacru_cb00
1280        },
1281        { /* V = Conexant                       P = ADSL modem                          */
1282                USB_DEVICE(0x0572, 0xcb01),     .driver_info = (unsigned long) &cxacru_cb00
1283        },
1284        { /* V = Conexant                       P = ADSL modem (Well PTI-800) */
1285                USB_DEVICE(0x0572, 0xcb02),     .driver_info = (unsigned long) &cxacru_cb00
1286        },
1287        { /* V = Conexant                       P = ADSL modem                          */
1288                USB_DEVICE(0x0572, 0xcb06),     .driver_info = (unsigned long) &cxacru_cb00
1289        },
1290        { /* V = Conexant                       P = ADSL modem (ZTE ZXDSL 852)          */
1291                USB_DEVICE(0x0572, 0xcb07),     .driver_info = (unsigned long) &cxacru_cb00
1292        },
1293        { /* V = Olitec                         P = ADSL modem version 2                */
1294                USB_DEVICE(0x08e3, 0x0100),     .driver_info = (unsigned long) &cxacru_cafe
1295        },
1296        { /* V = Olitec                         P = ADSL modem version 3                */
1297                USB_DEVICE(0x08e3, 0x0102),     .driver_info = (unsigned long) &cxacru_cb00
1298        },
1299        { /* V = Trust/Amigo Technology Co.     P = AMX-CA86U                           */
1300                USB_DEVICE(0x0eb0, 0x3457),     .driver_info = (unsigned long) &cxacru_cafe
1301        },
1302        { /* V = Zoom                           P = 5510                                */
1303                USB_DEVICE(0x1803, 0x5510),     .driver_info = (unsigned long) &cxacru_cb00
1304        },
1305        { /* V = Draytek                        P = Vigor 318                           */
1306                USB_DEVICE(0x0675, 0x0200),     .driver_info = (unsigned long) &cxacru_cb00
1307        },
1308        { /* V = Zyxel                          P = 630-C1 aka OMNI ADSL USB (Annex A)  */
1309                USB_DEVICE(0x0586, 0x330a),     .driver_info = (unsigned long) &cxacru_cb00
1310        },
1311        { /* V = Zyxel                          P = 630-C3 aka OMNI ADSL USB (Annex B)  */
1312                USB_DEVICE(0x0586, 0x330b),     .driver_info = (unsigned long) &cxacru_cb00
1313        },
1314        { /* V = Aethra                         P = Starmodem UM1020                    */
1315                USB_DEVICE(0x0659, 0x0020),     .driver_info = (unsigned long) &cxacru_cb00
1316        },
1317        { /* V = Aztech Systems                 P = ? AKA Pirelli AUA-010               */
1318                USB_DEVICE(0x0509, 0x0812),     .driver_info = (unsigned long) &cxacru_cb00
1319        },
1320        { /* V = Netopia                        P = Cayman 3341(Annex A)/3351(Annex B)  */
1321                USB_DEVICE(0x100d, 0xcb01),     .driver_info = (unsigned long) &cxacru_cb00
1322        },
1323        { /* V = Netopia                        P = Cayman 3342(Annex A)/3352(Annex B)  */
1324                USB_DEVICE(0x100d, 0x3342),     .driver_info = (unsigned long) &cxacru_cb00
1325        },
1326        {}
1327};
1328
1329MODULE_DEVICE_TABLE(usb, cxacru_usb_ids);
1330
1331static struct usbatm_driver cxacru_driver = {
1332        .driver_name    = cxacru_driver_name,
1333        .bind           = cxacru_bind,
1334        .heavy_init     = cxacru_heavy_init,
1335        .unbind         = cxacru_unbind,
1336        .atm_start      = cxacru_atm_start,
1337        .atm_stop       = cxacru_remove_device_files,
1338        .bulk_in        = CXACRU_EP_DATA,
1339        .bulk_out       = CXACRU_EP_DATA,
1340        .rx_padding     = 3,
1341        .tx_padding     = 11,
1342};
1343
1344static int cxacru_usb_probe(struct usb_interface *intf,
1345                const struct usb_device_id *id)
1346{
1347        struct usb_device *usb_dev = interface_to_usbdev(intf);
1348        char buf[15];
1349
1350        /* Avoid ADSL routers (cx82310_eth).
1351         * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD".
1352         */
1353        if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC
1354                        && usb_string(usb_dev, usb_dev->descriptor.iProduct,
1355                                buf, sizeof(buf)) > 0) {
1356                if (!strcmp(buf, "USB NET CARD")) {
1357                        dev_info(&intf->dev, "ignoring cx82310_eth device\n");
1358                        return -ENODEV;
1359                }
1360        }
1361
1362        return usbatm_usb_probe(intf, id, &cxacru_driver);
1363}
1364
1365static struct usb_driver cxacru_usb_driver = {
1366        .name           = cxacru_driver_name,
1367        .probe          = cxacru_usb_probe,
1368        .disconnect     = usbatm_usb_disconnect,
1369        .id_table       = cxacru_usb_ids
1370};
1371
1372module_usb_driver(cxacru_usb_driver);
1373
1374MODULE_AUTHOR(DRIVER_AUTHOR);
1375MODULE_DESCRIPTION(DRIVER_DESC);
1376MODULE_LICENSE("GPL");
1377