Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /******************************************************************************
0003  *  cxacru.c  -  driver for USB ADSL modems based on
0004  *               Conexant AccessRunner chipset
0005  *
0006  *  Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan
0007  *  Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru)
0008  *  Copyright (C) 2007 Simon Arlott
0009  *  Copyright (C) 2009 Simon Arlott
0010  ******************************************************************************/
0011 
0012 /*
0013  *  Credit is due for Josep Comas, who created the original patch to speedtch.c
0014  *  to support the different padding used by the AccessRunner (now generalized
0015  *  into usbatm), and the userspace firmware loading utility.
0016  */
0017 
0018 #include <linux/module.h>
0019 #include <linux/moduleparam.h>
0020 #include <linux/kernel.h>
0021 #include <linux/timer.h>
0022 #include <linux/errno.h>
0023 #include <linux/slab.h>
0024 #include <linux/device.h>
0025 #include <linux/firmware.h>
0026 #include <linux/mutex.h>
0027 #include <asm/unaligned.h>
0028 
0029 #include "usbatm.h"
0030 
0031 #define DRIVER_AUTHOR   "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott"
0032 #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver"
0033 
0034 static const char cxacru_driver_name[] = "cxacru";
0035 
0036 #define CXACRU_EP_CMD       0x01    /* Bulk/interrupt in/out */
0037 #define CXACRU_EP_DATA      0x02    /* Bulk in/out */
0038 
0039 #define CMD_PACKET_SIZE     64  /* Should be maxpacket(ep)? */
0040 #define CMD_MAX_CONFIG      ((CMD_PACKET_SIZE / 4 - 1) / 2)
0041 
0042 /* Addresses */
0043 #define PLLFCLK_ADDR    0x00350068
0044 #define PLLBCLK_ADDR    0x0035006c
0045 #define SDRAMEN_ADDR    0x00350010
0046 #define FW_ADDR     0x00801000
0047 #define BR_ADDR     0x00180600
0048 #define SIG_ADDR    0x00180500
0049 #define BR_STACK_ADDR   0x00187f10
0050 
0051 /* Values */
0052 #define SDRAM_ENA   0x1
0053 
0054 #define CMD_TIMEOUT 2000    /* msecs */
0055 #define POLL_INTERVAL   1   /* secs */
0056 
0057 /* commands for interaction with the modem through the control channel before
0058  * firmware is loaded  */
0059 enum cxacru_fw_request {
0060     FW_CMD_ERR,
0061     FW_GET_VER,
0062     FW_READ_MEM,
0063     FW_WRITE_MEM,
0064     FW_RMW_MEM,
0065     FW_CHECKSUM_MEM,
0066     FW_GOTO_MEM,
0067 };
0068 
0069 /* commands for interaction with the modem through the control channel once
0070  * firmware is loaded  */
0071 enum cxacru_cm_request {
0072     CM_REQUEST_UNDEFINED = 0x80,
0073     CM_REQUEST_TEST,
0074     CM_REQUEST_CHIP_GET_MAC_ADDRESS,
0075     CM_REQUEST_CHIP_GET_DP_VERSIONS,
0076     CM_REQUEST_CHIP_ADSL_LINE_START,
0077     CM_REQUEST_CHIP_ADSL_LINE_STOP,
0078     CM_REQUEST_CHIP_ADSL_LINE_GET_STATUS,
0079     CM_REQUEST_CHIP_ADSL_LINE_GET_SPEED,
0080     CM_REQUEST_CARD_INFO_GET,
0081     CM_REQUEST_CARD_DATA_GET,
0082     CM_REQUEST_CARD_DATA_SET,
0083     CM_REQUEST_COMMAND_HW_IO,
0084     CM_REQUEST_INTERFACE_HW_IO,
0085     CM_REQUEST_CARD_SERIAL_DATA_PATH_GET,
0086     CM_REQUEST_CARD_SERIAL_DATA_PATH_SET,
0087     CM_REQUEST_CARD_CONTROLLER_VERSION_GET,
0088     CM_REQUEST_CARD_GET_STATUS,
0089     CM_REQUEST_CARD_GET_MAC_ADDRESS,
0090     CM_REQUEST_CARD_GET_DATA_LINK_STATUS,
0091     CM_REQUEST_MAX,
0092 };
0093 
0094 /* commands for interaction with the flash memory
0095  *
0096  * read:  response is the contents of the first 60 bytes of flash memory
0097  * write: request contains the 60 bytes of data to write to flash memory
0098  *        response is the contents of the first 60 bytes of flash memory
0099  *
0100  * layout: PP PP VV VV  MM MM MM MM  MM MM ?? ??  SS SS SS SS  SS SS SS SS
0101  *         SS SS SS SS  SS SS SS SS  00 00 00 00  00 00 00 00  00 00 00 00
0102  *         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
0103  *
0104  *   P: le16  USB Product ID
0105  *   V: le16  USB Vendor ID
0106  *   M: be48  MAC Address
0107  *   S: le16  ASCII Serial Number
0108  */
0109 enum cxacru_cm_flash {
0110     CM_FLASH_READ = 0xa1,
0111     CM_FLASH_WRITE = 0xa2
0112 };
0113 
0114 /* reply codes to the commands above */
0115 enum cxacru_cm_status {
0116     CM_STATUS_UNDEFINED,
0117     CM_STATUS_SUCCESS,
0118     CM_STATUS_ERROR,
0119     CM_STATUS_UNSUPPORTED,
0120     CM_STATUS_UNIMPLEMENTED,
0121     CM_STATUS_PARAMETER_ERROR,
0122     CM_STATUS_DBG_LOOPBACK,
0123     CM_STATUS_MAX,
0124 };
0125 
0126 /* indices into CARD_INFO_GET return array */
0127 enum cxacru_info_idx {
0128     CXINF_DOWNSTREAM_RATE,
0129     CXINF_UPSTREAM_RATE,
0130     CXINF_LINK_STATUS,
0131     CXINF_LINE_STATUS,
0132     CXINF_MAC_ADDRESS_HIGH,
0133     CXINF_MAC_ADDRESS_LOW,
0134     CXINF_UPSTREAM_SNR_MARGIN,
0135     CXINF_DOWNSTREAM_SNR_MARGIN,
0136     CXINF_UPSTREAM_ATTENUATION,
0137     CXINF_DOWNSTREAM_ATTENUATION,
0138     CXINF_TRANSMITTER_POWER,
0139     CXINF_UPSTREAM_BITS_PER_FRAME,
0140     CXINF_DOWNSTREAM_BITS_PER_FRAME,
0141     CXINF_STARTUP_ATTEMPTS,
0142     CXINF_UPSTREAM_CRC_ERRORS,
0143     CXINF_DOWNSTREAM_CRC_ERRORS,
0144     CXINF_UPSTREAM_FEC_ERRORS,
0145     CXINF_DOWNSTREAM_FEC_ERRORS,
0146     CXINF_UPSTREAM_HEC_ERRORS,
0147     CXINF_DOWNSTREAM_HEC_ERRORS,
0148     CXINF_LINE_STARTABLE,
0149     CXINF_MODULATION,
0150     CXINF_ADSL_HEADEND,
0151     CXINF_ADSL_HEADEND_ENVIRONMENT,
0152     CXINF_CONTROLLER_VERSION,
0153     /* dunno what the missing two mean */
0154     CXINF_MAX = 0x1c,
0155 };
0156 
0157 enum cxacru_poll_state {
0158     CXPOLL_STOPPING,
0159     CXPOLL_STOPPED,
0160     CXPOLL_POLLING,
0161     CXPOLL_SHUTDOWN
0162 };
0163 
0164 struct cxacru_modem_type {
0165     u32 pll_f_clk;
0166     u32 pll_b_clk;
0167     int boot_rom_patch;
0168 };
0169 
0170 struct cxacru_data {
0171     struct usbatm_data *usbatm;
0172 
0173     const struct cxacru_modem_type *modem_type;
0174 
0175     int line_status;
0176     struct mutex adsl_state_serialize;
0177     int adsl_status;
0178     struct delayed_work poll_work;
0179     u32 card_info[CXINF_MAX];
0180     struct mutex poll_state_serialize;
0181     enum cxacru_poll_state poll_state;
0182 
0183     /* control handles */
0184     struct mutex cm_serialize;
0185     u8 *rcv_buf;
0186     u8 *snd_buf;
0187     struct urb *rcv_urb;
0188     struct urb *snd_urb;
0189     struct completion rcv_done;
0190     struct completion snd_done;
0191 };
0192 
0193 static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
0194     u8 *wdata, int wsize, u8 *rdata, int rsize);
0195 static void cxacru_poll_status(struct work_struct *work);
0196 
0197 /* Card info exported through sysfs */
0198 #define CXACRU__ATTR_INIT(_name) \
0199 static DEVICE_ATTR_RO(_name)
0200 
0201 #define CXACRU_CMD_INIT(_name) \
0202 static DEVICE_ATTR_RW(_name)
0203 
0204 #define CXACRU_SET_INIT(_name) \
0205 static DEVICE_ATTR_WO(_name)
0206 
0207 #define CXACRU_ATTR_INIT(_value, _type, _name) \
0208 static ssize_t _name##_show(struct device *dev, \
0209     struct device_attribute *attr, char *buf) \
0210 { \
0211     struct cxacru_data *instance = to_usbatm_driver_data(\
0212         to_usb_interface(dev)); \
0213 \
0214     if (instance == NULL) \
0215         return -ENODEV; \
0216 \
0217     return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \
0218 } \
0219 CXACRU__ATTR_INIT(_name)
0220 
0221 #define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name)
0222 #define CXACRU_CMD_CREATE(_name)          CXACRU_DEVICE_CREATE_FILE(_name)
0223 #define CXACRU_SET_CREATE(_name)          CXACRU_DEVICE_CREATE_FILE(_name)
0224 #define CXACRU__ATTR_CREATE(_name)        CXACRU_DEVICE_CREATE_FILE(_name)
0225 
0226 #define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name)
0227 #define CXACRU_CMD_REMOVE(_name)          CXACRU_DEVICE_REMOVE_FILE(_name)
0228 #define CXACRU_SET_REMOVE(_name)          CXACRU_DEVICE_REMOVE_FILE(_name)
0229 #define CXACRU__ATTR_REMOVE(_name)        CXACRU_DEVICE_REMOVE_FILE(_name)
0230 
0231 static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf)
0232 {
0233     return sprintf(buf, "%u\n", value);
0234 }
0235 
0236 static ssize_t cxacru_sysfs_showattr_s8(s8 value, char *buf)
0237 {
0238     return sprintf(buf, "%d\n", value);
0239 }
0240 
0241 static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf)
0242 {
0243     if (likely(value >= 0)) {
0244         return snprintf(buf, PAGE_SIZE, "%u.%02u\n",
0245                     value / 100, value % 100);
0246     } else {
0247         value = -value;
0248         return snprintf(buf, PAGE_SIZE, "-%u.%02u\n",
0249                     value / 100, value % 100);
0250     }
0251 }
0252 
0253 static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf)
0254 {
0255     static char *str[] = { "no", "yes" };
0256 
0257     if (unlikely(value >= ARRAY_SIZE(str)))
0258         return sprintf(buf, "%u\n", value);
0259     return sprintf(buf, "%s\n", str[value]);
0260 }
0261 
0262 static ssize_t cxacru_sysfs_showattr_LINK(u32 value, char *buf)
0263 {
0264     static char *str[] = { NULL, "not connected", "connected", "lost" };
0265 
0266     if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
0267         return sprintf(buf, "%u\n", value);
0268     return sprintf(buf, "%s\n", str[value]);
0269 }
0270 
0271 static ssize_t cxacru_sysfs_showattr_LINE(u32 value, char *buf)
0272 {
0273     static char *str[] = { "down", "attempting to activate",
0274         "training", "channel analysis", "exchange", "up",
0275         "waiting", "initialising"
0276     };
0277     if (unlikely(value >= ARRAY_SIZE(str)))
0278         return sprintf(buf, "%u\n", value);
0279     return sprintf(buf, "%s\n", str[value]);
0280 }
0281 
0282 static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf)
0283 {
0284     static char *str[] = {
0285             "",
0286             "ANSI T1.413",
0287             "ITU-T G.992.1 (G.DMT)",
0288             "ITU-T G.992.2 (G.LITE)"
0289     };
0290     if (unlikely(value >= ARRAY_SIZE(str)))
0291         return sprintf(buf, "%u\n", value);
0292     return sprintf(buf, "%s\n", str[value]);
0293 }
0294 
0295 /*
0296  * This could use MAC_ADDRESS_HIGH and MAC_ADDRESS_LOW, but since
0297  * this data is already in atm_dev there's no point.
0298  *
0299  * MAC_ADDRESS_HIGH = 0x????5544
0300  * MAC_ADDRESS_LOW  = 0x33221100
0301  * Where 00-55 are bytes 0-5 of the MAC.
0302  */
0303 static ssize_t mac_address_show(struct device *dev,
0304     struct device_attribute *attr, char *buf)
0305 {
0306     struct cxacru_data *instance = to_usbatm_driver_data(
0307             to_usb_interface(dev));
0308 
0309     if (instance == NULL || instance->usbatm->atm_dev == NULL)
0310         return -ENODEV;
0311 
0312     return sprintf(buf, "%pM\n", instance->usbatm->atm_dev->esi);
0313 }
0314 
0315 static ssize_t adsl_state_show(struct device *dev,
0316     struct device_attribute *attr, char *buf)
0317 {
0318     static char *str[] = { "running", "stopped" };
0319     struct cxacru_data *instance = to_usbatm_driver_data(
0320             to_usb_interface(dev));
0321     u32 value;
0322 
0323     if (instance == NULL)
0324         return -ENODEV;
0325 
0326     value = instance->card_info[CXINF_LINE_STARTABLE];
0327     if (unlikely(value >= ARRAY_SIZE(str)))
0328         return sprintf(buf, "%u\n", value);
0329     return sprintf(buf, "%s\n", str[value]);
0330 }
0331 
0332 static ssize_t adsl_state_store(struct device *dev,
0333     struct device_attribute *attr, const char *buf, size_t count)
0334 {
0335     struct cxacru_data *instance = to_usbatm_driver_data(
0336             to_usb_interface(dev));
0337     int ret;
0338     int poll = -1;
0339     char str_cmd[8];
0340     int len = strlen(buf);
0341 
0342     if (!capable(CAP_NET_ADMIN))
0343         return -EACCES;
0344 
0345     ret = sscanf(buf, "%7s", str_cmd);
0346     if (ret != 1)
0347         return -EINVAL;
0348     ret = 0;
0349 
0350     if (instance == NULL)
0351         return -ENODEV;
0352 
0353     if (mutex_lock_interruptible(&instance->adsl_state_serialize))
0354         return -ERESTARTSYS;
0355 
0356     if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) {
0357         ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0);
0358         if (ret < 0) {
0359             atm_err(instance->usbatm, "change adsl state:"
0360                 " CHIP_ADSL_LINE_STOP returned %d\n", ret);
0361 
0362             ret = -EIO;
0363         } else {
0364             ret = len;
0365             poll = CXPOLL_STOPPED;
0366         }
0367     }
0368 
0369     /* Line status is only updated every second
0370      * and the device appears to only react to
0371      * START/STOP every second too. Wait 1.5s to
0372      * be sure that restart will have an effect. */
0373     if (!strcmp(str_cmd, "restart"))
0374         msleep(1500);
0375 
0376     if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) {
0377         ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
0378         if (ret < 0) {
0379             atm_err(instance->usbatm, "change adsl state:"
0380                 " CHIP_ADSL_LINE_START returned %d\n", ret);
0381 
0382             ret = -EIO;
0383         } else {
0384             ret = len;
0385             poll = CXPOLL_POLLING;
0386         }
0387     }
0388 
0389     if (!strcmp(str_cmd, "poll")) {
0390         ret = len;
0391         poll = CXPOLL_POLLING;
0392     }
0393 
0394     if (ret == 0) {
0395         ret = -EINVAL;
0396         poll = -1;
0397     }
0398 
0399     if (poll == CXPOLL_POLLING) {
0400         mutex_lock(&instance->poll_state_serialize);
0401         switch (instance->poll_state) {
0402         case CXPOLL_STOPPED:
0403             /* start polling */
0404             instance->poll_state = CXPOLL_POLLING;
0405             break;
0406 
0407         case CXPOLL_STOPPING:
0408             /* abort stop request */
0409             instance->poll_state = CXPOLL_POLLING;
0410             fallthrough;
0411         case CXPOLL_POLLING:
0412         case CXPOLL_SHUTDOWN:
0413             /* don't start polling */
0414             poll = -1;
0415         }
0416         mutex_unlock(&instance->poll_state_serialize);
0417     } else if (poll == CXPOLL_STOPPED) {
0418         mutex_lock(&instance->poll_state_serialize);
0419         /* request stop */
0420         if (instance->poll_state == CXPOLL_POLLING)
0421             instance->poll_state = CXPOLL_STOPPING;
0422         mutex_unlock(&instance->poll_state_serialize);
0423     }
0424 
0425     mutex_unlock(&instance->adsl_state_serialize);
0426 
0427     if (poll == CXPOLL_POLLING)
0428         cxacru_poll_status(&instance->poll_work.work);
0429 
0430     return ret;
0431 }
0432 
0433 /* CM_REQUEST_CARD_DATA_GET times out, so no show attribute */
0434 
0435 static ssize_t adsl_config_store(struct device *dev,
0436     struct device_attribute *attr, const char *buf, size_t count)
0437 {
0438     struct cxacru_data *instance = to_usbatm_driver_data(
0439             to_usb_interface(dev));
0440     int len = strlen(buf);
0441     int ret, pos, num;
0442     __le32 data[CMD_PACKET_SIZE / 4];
0443 
0444     if (!capable(CAP_NET_ADMIN))
0445         return -EACCES;
0446 
0447     if (instance == NULL)
0448         return -ENODEV;
0449 
0450     pos = 0;
0451     num = 0;
0452     while (pos < len) {
0453         int tmp;
0454         u32 index;
0455         u32 value;
0456 
0457         ret = sscanf(buf + pos, "%x=%x%n", &index, &value, &tmp);
0458         if (ret < 2)
0459             return -EINVAL;
0460         if (index > 0x7f)
0461             return -EINVAL;
0462         if (tmp < 0 || tmp > len - pos)
0463             return -EINVAL;
0464         pos += tmp;
0465 
0466         /* skip trailing newline */
0467         if (buf[pos] == '\n' && pos == len-1)
0468             pos++;
0469 
0470         data[num * 2 + 1] = cpu_to_le32(index);
0471         data[num * 2 + 2] = cpu_to_le32(value);
0472         num++;
0473 
0474         /* send config values when data buffer is full
0475          * or no more data
0476          */
0477         if (pos >= len || num >= CMD_MAX_CONFIG) {
0478             char log[CMD_MAX_CONFIG * 12 + 1]; /* %02x=%08x */
0479 
0480             data[0] = cpu_to_le32(num);
0481             ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET,
0482                 (u8 *) data, 4 + num * 8, NULL, 0);
0483             if (ret < 0) {
0484                 atm_err(instance->usbatm,
0485                     "set card data returned %d\n", ret);
0486                 return -EIO;
0487             }
0488 
0489             for (tmp = 0; tmp < num; tmp++)
0490                 snprintf(log + tmp*12, 13, " %02x=%08x",
0491                     le32_to_cpu(data[tmp * 2 + 1]),
0492                     le32_to_cpu(data[tmp * 2 + 2]));
0493             atm_info(instance->usbatm, "config%s\n", log);
0494             num = 0;
0495         }
0496     }
0497 
0498     return len;
0499 }
0500 
0501 /*
0502  * All device attributes are included in CXACRU_ALL_FILES
0503  * so that the same list can be used multiple times:
0504  *     INIT   (define the device attributes)
0505  *     CREATE (create all the device files)
0506  *     REMOVE (remove all the device files)
0507  *
0508  * With the last two being defined as needed in the functions
0509  * they are used in before calling CXACRU_ALL_FILES()
0510  */
0511 #define CXACRU_ALL_FILES(_action) \
0512 CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_RATE,           u32,  downstream_rate); \
0513 CXACRU_ATTR_##_action(CXINF_UPSTREAM_RATE,             u32,  upstream_rate); \
0514 CXACRU_ATTR_##_action(CXINF_LINK_STATUS,               LINK, link_status); \
0515 CXACRU_ATTR_##_action(CXINF_LINE_STATUS,               LINE, line_status); \
0516 CXACRU__ATTR_##_action(                                      mac_address); \
0517 CXACRU_ATTR_##_action(CXINF_UPSTREAM_SNR_MARGIN,       dB,   upstream_snr_margin); \
0518 CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_SNR_MARGIN,     dB,   downstream_snr_margin); \
0519 CXACRU_ATTR_##_action(CXINF_UPSTREAM_ATTENUATION,      dB,   upstream_attenuation); \
0520 CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_ATTENUATION,    dB,   downstream_attenuation); \
0521 CXACRU_ATTR_##_action(CXINF_TRANSMITTER_POWER,         s8,   transmitter_power); \
0522 CXACRU_ATTR_##_action(CXINF_UPSTREAM_BITS_PER_FRAME,   u32,  upstream_bits_per_frame); \
0523 CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_BITS_PER_FRAME, u32,  downstream_bits_per_frame); \
0524 CXACRU_ATTR_##_action(CXINF_STARTUP_ATTEMPTS,          u32,  startup_attempts); \
0525 CXACRU_ATTR_##_action(CXINF_UPSTREAM_CRC_ERRORS,       u32,  upstream_crc_errors); \
0526 CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_CRC_ERRORS,     u32,  downstream_crc_errors); \
0527 CXACRU_ATTR_##_action(CXINF_UPSTREAM_FEC_ERRORS,       u32,  upstream_fec_errors); \
0528 CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_FEC_ERRORS,     u32,  downstream_fec_errors); \
0529 CXACRU_ATTR_##_action(CXINF_UPSTREAM_HEC_ERRORS,       u32,  upstream_hec_errors); \
0530 CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_HEC_ERRORS,     u32,  downstream_hec_errors); \
0531 CXACRU_ATTR_##_action(CXINF_LINE_STARTABLE,            bool, line_startable); \
0532 CXACRU_ATTR_##_action(CXINF_MODULATION,                MODU, modulation); \
0533 CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND,              u32,  adsl_headend); \
0534 CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT,  u32,  adsl_headend_environment); \
0535 CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION,        u32,  adsl_controller_version); \
0536 CXACRU_CMD_##_action(                                        adsl_state); \
0537 CXACRU_SET_##_action(                                        adsl_config);
0538 
0539 CXACRU_ALL_FILES(INIT);
0540 
0541 static struct attribute *cxacru_attrs[] = {
0542     &dev_attr_adsl_config.attr,
0543     &dev_attr_adsl_state.attr,
0544     &dev_attr_adsl_controller_version.attr,
0545     &dev_attr_adsl_headend_environment.attr,
0546     &dev_attr_adsl_headend.attr,
0547     &dev_attr_modulation.attr,
0548     &dev_attr_line_startable.attr,
0549     &dev_attr_downstream_hec_errors.attr,
0550     &dev_attr_upstream_hec_errors.attr,
0551     &dev_attr_downstream_fec_errors.attr,
0552     &dev_attr_upstream_fec_errors.attr,
0553     &dev_attr_downstream_crc_errors.attr,
0554     &dev_attr_upstream_crc_errors.attr,
0555     &dev_attr_startup_attempts.attr,
0556     &dev_attr_downstream_bits_per_frame.attr,
0557     &dev_attr_upstream_bits_per_frame.attr,
0558     &dev_attr_transmitter_power.attr,
0559     &dev_attr_downstream_attenuation.attr,
0560     &dev_attr_upstream_attenuation.attr,
0561     &dev_attr_downstream_snr_margin.attr,
0562     &dev_attr_upstream_snr_margin.attr,
0563     &dev_attr_mac_address.attr,
0564     &dev_attr_line_status.attr,
0565     &dev_attr_link_status.attr,
0566     &dev_attr_upstream_rate.attr,
0567     &dev_attr_downstream_rate.attr,
0568     NULL,
0569 };
0570 ATTRIBUTE_GROUPS(cxacru);
0571 
0572 /* the following three functions are stolen from drivers/usb/core/message.c */
0573 static void cxacru_blocking_completion(struct urb *urb)
0574 {
0575     complete(urb->context);
0576 }
0577 
0578 struct cxacru_timer {
0579     struct timer_list timer;
0580     struct urb *urb;
0581 };
0582 
0583 static void cxacru_timeout_kill(struct timer_list *t)
0584 {
0585     struct cxacru_timer *timer = from_timer(timer, t, timer);
0586 
0587     usb_unlink_urb(timer->urb);
0588 }
0589 
0590 static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
0591                  int *actual_length)
0592 {
0593     struct cxacru_timer timer = {
0594         .urb = urb,
0595     };
0596 
0597     timer_setup_on_stack(&timer.timer, cxacru_timeout_kill, 0);
0598     mod_timer(&timer.timer, jiffies + msecs_to_jiffies(CMD_TIMEOUT));
0599     wait_for_completion(done);
0600     del_timer_sync(&timer.timer);
0601     destroy_timer_on_stack(&timer.timer);
0602 
0603     if (actual_length)
0604         *actual_length = urb->actual_length;
0605     return urb->status; /* must read status after completion */
0606 }
0607 
0608 static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
0609              u8 *wdata, int wsize, u8 *rdata, int rsize)
0610 {
0611     int ret, actlen;
0612     int offb, offd;
0613     const int stride = CMD_PACKET_SIZE - 4;
0614     u8 *wbuf = instance->snd_buf;
0615     u8 *rbuf = instance->rcv_buf;
0616     int wbuflen = ((wsize - 1) / stride + 1) * CMD_PACKET_SIZE;
0617     int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE;
0618 
0619     if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) {
0620         if (printk_ratelimit())
0621             usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n",
0622                 wbuflen, rbuflen);
0623         ret = -ENOMEM;
0624         goto err;
0625     }
0626 
0627     mutex_lock(&instance->cm_serialize);
0628 
0629     /* submit reading urb before the writing one */
0630     init_completion(&instance->rcv_done);
0631     ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL);
0632     if (ret < 0) {
0633         if (printk_ratelimit())
0634             usb_err(instance->usbatm, "submit of read urb for cm %#x failed (%d)\n",
0635                 cm, ret);
0636         goto fail;
0637     }
0638 
0639     memset(wbuf, 0, wbuflen);
0640     /* handle wsize == 0 */
0641     wbuf[0] = cm;
0642     for (offb = offd = 0; offd < wsize; offd += stride, offb += CMD_PACKET_SIZE) {
0643         wbuf[offb] = cm;
0644         memcpy(wbuf + offb + 4, wdata + offd, min_t(int, stride, wsize - offd));
0645     }
0646 
0647     instance->snd_urb->transfer_buffer_length = wbuflen;
0648     init_completion(&instance->snd_done);
0649     ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL);
0650     if (ret < 0) {
0651         if (printk_ratelimit())
0652             usb_err(instance->usbatm, "submit of write urb for cm %#x failed (%d)\n",
0653                 cm, ret);
0654         goto fail;
0655     }
0656 
0657     ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL);
0658     if (ret < 0) {
0659         if (printk_ratelimit())
0660             usb_err(instance->usbatm, "send of cm %#x failed (%d)\n", cm, ret);
0661         goto fail;
0662     }
0663 
0664     ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen);
0665     if (ret < 0) {
0666         if (printk_ratelimit())
0667             usb_err(instance->usbatm, "receive of cm %#x failed (%d)\n", cm, ret);
0668         goto fail;
0669     }
0670     if (actlen % CMD_PACKET_SIZE || !actlen) {
0671         if (printk_ratelimit())
0672             usb_err(instance->usbatm, "invalid response length to cm %#x: %d\n",
0673                 cm, actlen);
0674         ret = -EIO;
0675         goto fail;
0676     }
0677 
0678     /* check the return status and copy the data to the output buffer, if needed */
0679     for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) {
0680         if (rbuf[offb] != cm) {
0681             if (printk_ratelimit())
0682                 usb_err(instance->usbatm, "wrong cm %#x in response to cm %#x\n",
0683                     rbuf[offb], cm);
0684             ret = -EIO;
0685             goto fail;
0686         }
0687         if (rbuf[offb + 1] != CM_STATUS_SUCCESS) {
0688             if (printk_ratelimit())
0689                 usb_err(instance->usbatm, "response to cm %#x failed: %#x\n",
0690                     cm, rbuf[offb + 1]);
0691             ret = -EIO;
0692             goto fail;
0693         }
0694         if (offd >= rsize)
0695             break;
0696         memcpy(rdata + offd, rbuf + offb + 4, min_t(int, stride, rsize - offd));
0697         offd += stride;
0698     }
0699 
0700     ret = offd;
0701     usb_dbg(instance->usbatm, "cm %#x\n", cm);
0702 fail:
0703     mutex_unlock(&instance->cm_serialize);
0704 err:
0705     return ret;
0706 }
0707 
0708 static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_request cm,
0709                    u32 *data, int size)
0710 {
0711     int ret, len;
0712     __le32 *buf;
0713     int offb;
0714     unsigned int offd;
0715     const int stride = CMD_PACKET_SIZE / (4 * 2) - 1;
0716     int buflen =  ((size - 1) / stride + 1 + size * 2) * 4;
0717 
0718     buf = kmalloc(buflen, GFP_KERNEL);
0719     if (!buf)
0720         return -ENOMEM;
0721 
0722     ret = cxacru_cm(instance, cm, NULL, 0, (u8 *) buf, buflen);
0723     if (ret < 0)
0724         goto cleanup;
0725 
0726     /* len > 0 && len % 4 == 0 guaranteed by cxacru_cm() */
0727     len = ret / 4;
0728     for (offb = 0; offb < len; ) {
0729         int l = le32_to_cpu(buf[offb++]);
0730 
0731         if (l < 0 || l > stride || l > (len - offb) / 2) {
0732             if (printk_ratelimit())
0733                 usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n",
0734                     cm, l);
0735             ret = -EIO;
0736             goto cleanup;
0737         }
0738         while (l--) {
0739             offd = le32_to_cpu(buf[offb++]);
0740             if (offd >= size) {
0741                 if (printk_ratelimit())
0742                     usb_err(instance->usbatm, "wrong index %#x in response to cm %#x\n",
0743                         offd, cm);
0744                 ret = -EIO;
0745                 goto cleanup;
0746             }
0747             data[offd] = le32_to_cpu(buf[offb++]);
0748         }
0749     }
0750 
0751     ret = 0;
0752 
0753 cleanup:
0754     kfree(buf);
0755     return ret;
0756 }
0757 
0758 static int cxacru_card_status(struct cxacru_data *instance)
0759 {
0760     int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
0761 
0762     if (ret < 0) {      /* firmware not loaded */
0763         usb_dbg(instance->usbatm, "cxacru_adsl_start: CARD_GET_STATUS returned %d\n", ret);
0764         return ret;
0765     }
0766     return 0;
0767 }
0768 
0769 static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
0770         struct atm_dev *atm_dev)
0771 {
0772     struct cxacru_data *instance = usbatm_instance->driver_data;
0773     struct usb_interface *intf = usbatm_instance->usb_intf;
0774     int ret;
0775     int start_polling = 1;
0776 
0777     dev_dbg(&intf->dev, "%s\n", __func__);
0778 
0779     /* Read MAC address */
0780     ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0,
0781             atm_dev->esi, sizeof(atm_dev->esi));
0782     if (ret < 0) {
0783         atm_err(usbatm_instance, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret);
0784         return ret;
0785     }
0786 
0787     /* start ADSL */
0788     mutex_lock(&instance->adsl_state_serialize);
0789     ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
0790     if (ret < 0)
0791         atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
0792 
0793     /* Start status polling */
0794     mutex_lock(&instance->poll_state_serialize);
0795     switch (instance->poll_state) {
0796     case CXPOLL_STOPPED:
0797         /* start polling */
0798         instance->poll_state = CXPOLL_POLLING;
0799         break;
0800 
0801     case CXPOLL_STOPPING:
0802         /* abort stop request */
0803         instance->poll_state = CXPOLL_POLLING;
0804         fallthrough;
0805     case CXPOLL_POLLING:
0806     case CXPOLL_SHUTDOWN:
0807         /* don't start polling */
0808         start_polling = 0;
0809     }
0810     mutex_unlock(&instance->poll_state_serialize);
0811     mutex_unlock(&instance->adsl_state_serialize);
0812 
0813     if (start_polling)
0814         cxacru_poll_status(&instance->poll_work.work);
0815     return 0;
0816 }
0817 
0818 static void cxacru_poll_status(struct work_struct *work)
0819 {
0820     struct cxacru_data *instance =
0821         container_of(work, struct cxacru_data, poll_work.work);
0822     u32 buf[CXINF_MAX] = {};
0823     struct usbatm_data *usbatm = instance->usbatm;
0824     struct atm_dev *atm_dev = usbatm->atm_dev;
0825     int keep_polling = 1;
0826     int ret;
0827 
0828     ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX);
0829     if (ret < 0) {
0830         if (ret != -ESHUTDOWN)
0831             atm_warn(usbatm, "poll status: error %d\n", ret);
0832 
0833         mutex_lock(&instance->poll_state_serialize);
0834         if (instance->poll_state != CXPOLL_SHUTDOWN) {
0835             instance->poll_state = CXPOLL_STOPPED;
0836 
0837             if (ret != -ESHUTDOWN)
0838                 atm_warn(usbatm, "polling disabled, set adsl_state"
0839                         " to 'start' or 'poll' to resume\n");
0840         }
0841         mutex_unlock(&instance->poll_state_serialize);
0842         goto reschedule;
0843     }
0844 
0845     memcpy(instance->card_info, buf, sizeof(instance->card_info));
0846 
0847     if (instance->adsl_status != buf[CXINF_LINE_STARTABLE]) {
0848         instance->adsl_status = buf[CXINF_LINE_STARTABLE];
0849 
0850         switch (instance->adsl_status) {
0851         case 0:
0852             atm_info(usbatm, "ADSL state: running\n");
0853             break;
0854 
0855         case 1:
0856             atm_info(usbatm, "ADSL state: stopped\n");
0857             break;
0858 
0859         default:
0860             atm_info(usbatm, "Unknown adsl status %02x\n", instance->adsl_status);
0861             break;
0862         }
0863     }
0864 
0865     if (instance->line_status == buf[CXINF_LINE_STATUS])
0866         goto reschedule;
0867 
0868     instance->line_status = buf[CXINF_LINE_STATUS];
0869     switch (instance->line_status) {
0870     case 0:
0871         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
0872         atm_info(usbatm, "ADSL line: down\n");
0873         break;
0874 
0875     case 1:
0876         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
0877         atm_info(usbatm, "ADSL line: attempting to activate\n");
0878         break;
0879 
0880     case 2:
0881         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
0882         atm_info(usbatm, "ADSL line: training\n");
0883         break;
0884 
0885     case 3:
0886         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
0887         atm_info(usbatm, "ADSL line: channel analysis\n");
0888         break;
0889 
0890     case 4:
0891         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
0892         atm_info(usbatm, "ADSL line: exchange\n");
0893         break;
0894 
0895     case 5:
0896         atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424;
0897         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_FOUND);
0898 
0899         atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n",
0900              buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]);
0901         break;
0902 
0903     case 6:
0904         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
0905         atm_info(usbatm, "ADSL line: waiting\n");
0906         break;
0907 
0908     case 7:
0909         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST);
0910         atm_info(usbatm, "ADSL line: initializing\n");
0911         break;
0912 
0913     default:
0914         atm_dev_signal_change(atm_dev, ATM_PHY_SIG_UNKNOWN);
0915         atm_info(usbatm, "Unknown line state %02x\n", instance->line_status);
0916         break;
0917     }
0918 reschedule:
0919 
0920     mutex_lock(&instance->poll_state_serialize);
0921     if (instance->poll_state == CXPOLL_STOPPING &&
0922                 instance->adsl_status == 1 && /* stopped */
0923                 instance->line_status == 0) /* down */
0924         instance->poll_state = CXPOLL_STOPPED;
0925 
0926     if (instance->poll_state == CXPOLL_STOPPED)
0927         keep_polling = 0;
0928     mutex_unlock(&instance->poll_state_serialize);
0929 
0930     if (keep_polling)
0931         schedule_delayed_work(&instance->poll_work,
0932                 round_jiffies_relative(POLL_INTERVAL*HZ));
0933 }
0934 
0935 static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw,
0936              u8 code1, u8 code2, u32 addr, const u8 *data, int size)
0937 {
0938     int ret;
0939     u8 *buf;
0940     int offd, offb;
0941     const int stride = CMD_PACKET_SIZE - 8;
0942 
0943     buf = (u8 *) __get_free_page(GFP_KERNEL);
0944     if (!buf)
0945         return -ENOMEM;
0946 
0947     offb = offd = 0;
0948     do {
0949         int l = min_t(int, stride, size - offd);
0950 
0951         buf[offb++] = fw;
0952         buf[offb++] = l;
0953         buf[offb++] = code1;
0954         buf[offb++] = code2;
0955         put_unaligned(cpu_to_le32(addr), (__le32 *)(buf + offb));
0956         offb += 4;
0957         addr += l;
0958         if (l)
0959             memcpy(buf + offb, data + offd, l);
0960         if (l < stride)
0961             memset(buf + offb + l, 0, stride - l);
0962         offb += stride;
0963         offd += stride;
0964         if ((offb >= PAGE_SIZE) || (offd >= size)) {
0965             ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD),
0966                        buf, offb, NULL, CMD_TIMEOUT);
0967             if (ret < 0) {
0968                 dev_dbg(&usb_dev->dev, "sending fw %#x failed\n", fw);
0969                 goto cleanup;
0970             }
0971             offb = 0;
0972         }
0973     } while (offd < size);
0974     dev_dbg(&usb_dev->dev, "sent fw %#x\n", fw);
0975 
0976     ret = 0;
0977 
0978 cleanup:
0979     free_page((unsigned long) buf);
0980     return ret;
0981 }
0982 
0983 static void cxacru_upload_firmware(struct cxacru_data *instance,
0984                    const struct firmware *fw,
0985                    const struct firmware *bp)
0986 {
0987     int ret;
0988     struct usbatm_data *usbatm = instance->usbatm;
0989     struct usb_device *usb_dev = usbatm->usb_dev;
0990     __le16 signature[] = { usb_dev->descriptor.idVendor,
0991                    usb_dev->descriptor.idProduct };
0992     __le32 val;
0993 
0994     usb_dbg(usbatm, "%s\n", __func__);
0995 
0996     /* FirmwarePllFClkValue */
0997     val = cpu_to_le32(instance->modem_type->pll_f_clk);
0998     ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
0999     if (ret) {
1000         usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret);
1001         return;
1002     }
1003 
1004     /* FirmwarePllBClkValue */
1005     val = cpu_to_le32(instance->modem_type->pll_b_clk);
1006     ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
1007     if (ret) {
1008         usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret);
1009         return;
1010     }
1011 
1012     /* Enable SDRAM */
1013     val = cpu_to_le32(SDRAM_ENA);
1014     ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
1015     if (ret) {
1016         usb_err(usbatm, "Enable SDRAM failed: %d\n", ret);
1017         return;
1018     }
1019 
1020     /* Firmware */
1021     usb_info(usbatm, "loading firmware\n");
1022     ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
1023     if (ret) {
1024         usb_err(usbatm, "Firmware upload failed: %d\n", ret);
1025         return;
1026     }
1027 
1028     /* Boot ROM patch */
1029     if (instance->modem_type->boot_rom_patch) {
1030         usb_info(usbatm, "loading boot ROM patch\n");
1031         ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size);
1032         if (ret) {
1033             usb_err(usbatm, "Boot ROM patching failed: %d\n", ret);
1034             return;
1035         }
1036     }
1037 
1038     /* Signature */
1039     ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4);
1040     if (ret) {
1041         usb_err(usbatm, "Signature storing failed: %d\n", ret);
1042         return;
1043     }
1044 
1045     usb_info(usbatm, "starting device\n");
1046     if (instance->modem_type->boot_rom_patch) {
1047         val = cpu_to_le32(BR_ADDR);
1048         ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
1049     } else {
1050         ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
1051     }
1052     if (ret) {
1053         usb_err(usbatm, "Passing control to firmware failed: %d\n", ret);
1054         return;
1055     }
1056 
1057     /* Delay to allow firmware to start up. */
1058     msleep_interruptible(1000);
1059 
1060     usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD));
1061     usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD));
1062     usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA));
1063     usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA));
1064 
1065     ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
1066     if (ret < 0) {
1067         usb_err(usbatm, "modem failed to initialize: %d\n", ret);
1068         return;
1069     }
1070 }
1071 
1072 static int cxacru_find_firmware(struct cxacru_data *instance,
1073                 char *phase, const struct firmware **fw_p)
1074 {
1075     struct usbatm_data *usbatm = instance->usbatm;
1076     struct device *dev = &usbatm->usb_intf->dev;
1077     char buf[16];
1078 
1079     sprintf(buf, "cxacru-%s.bin", phase);
1080     usb_dbg(usbatm, "cxacru_find_firmware: looking for %s\n", buf);
1081 
1082     if (request_firmware(fw_p, buf, dev)) {
1083         usb_dbg(usbatm, "no stage %s firmware found\n", phase);
1084         return -ENOENT;
1085     }
1086 
1087     usb_info(usbatm, "found firmware %s\n", buf);
1088 
1089     return 0;
1090 }
1091 
1092 static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
1093                  struct usb_interface *usb_intf)
1094 {
1095     const struct firmware *fw, *bp;
1096     struct cxacru_data *instance = usbatm_instance->driver_data;
1097     int ret = cxacru_find_firmware(instance, "fw", &fw);
1098 
1099     if (ret) {
1100         usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n");
1101         return ret;
1102     }
1103 
1104     if (instance->modem_type->boot_rom_patch) {
1105         ret = cxacru_find_firmware(instance, "bp", &bp);
1106         if (ret) {
1107             usb_warn(usbatm_instance, "boot ROM patch (cxacru-bp.bin) unavailable (system misconfigured?)\n");
1108             release_firmware(fw);
1109             return ret;
1110         }
1111     }
1112 
1113     cxacru_upload_firmware(instance, fw, bp);
1114 
1115     if (instance->modem_type->boot_rom_patch)
1116         release_firmware(bp);
1117     release_firmware(fw);
1118 
1119     ret = cxacru_card_status(instance);
1120     if (ret)
1121         usb_dbg(usbatm_instance, "modem initialisation failed\n");
1122     else
1123         usb_dbg(usbatm_instance, "done setting up the modem\n");
1124 
1125     return ret;
1126 }
1127 
1128 static int cxacru_bind(struct usbatm_data *usbatm_instance,
1129                struct usb_interface *intf, const struct usb_device_id *id)
1130 {
1131     struct cxacru_data *instance;
1132     struct usb_device *usb_dev = interface_to_usbdev(intf);
1133     struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD];
1134     int ret;
1135 
1136     /* instance init */
1137     instance = kzalloc(sizeof(*instance), GFP_KERNEL);
1138     if (!instance)
1139         return -ENOMEM;
1140 
1141     instance->usbatm = usbatm_instance;
1142     instance->modem_type = (struct cxacru_modem_type *) id->driver_info;
1143 
1144     mutex_init(&instance->poll_state_serialize);
1145     instance->poll_state = CXPOLL_STOPPED;
1146     instance->line_status = -1;
1147     instance->adsl_status = -1;
1148 
1149     mutex_init(&instance->adsl_state_serialize);
1150 
1151     instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL);
1152     if (!instance->rcv_buf) {
1153         usb_dbg(usbatm_instance, "cxacru_bind: no memory for rcv_buf\n");
1154         ret = -ENOMEM;
1155         goto fail;
1156     }
1157     instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL);
1158     if (!instance->snd_buf) {
1159         usb_dbg(usbatm_instance, "cxacru_bind: no memory for snd_buf\n");
1160         ret = -ENOMEM;
1161         goto fail;
1162     }
1163     instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL);
1164     if (!instance->rcv_urb) {
1165         ret = -ENOMEM;
1166         goto fail;
1167     }
1168     instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL);
1169     if (!instance->snd_urb) {
1170         ret = -ENOMEM;
1171         goto fail;
1172     }
1173 
1174     if (!cmd_ep) {
1175         usb_dbg(usbatm_instance, "cxacru_bind: no command endpoint\n");
1176         ret = -ENODEV;
1177         goto fail;
1178     }
1179 
1180     if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1181             == USB_ENDPOINT_XFER_INT) {
1182         usb_fill_int_urb(instance->rcv_urb,
1183             usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
1184             instance->rcv_buf, PAGE_SIZE,
1185             cxacru_blocking_completion, &instance->rcv_done, 1);
1186 
1187         usb_fill_int_urb(instance->snd_urb,
1188             usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
1189             instance->snd_buf, PAGE_SIZE,
1190             cxacru_blocking_completion, &instance->snd_done, 4);
1191     } else {
1192         usb_fill_bulk_urb(instance->rcv_urb,
1193             usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD),
1194             instance->rcv_buf, PAGE_SIZE,
1195             cxacru_blocking_completion, &instance->rcv_done);
1196 
1197         usb_fill_bulk_urb(instance->snd_urb,
1198             usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD),
1199             instance->snd_buf, PAGE_SIZE,
1200             cxacru_blocking_completion, &instance->snd_done);
1201     }
1202 
1203     mutex_init(&instance->cm_serialize);
1204 
1205     INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status);
1206 
1207     usbatm_instance->driver_data = instance;
1208 
1209     usbatm_instance->flags = (cxacru_card_status(instance) ? 0 : UDSL_SKIP_HEAVY_INIT);
1210 
1211     return 0;
1212 
1213  fail:
1214     free_page((unsigned long) instance->snd_buf);
1215     free_page((unsigned long) instance->rcv_buf);
1216     usb_free_urb(instance->snd_urb);
1217     usb_free_urb(instance->rcv_urb);
1218     kfree(instance);
1219 
1220     return ret;
1221 }
1222 
1223 static void cxacru_unbind(struct usbatm_data *usbatm_instance,
1224         struct usb_interface *intf)
1225 {
1226     struct cxacru_data *instance = usbatm_instance->driver_data;
1227     int is_polling = 1;
1228 
1229     usb_dbg(usbatm_instance, "cxacru_unbind entered\n");
1230 
1231     if (!instance) {
1232         usb_dbg(usbatm_instance, "cxacru_unbind: NULL instance!\n");
1233         return;
1234     }
1235 
1236     mutex_lock(&instance->poll_state_serialize);
1237     BUG_ON(instance->poll_state == CXPOLL_SHUTDOWN);
1238 
1239     /* ensure that status polling continues unless
1240      * it has already stopped */
1241     if (instance->poll_state == CXPOLL_STOPPED)
1242         is_polling = 0;
1243 
1244     /* stop polling from being stopped or started */
1245     instance->poll_state = CXPOLL_SHUTDOWN;
1246     mutex_unlock(&instance->poll_state_serialize);
1247 
1248     if (is_polling)
1249         cancel_delayed_work_sync(&instance->poll_work);
1250 
1251     usb_kill_urb(instance->snd_urb);
1252     usb_kill_urb(instance->rcv_urb);
1253     usb_free_urb(instance->snd_urb);
1254     usb_free_urb(instance->rcv_urb);
1255 
1256     free_page((unsigned long) instance->snd_buf);
1257     free_page((unsigned long) instance->rcv_buf);
1258 
1259     kfree(instance);
1260 
1261     usbatm_instance->driver_data = NULL;
1262 }
1263 
1264 static const struct cxacru_modem_type cxacru_cafe = {
1265     .pll_f_clk = 0x02d874df,
1266     .pll_b_clk = 0x0196a51a,
1267     .boot_rom_patch = 1,
1268 };
1269 
1270 static const struct cxacru_modem_type cxacru_cb00 = {
1271     .pll_f_clk = 0x5,
1272     .pll_b_clk = 0x3,
1273     .boot_rom_patch = 0,
1274 };
1275 
1276 static const struct usb_device_id cxacru_usb_ids[] = {
1277     { /* V = Conexant           P = ADSL modem (Euphrates project)  */
1278         USB_DEVICE(0x0572, 0xcafe), .driver_info = (unsigned long) &cxacru_cafe
1279     },
1280     { /* V = Conexant           P = ADSL modem (Hasbani project)    */
1281         USB_DEVICE(0x0572, 0xcb00), .driver_info = (unsigned long) &cxacru_cb00
1282     },
1283     { /* V = Conexant           P = ADSL modem              */
1284         USB_DEVICE(0x0572, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00
1285     },
1286     { /* V = Conexant           P = ADSL modem (Well PTI-800) */
1287         USB_DEVICE(0x0572, 0xcb02), .driver_info = (unsigned long) &cxacru_cb00
1288     },
1289     { /* V = Conexant           P = ADSL modem              */
1290         USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00
1291     },
1292     { /* V = Conexant           P = ADSL modem (ZTE ZXDSL 852)      */
1293         USB_DEVICE(0x0572, 0xcb07), .driver_info = (unsigned long) &cxacru_cb00
1294     },
1295     { /* V = Olitec             P = ADSL modem version 2        */
1296         USB_DEVICE(0x08e3, 0x0100), .driver_info = (unsigned long) &cxacru_cafe
1297     },
1298     { /* V = Olitec             P = ADSL modem version 3        */
1299         USB_DEVICE(0x08e3, 0x0102), .driver_info = (unsigned long) &cxacru_cb00
1300     },
1301     { /* V = Trust/Amigo Technology Co. P = AMX-CA86U               */
1302         USB_DEVICE(0x0eb0, 0x3457), .driver_info = (unsigned long) &cxacru_cafe
1303     },
1304     { /* V = Zoom               P = 5510                */
1305         USB_DEVICE(0x1803, 0x5510), .driver_info = (unsigned long) &cxacru_cb00
1306     },
1307     { /* V = Draytek            P = Vigor 318               */
1308         USB_DEVICE(0x0675, 0x0200), .driver_info = (unsigned long) &cxacru_cb00
1309     },
1310     { /* V = Zyxel              P = 630-C1 aka OMNI ADSL USB (Annex A)  */
1311         USB_DEVICE(0x0586, 0x330a), .driver_info = (unsigned long) &cxacru_cb00
1312     },
1313     { /* V = Zyxel              P = 630-C3 aka OMNI ADSL USB (Annex B)  */
1314         USB_DEVICE(0x0586, 0x330b), .driver_info = (unsigned long) &cxacru_cb00
1315     },
1316     { /* V = Aethra             P = Starmodem UM1020            */
1317         USB_DEVICE(0x0659, 0x0020), .driver_info = (unsigned long) &cxacru_cb00
1318     },
1319     { /* V = Aztech Systems         P = ? AKA Pirelli AUA-010       */
1320         USB_DEVICE(0x0509, 0x0812), .driver_info = (unsigned long) &cxacru_cb00
1321     },
1322     { /* V = Netopia            P = Cayman 3341(Annex A)/3351(Annex B)  */
1323         USB_DEVICE(0x100d, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00
1324     },
1325     { /* V = Netopia            P = Cayman 3342(Annex A)/3352(Annex B)  */
1326         USB_DEVICE(0x100d, 0x3342), .driver_info = (unsigned long) &cxacru_cb00
1327     },
1328     {}
1329 };
1330 
1331 MODULE_DEVICE_TABLE(usb, cxacru_usb_ids);
1332 
1333 static struct usbatm_driver cxacru_driver = {
1334     .driver_name    = cxacru_driver_name,
1335     .bind       = cxacru_bind,
1336     .heavy_init = cxacru_heavy_init,
1337     .unbind     = cxacru_unbind,
1338     .atm_start  = cxacru_atm_start,
1339     .bulk_in    = CXACRU_EP_DATA,
1340     .bulk_out   = CXACRU_EP_DATA,
1341     .rx_padding = 3,
1342     .tx_padding = 11,
1343 };
1344 
1345 static int cxacru_usb_probe(struct usb_interface *intf,
1346         const struct usb_device_id *id)
1347 {
1348     struct usb_device *usb_dev = interface_to_usbdev(intf);
1349     char buf[15];
1350 
1351     /* Avoid ADSL routers (cx82310_eth).
1352      * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD".
1353      */
1354     if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC
1355             && usb_string(usb_dev, usb_dev->descriptor.iProduct,
1356                 buf, sizeof(buf)) > 0) {
1357         if (!strcmp(buf, "USB NET CARD")) {
1358             dev_info(&intf->dev, "ignoring cx82310_eth device\n");
1359             return -ENODEV;
1360         }
1361     }
1362 
1363     return usbatm_usb_probe(intf, id, &cxacru_driver);
1364 }
1365 
1366 static struct usb_driver cxacru_usb_driver = {
1367     .name       = cxacru_driver_name,
1368     .probe      = cxacru_usb_probe,
1369     .disconnect = usbatm_usb_disconnect,
1370     .id_table   = cxacru_usb_ids,
1371     .dev_groups = cxacru_groups,
1372 };
1373 
1374 module_usb_driver(cxacru_usb_driver);
1375 
1376 MODULE_AUTHOR(DRIVER_AUTHOR);
1377 MODULE_DESCRIPTION(DRIVER_DESC);
1378 MODULE_LICENSE("GPL");