aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormatthieu castet <castet.matthieu@free.fr>2005-11-07 17:27:13 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-04 16:48:29 -0500
commitb72458a80c75cab832248f536412f386e20a93a0 (patch)
treeaae8bd4f4ca209cd5ddb22ab51c8f02012ed6593
parent6912354a895fcd234155273fe8838a0d83259a9b (diff)
[PATCH] USB: Eagle and ADI 930 usb adsl modem driver
A driver for USB ADSL modems based on the ADI eagle chipset using the usb_atm infrastructure. The managing part was taken from bsd ueagle driver, other parts were written from scratch. The driver uses the in-kernel firmware loader : - to load a first usb firmware when the modem is in pre-firmware state - to load the dsp firmware that are swapped in host memory. - to load CMV (configuration and management variables) when the modem boot. (We can't use options or sysfs for this as there many possible values. See https://mail.gna.org/public/eagleusb-dev/2005-04/msg00031.html for a description of some) - to load fpga code for 930 chipset. The device had 4 endpoints : * 2 for data (use by usbatm). The incoming endpoint could be iso or bulk. The modem seems buggy and produce lot's of atm errors when using it in bulk mode for speed > 3Mbps, so iso endpoint is need for speed > 3Mbps. At the moment iso endpoint need a patched usbatm library and for this reason is not included in this patch. * One bulk endpoint for uploading dsp firmware * One irq endpoint that notices the driver - if we need to upload a page of the dsp firmware - an ack for read or write CMV and the value (for the read case). If order to make the driver cleaner, we design synchronous (read|write)_cmv : -send a synchronous control message to the modem -wait for an ack or a timeout -return the value if needed. In order to run these synchronous usb messages we need a kernel thread. The driver has been tested with sagem fast 800 modems with different eagle chipset revision and with ADI 930 since April 2005. Signed-off-by: Matthieu CASTET <castet.matthieu@free.fr> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/atm/Kconfig13
-rw-r--r--drivers/usb/atm/Makefile1
-rw-r--r--drivers/usb/atm/ueagle-atm.c1813
3 files changed, 1827 insertions, 0 deletions
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig
index f429862e0974..550ddfa71a43 100644
--- a/drivers/usb/atm/Kconfig
+++ b/drivers/usb/atm/Kconfig
@@ -44,6 +44,19 @@ config USB_CXACRU
44 To compile this driver as a module, choose M here: the 44 To compile this driver as a module, choose M here: the
45 module will be called cxacru. 45 module will be called cxacru.
46 46
47config USB_UEAGLEATM
48 tristate "ADI 930 and eagle USB DSL modem"
49 depends on USB_ATM
50 select FW_LOADER
51 help
52 Say Y here if you have an ADSL USB modem based on the ADI 930
53 or eagle chipset. In order to use your modem you will need to
54 install firmwares and CMV (Command Management Variables); see
55 <https://gna.org/projects/ueagleatm/> for details.
56
57 To compile this driver as a module, choose M here: the
58 module will be called ueagle-atm.
59
47config USB_XUSBATM 60config USB_XUSBATM
48 tristate "Other USB DSL modem support" 61 tristate "Other USB DSL modem support"
49 depends on USB_ATM 62 depends on USB_ATM
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile
index 85099718c683..4c4a776ab1cd 100644
--- a/drivers/usb/atm/Makefile
+++ b/drivers/usb/atm/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_USB_CXACRU) += cxacru.o 5obj-$(CONFIG_USB_CXACRU) += cxacru.o
6obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o 6obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o
7obj-$(CONFIG_USB_UEAGLEATM) += ueagle-atm.o
7obj-$(CONFIG_USB_ATM) += usbatm.o 8obj-$(CONFIG_USB_ATM) += usbatm.o
8obj-$(CONFIG_USB_XUSBATM) += xusbatm.o 9obj-$(CONFIG_USB_XUSBATM) += xusbatm.o
9 10
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
new file mode 100644
index 000000000000..3e2475c666ab
--- /dev/null
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -0,0 +1,1813 @@
1/*-
2 * Copyright (c) 2003, 2004
3 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
4 *
5 * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr>
6 *
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * BSD license below:
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice unmodified, this list of conditions, and the following
18 * disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * GPL license :
36 * This program is free software; you can redistribute it and/or
37 * modify it under the terms of the GNU General Public License
38 * as published by the Free Software Foundation; either version 2
39 * of the License, or (at your option) any later version.
40 *
41 * This program is distributed in the hope that it will be useful,
42 * but WITHOUT ANY WARRANTY; without even the implied warranty of
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44 * GNU General Public License for more details.
45 *
46 * You should have received a copy of the GNU General Public License
47 * along with this program; if not, write to the Free Software
48 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
49 *
50 *
51 * HISTORY : some part of the code was base on ueagle 1.3 BSD driver,
52 * Damien Bergamini agree to put his code under a DUAL GPL/BSD license.
53 *
54 * The rest of the code was was rewritten from scratch.
55 */
56
57#include <linux/module.h>
58#include <linux/moduleparam.h>
59#include <linux/init.h>
60#include <linux/crc32.h>
61#include <linux/usb.h>
62#include <linux/firmware.h>
63#include <linux/ctype.h>
64#include <linux/kthread.h>
65#include <linux/version.h>
66#include <asm/unaligned.h>
67
68#include "usbatm.h"
69
70#define EAGLEUSBVERSION "ueagle 1.1"
71
72
73/*
74 * Debug macros
75 */
76#define uea_dbg(usb_dev, format, args...) \
77 do { \
78 if (debug >= 1) \
79 dev_dbg(&(usb_dev)->dev, \
80 "[ueagle-atm dbg] %s: " format, \
81 __FUNCTION__, ##args); \
82 } while (0)
83
84#define uea_vdbg(usb_dev, format, args...) \
85 do { \
86 if (debug >= 2) \
87 dev_dbg(&(usb_dev)->dev, \
88 "[ueagle-atm vdbg] " format, ##args); \
89 } while (0)
90
91#define uea_enters(usb_dev) \
92 uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)
93
94#define uea_leaves(usb_dev) \
95 uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__)
96
97#define uea_err(usb_dev, format,args...) \
98 dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)
99
100#define uea_warn(usb_dev, format,args...) \
101 dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args)
102
103#define uea_info(usb_dev, format,args...) \
104 dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args)
105
106struct uea_cmvs {
107 u32 address;
108 u16 offset;
109 u32 data;
110} __attribute__ ((packed));
111
112struct uea_softc {
113 struct usb_device *usb_dev;
114 struct usbatm_data *usbatm;
115
116 int modem_index;
117 unsigned int driver_info;
118
119 int booting;
120 int reset;
121
122 wait_queue_head_t sync_q;
123
124 struct task_struct *kthread;
125 u32 data;
126 wait_queue_head_t cmv_ack_wait;
127 int cmv_ack;
128
129 struct work_struct task;
130 u16 pageno;
131 u16 ovl;
132
133 const struct firmware *dsp_firm;
134 struct urb *urb_int;
135
136 u8 cmv_function;
137 u16 cmv_idx;
138 u32 cmv_address;
139 u16 cmv_offset;
140
141 /* keep in sync with eaglectl */
142 struct uea_stats {
143 struct {
144 u32 state;
145 u32 flags;
146 u32 mflags;
147 u32 vidcpe;
148 u32 vidco;
149 u32 dsrate;
150 u32 usrate;
151 u32 dsunc;
152 u32 usunc;
153 u32 dscorr;
154 u32 uscorr;
155 u32 txflow;
156 u32 rxflow;
157 u32 usattenuation;
158 u32 dsattenuation;
159 u32 dsmargin;
160 u32 usmargin;
161 u32 firmid;
162 } phy;
163 } stats;
164};
165
166/*
167 * Elsa IDs
168 */
169#define ELSA_VID 0x05CC
170#define ELSA_PID_PSTFIRM 0x3350
171#define ELSA_PID_PREFIRM 0x3351
172
173/*
174 * Sagem USB IDs
175 */
176#define EAGLE_VID 0x1110
177#define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */
178#define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */
179
180#define EAGLE_IIC_PID_PREFIRM 0x9024 /* Eagle IIC */
181#define EAGLE_IIC_PID_PSTFIRM 0x9023 /* Eagle IIC */
182
183#define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */
184#define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */
185
186/*
187 * Eagle III Pid
188 */
189#define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */
190#define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */
191
192/*
193 * USR USB IDs
194 */
195#define USR_VID 0x0BAF
196#define MILLER_A_PID_PREFIRM 0x00F2
197#define MILLER_A_PID_PSTFIRM 0x00F1
198#define MILLER_B_PID_PREFIRM 0x00FA
199#define MILLER_B_PID_PSTFIRM 0x00F9
200#define HEINEKEN_A_PID_PREFIRM 0x00F6
201#define HEINEKEN_A_PID_PSTFIRM 0x00F5
202#define HEINEKEN_B_PID_PREFIRM 0x00F8
203#define HEINEKEN_B_PID_PSTFIRM 0x00F7
204
205#define PREFIRM 0
206#define PSTFIRM (1<<7)
207enum {
208 ADI930 = 0,
209 EAGLE_I,
210 EAGLE_II,
211 EAGLE_III
212};
213
214/* macros for both struct usb_device_id and struct uea_softc */
215#define UEA_IS_PREFIRM(x) \
216 (!((x)->driver_info & PSTFIRM))
217#define UEA_CHIP_VERSION(x) \
218 ((x)->driver_info & 0xf)
219
220#define IS_ISDN(sc) \
221 (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)
222
223#define INS_TO_USBDEV(ins) ins->usb_dev
224
225#define GET_STATUS(data) \
226 ((data >> 8) & 0xf)
227#define IS_OPERATIONAL(sc) \
228 (GET_STATUS(sc->stats.phy.state) == 2)
229
230/*
231 * Set of macros to handle unaligned data in the firmware blob.
232 * The FW_GET_BYTE() macro is provided only for consistency.
233 */
234
235#define FW_GET_BYTE(p) *((__u8 *) (p))
236#define FW_GET_WORD(p) le16_to_cpu(get_unaligned((__le16 *) (p)))
237#define FW_GET_LONG(p) le32_to_cpu(get_unaligned((__le32 *) (p)))
238
239#define FW_DIR "ueagle-atm/"
240#define NB_MODEM 4
241
242#define BULK_TIMEOUT 300
243#define CTRL_TIMEOUT 1000
244
245#define ACK_TIMEOUT msecs_to_jiffies(1500)
246
247#define UEA_INTR_IFACE_NO 0
248#define UEA_US_IFACE_NO 1
249#define UEA_DS_IFACE_NO 2
250
251#define FASTEST_ISO_INTF 8
252
253#define UEA_BULK_DATA_PIPE 0x02
254#define UEA_IDMA_PIPE 0x04
255#define UEA_INTR_PIPE 0x04
256#define UEA_ISO_DATA_PIPE 0x08
257
258#define UEA_SET_BLOCK 0x0001
259#define UEA_SET_MODE 0x0003
260#define UEA_SET_2183_DATA 0x0004
261#define UEA_SET_TIMEOUT 0x0011
262
263#define UEA_LOOPBACK_OFF 0x0002
264#define UEA_LOOPBACK_ON 0x0003
265#define UEA_BOOT_IDMA 0x0006
266#define UEA_START_RESET 0x0007
267#define UEA_END_RESET 0x0008
268
269#define UEA_SWAP_MAILBOX (0x3fcd | 0x4000)
270#define UEA_MPTX_START (0x3fce | 0x4000)
271#define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000)
272#define UEA_MPRX_MAILBOX (0x3fdf | 0x4000)
273
274/* structure describing a block within a DSP page */
275struct block_info {
276 __le16 wHdr;
277#define UEA_BIHDR 0xabcd
278 __le16 wAddress;
279 __le16 wSize;
280 __le16 wOvlOffset;
281 __le16 wOvl; /* overlay */
282 __le16 wLast;
283} __attribute__ ((packed));
284#define BLOCK_INFO_SIZE 12
285
286/* structure representing a CMV (Configuration and Management Variable) */
287struct cmv {
288 __le16 wPreamble;
289#define PREAMBLE 0x535c
290 __u8 bDirection;
291#define MODEMTOHOST 0x01
292#define HOSTTOMODEM 0x10
293 __u8 bFunction;
294#define FUNCTION_TYPE(f) ((f) >> 4)
295#define MEMACCESS 0x1
296#define ADSLDIRECTIVE 0x7
297
298#define FUNCTION_SUBTYPE(f) ((f) & 0x0f)
299/* for MEMACCESS */
300#define REQUESTREAD 0x0
301#define REQUESTWRITE 0x1
302#define REPLYREAD 0x2
303#define REPLYWRITE 0x3
304/* for ADSLDIRECTIVE */
305#define KERNELREADY 0x0
306#define MODEMREADY 0x1
307
308#define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf))
309 __le16 wIndex;
310 __le32 dwSymbolicAddress;
311#define MAKESA(a, b, c, d) \
312 (((c) & 0xff) << 24 | \
313 ((d) & 0xff) << 16 | \
314 ((a) & 0xff) << 8 | \
315 ((b) & 0xff))
316
317#define SA_CNTL MAKESA('C', 'N', 'T', 'L')
318#define SA_DIAG MAKESA('D', 'I', 'A', 'G')
319#define SA_INFO MAKESA('I', 'N', 'F', 'O')
320#define SA_OPTN MAKESA('O', 'P', 'T', 'N')
321#define SA_RATE MAKESA('R', 'A', 'T', 'E')
322#define SA_STAT MAKESA('S', 'T', 'A', 'T')
323 __le16 wOffsetAddress;
324 __le32 dwData;
325} __attribute__ ((packed));
326#define CMV_SIZE 16
327
328/* structure representing swap information */
329struct swap_info {
330 __u8 bSwapPageNo;
331 __u8 bOvl; /* overlay */
332} __attribute__ ((packed));
333
334/* structure representing interrupt data */
335struct intr_pkt {
336 __u8 bType;
337 __u8 bNotification;
338 __le16 wValue;
339 __le16 wIndex;
340 __le16 wLength;
341 __le16 wInterrupt;
342#define INT_LOADSWAPPAGE 0x0001
343#define INT_INCOMINGCMV 0x0002
344 union {
345 struct {
346 struct swap_info swapinfo;
347 __le16 wDataSize;
348 } __attribute__ ((packed)) s1;
349
350 struct {
351 struct cmv cmv;
352 __le16 wDataSize;
353 } __attribute__ ((packed)) s2;
354 } __attribute__ ((packed)) u;
355#define bSwapPageNo u.s1.swapinfo.bSwapPageNo
356#define bOvl u.s1.swapinfo.bOvl
357} __attribute__ ((packed));
358#define INTR_PKT_SIZE 28
359
360static struct usb_driver uea_driver;
361static DECLARE_MUTEX(uea_semaphore);
362static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};
363
364static int modem_index;
365static unsigned int debug;
366static int sync_wait[NB_MODEM];
367static char *cmv_file[NB_MODEM];
368
369module_param(debug, uint, 0644);
370MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
371module_param_array(sync_wait, bool, NULL, 0644);
372MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM");
373module_param_array(cmv_file, charp, NULL, 0644);
374MODULE_PARM_DESC(cmv_file,
375 "file name with configuration and management variables");
376
377#define UPDATE_ATM_STAT(type, val) \
378 do { \
379 if (sc->usbatm->atm_dev) \
380 sc->usbatm->atm_dev->type = val; \
381 } while (0)
382
383/* Firmware loading */
384#define LOAD_INTERNAL 0xA0
385#define F8051_USBCS 0x7f92
386
387/**
388 * uea_send_modem_cmd - Send a command for pre-firmware devices.
389 */
390static int uea_send_modem_cmd(struct usb_device *usb,
391 u16 addr, u16 size, u8 * buff)
392{
393 int ret = -ENOMEM;
394 u8 *xfer_buff;
395
396 xfer_buff = kmalloc(size, GFP_KERNEL);
397 if (xfer_buff) {
398 memcpy(xfer_buff, buff, size);
399 ret = usb_control_msg(usb,
400 usb_sndctrlpipe(usb, 0),
401 LOAD_INTERNAL,
402 USB_DIR_OUT | USB_TYPE_VENDOR |
403 USB_RECIP_DEVICE, addr, 0, xfer_buff,
404 size, CTRL_TIMEOUT);
405 kfree(xfer_buff);
406 }
407
408 if (ret < 0)
409 return ret;
410
411 return (ret == size) ? 0 : -EIO;
412}
413
414static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context)
415{
416 struct usb_device *usb = context;
417 u8 *pfw, value;
418 u32 crc = 0;
419 int ret, size;
420
421 uea_enters(usb);
422 if (!fw_entry) {
423 uea_err(usb, "firmware is not available\n");
424 goto err;
425 }
426
427 pfw = fw_entry->data;
428 size = fw_entry->size;
429
430 crc = FW_GET_LONG(pfw);
431 pfw += 4;
432 size -= 4;
433 if (crc32_be(0, pfw, size) != crc) {
434 uea_err(usb, "firmware is corrupted\n");
435 goto err;
436 }
437
438 /*
439 * Start to upload formware : send reset
440 */
441 value = 1;
442 ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
443
444 if (ret < 0) {
445 uea_err(usb, "modem reset failed with error %d\n", ret);
446 goto err;
447 }
448
449 while (size > 0) {
450 u8 len = FW_GET_BYTE(pfw);
451 u16 add = FW_GET_WORD(pfw + 1);
452 ret = uea_send_modem_cmd(usb, add, len, pfw + 3);
453 if (ret < 0) {
454 uea_err(usb, "uploading firmware data failed "
455 "with error %d\n", ret);
456 goto err;
457 }
458 pfw += len + 3;
459 size -= len + 3;
460 }
461
462 /*
463 * Tell the modem we finish : de-assert reset
464 */
465 value = 0;
466 ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value);
467 if (ret < 0)
468 uea_err(usb, "modem de-assert failed with error %d\n", ret);
469 else
470 uea_info(usb, "firmware uploaded\n");
471
472err:
473 uea_leaves(usb);
474}
475
476/**
477 * uea_load_firmware - Load usb firmware for pre-firmware devices.
478 */
479static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
480{
481 int ret;
482 char *fw_name = FW_DIR "eagle.fw";
483
484 uea_enters(usb);
485 uea_info(usb, "pre-firmware device, uploading firmware\n");
486
487 switch (ver) {
488 case ADI930:
489 fw_name = FW_DIR "adi930.fw";
490 break;
491 case EAGLE_I:
492 fw_name = FW_DIR "eagleI.fw";
493 break;
494 case EAGLE_II:
495 fw_name = FW_DIR "eagleII.fw";
496 break;
497 case EAGLE_III:
498 fw_name = FW_DIR "eagleIII.fw";
499 break;
500 }
501
502 ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
503 if (ret)
504 uea_err(usb, "firmware %s is not available\n", fw_name);
505 else
506 uea_info(usb, "loading firmware %s\n", fw_name);
507
508 uea_leaves(usb);
509 return ret;
510}
511
512/* modem management : dsp firmware, send/read CMV, monitoring statistic
513 */
514
515/*
516 * Make sure that the DSP code provided is safe to use.
517 */
518static int check_dsp(u8 *dsp, unsigned int len)
519{
520 u8 pagecount, blockcount;
521 u16 blocksize;
522 u32 pageoffset;
523 unsigned int i, j, p, pp;
524
525 /* enough space for pagecount? */
526 if (len < 1)
527 return 1;
528
529 pagecount = FW_GET_BYTE(dsp);
530 p = 1;
531
532 /* enough space for page offsets? */
533 if (p + 4 * pagecount > len)
534 return 1;
535
536 for (i = 0; i < pagecount; i++) {
537
538 pageoffset = FW_GET_LONG(dsp + p);
539 p += 4;
540
541 if (pageoffset == 0)
542 continue;
543
544 /* enough space for blockcount? */
545 if (pageoffset >= len)
546 return 1;
547
548 pp = pageoffset;
549 blockcount = FW_GET_BYTE(dsp + pp);
550 pp += 1;
551
552 for (j = 0; j < blockcount; j++) {
553
554 /* enough space for block header? */
555 if (pp + 4 > len)
556 return 1;
557
558 pp += 2; /* skip blockaddr */
559 blocksize = FW_GET_WORD(dsp + pp);
560 pp += 2;
561
562 /* enough space for block data? */
563 if (pp + blocksize > len)
564 return 1;
565
566 pp += blocksize;
567 }
568 }
569
570 return 0;
571}
572
573/*
574 * send data to the idma pipe
575 * */
576static int uea_idma_write(struct uea_softc *sc, void *data, u32 size)
577{
578 int ret = -ENOMEM;
579 u8 *xfer_buff;
580 int bytes_read;
581
582 xfer_buff = kmalloc(size, GFP_KERNEL);
583 if (!xfer_buff) {
584 uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
585 return ret;
586 }
587
588 memcpy(xfer_buff, data, size);
589
590 ret = usb_bulk_msg(sc->usb_dev,
591 usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE),
592 xfer_buff, size, &bytes_read, BULK_TIMEOUT);
593
594 kfree(xfer_buff);
595 if (ret < 0)
596 return ret;
597 if (size != bytes_read) {
598 uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size,
599 bytes_read);
600 return -EIO;
601 }
602
603 return 0;
604}
605
606static int request_dsp(struct uea_softc *sc)
607{
608 int ret;
609 char *dsp_name;
610
611 if (UEA_CHIP_VERSION(sc) == ADI930) {
612 if (IS_ISDN(sc))
613 dsp_name = FW_DIR "DSP9i.bin";
614 else
615 dsp_name = FW_DIR "DSP9p.bin";
616 } else {
617 if (IS_ISDN(sc))
618 dsp_name = FW_DIR "DSPei.bin";
619 else
620 dsp_name = FW_DIR "DSPep.bin";
621 }
622
623 ret = request_firmware(&sc->dsp_firm,
624 dsp_name, &sc->usb_dev->dev);
625 if (ret < 0) {
626 uea_err(INS_TO_USBDEV(sc),
627 "requesting firmware %s failed with error %d\n",
628 dsp_name, ret);
629 return ret;
630 }
631
632 if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) {
633 uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
634 dsp_name);
635 release_firmware(sc->dsp_firm);
636 sc->dsp_firm = NULL;
637 return -EILSEQ;
638 }
639
640 return 0;
641}
642
643/*
644 * The uea_load_page() function must be called within a process context
645 */
646static void uea_load_page(void *xsc)
647{
648 struct uea_softc *sc = xsc;
649 u16 pageno = sc->pageno;
650 u16 ovl = sc->ovl;
651 struct block_info bi;
652
653 u8 *p;
654 u8 pagecount, blockcount;
655 u16 blockaddr, blocksize;
656 u32 pageoffset;
657 int i;
658
659 /* reload firmware when reboot start and it's loaded already */
660 if (ovl == 0 && pageno == 0 && sc->dsp_firm) {
661 release_firmware(sc->dsp_firm);
662 sc->dsp_firm = NULL;
663 }
664
665 if (sc->dsp_firm == NULL && request_dsp(sc) < 0)
666 return;
667
668 p = sc->dsp_firm->data;
669 pagecount = FW_GET_BYTE(p);
670 p += 1;
671
672 if (pageno >= pagecount)
673 goto bad1;
674
675 p += 4 * pageno;
676 pageoffset = FW_GET_LONG(p);
677
678 if (pageoffset == 0)
679 goto bad1;
680
681 p = sc->dsp_firm->data + pageoffset;
682 blockcount = FW_GET_BYTE(p);
683 p += 1;
684
685 uea_dbg(INS_TO_USBDEV(sc),
686 "sending %u blocks for DSP page %u\n", blockcount, pageno);
687
688 bi.wHdr = cpu_to_le16(UEA_BIHDR);
689 bi.wOvl = cpu_to_le16(ovl);
690 bi.wOvlOffset = cpu_to_le16(ovl | 0x8000);
691
692 for (i = 0; i < blockcount; i++) {
693 blockaddr = FW_GET_WORD(p);
694 p += 2;
695
696 blocksize = FW_GET_WORD(p);
697 p += 2;
698
699 bi.wSize = cpu_to_le16(blocksize);
700 bi.wAddress = cpu_to_le16(blockaddr);
701 bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0);
702
703 /* send block info through the IDMA pipe */
704 if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE))
705 goto bad2;
706
707 /* send block data through the IDMA pipe */
708 if (uea_idma_write(sc, p, blocksize))
709 goto bad2;
710
711 p += blocksize;
712 }
713
714 return;
715
716bad2:
717 uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i);
718 return;
719bad1:
720 uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno);
721}
722
723static inline void wake_up_cmv_ack(struct uea_softc *sc)
724{
725 sc->cmv_ack = 1;
726 wake_up(&sc->cmv_ack_wait);
727}
728
729static inline int wait_cmv_ack(struct uea_softc *sc)
730{
731 int ret = wait_event_timeout(sc->cmv_ack_wait,
732 sc->cmv_ack, ACK_TIMEOUT);
733 sc->cmv_ack = 0;
734
735 if (ret < 0)
736 return ret;
737
738 return (ret == 0) ? -ETIMEDOUT : 0;
739
740}
741
742#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
743
744static int uea_request(struct uea_softc *sc,
745 u16 value, u16 index, u16 size, void *data)
746{
747 u8 *xfer_buff;
748 int ret = -ENOMEM;
749
750 xfer_buff = kmalloc(size, GFP_KERNEL);
751 if (!xfer_buff) {
752 uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
753 return ret;
754 }
755 memcpy(xfer_buff, data, size);
756
757 ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0),
758 UCDC_SEND_ENCAPSULATED_COMMAND,
759 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
760 value, index, xfer_buff, size, CTRL_TIMEOUT);
761
762 kfree(xfer_buff);
763 if (ret < 0) {
764 uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret);
765 return ret;
766 }
767
768 if (ret != size) {
769 uea_err(INS_TO_USBDEV(sc),
770 "usb_control_msg send only %d bytes (instead of %d)\n",
771 ret, size);
772 return -EIO;
773 }
774
775 return 0;
776}
777
778static int uea_cmv(struct uea_softc *sc,
779 u8 function, u32 address, u16 offset, u32 data)
780{
781 struct cmv cmv;
782 int ret;
783
784 /* we send a request, but we expect a reply */
785 sc->cmv_function = function | 0x2;
786 sc->cmv_idx++;
787 sc->cmv_address = address;
788 sc->cmv_offset = offset;
789
790 cmv.wPreamble = cpu_to_le16(PREAMBLE);
791 cmv.bDirection = HOSTTOMODEM;
792 cmv.bFunction = function;
793 cmv.wIndex = cpu_to_le16(sc->cmv_idx);
794 put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress);
795 cmv.wOffsetAddress = cpu_to_le16(offset);
796 put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData);
797
798 ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv);
799 if (ret < 0)
800 return ret;
801 return wait_cmv_ack(sc);
802}
803
804static inline int uea_read_cmv(struct uea_softc *sc,
805 u32 address, u16 offset, u32 *data)
806{
807 int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD),
808 address, offset, 0);
809 if (ret < 0)
810 uea_err(INS_TO_USBDEV(sc),
811 "reading cmv failed with error %d\n", ret);
812 else
813 *data = sc->data;
814
815 return ret;
816}
817
818static inline int uea_write_cmv(struct uea_softc *sc,
819 u32 address, u16 offset, u32 data)
820{
821 int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE),
822 address, offset, data);
823 if (ret < 0)
824 uea_err(INS_TO_USBDEV(sc),
825 "writing cmv failed with error %d\n", ret);
826
827 return ret;
828}
829
830/*
831 * Monitor the modem and update the stat
832 * return 0 if everything is ok
833 * return < 0 if an error occurs (-EAGAIN reboot needed)
834 */
835static int uea_stat(struct uea_softc *sc)
836{
837 u32 data;
838 int ret;
839
840 uea_enters(INS_TO_USBDEV(sc));
841 data = sc->stats.phy.state;
842
843 ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state);
844 if (ret < 0)
845 return ret;
846
847 switch (GET_STATUS(sc->stats.phy.state)) {
848 case 0: /* not yet synchronized */
849 uea_dbg(INS_TO_USBDEV(sc),
850 "modem not yet synchronized\n");
851 return 0;
852
853 case 1: /* initialization */
854 uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");
855 return 0;
856
857 case 2: /* operational */
858 uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n");
859 break;
860
861 case 3: /* fail ... */
862 uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n");
863 return -EAGAIN;
864
865 case 4 ... 6: /* test state */
866 uea_warn(INS_TO_USBDEV(sc),
867 "modem in test mode - not supported\n");
868 return -EAGAIN;
869
870 case 7: /* fast-retain ... */
871 uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n");
872 return 0;
873 default:
874 uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n",
875 GET_STATUS(sc->stats.phy.state));
876 return -EAGAIN;
877 }
878
879 if (GET_STATUS(data) != 2) {
880 uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);
881 uea_info(INS_TO_USBDEV(sc), "modem operational\n");
882
883 /* release the dsp firmware as it is not needed until
884 * the next failure
885 */
886 if (sc->dsp_firm) {
887 release_firmware(sc->dsp_firm);
888 sc->dsp_firm = NULL;
889 }
890
891 ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid);
892 if (ret < 0)
893 return ret;
894 uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
895 sc->stats.phy.firmid);
896 }
897
898 /* always update it as atm layer could not be init when we switch to
899 * operational state
900 */
901 UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND);
902
903 /* wake up processes waiting for synchronization */
904 wake_up(&sc->sync_q);
905
906 ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags);
907 if (ret < 0)
908 return ret;
909 sc->stats.phy.mflags |= sc->stats.phy.flags;
910
911 /* in case of a flags ( for example delineation LOSS (& 0x10)),
912 * we check the status again in order to detect the failure earlier
913 */
914 if (sc->stats.phy.flags) {
915 uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n",
916 sc->stats.phy.flags);
917 return 0;
918 }
919
920 ret = uea_read_cmv(sc, SA_RATE, 0, &data);
921 if (ret < 0)
922 return ret;
923
924 /* in bulk mode the modem have problem with high rate
925 * changing internal timing could improve things, but the
926 * value is misterious.
927 * ADI930 don't support it (-EPIPE error).
928 */
929 if (UEA_CHIP_VERSION(sc) != ADI930
930 && sc->stats.phy.dsrate != (data >> 16) * 32) {
931 /* Original timming from ADI(used in windows driver)
932 * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits
933 */
934 u16 timeout = (data <= 0x20ffff) ? 0 : 1;
935 ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL);
936 uea_info(INS_TO_USBDEV(sc),
937 "setting new timeout %d%s\n", timeout,
938 ret < 0?" failed":"");
939 }
940 sc->stats.phy.dsrate = (data >> 16) * 32;
941 sc->stats.phy.usrate = (data & 0xffff) * 32;
942 UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);
943
944 ret = uea_read_cmv(sc, SA_DIAG, 23, &data);
945 if (ret < 0)
946 return ret;
947 sc->stats.phy.dsattenuation = (data & 0xff) / 2;
948
949 ret = uea_read_cmv(sc, SA_DIAG, 47, &data);
950 if (ret < 0)
951 return ret;
952 sc->stats.phy.usattenuation = (data & 0xff) / 2;
953
954 ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin);
955 if (ret < 0)
956 return ret;
957
958 ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin);
959 if (ret < 0)
960 return ret;
961
962 ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow);
963 if (ret < 0)
964 return ret;
965
966 ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow);
967 if (ret < 0)
968 return ret;
969
970 ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc);
971 if (ret < 0)
972 return ret;
973
974 /* only for atu-c */
975 ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc);
976 if (ret < 0)
977 return ret;
978
979 ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr);
980 if (ret < 0)
981 return ret;
982
983 /* only for atu-c */
984 ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr);
985 if (ret < 0)
986 return ret;
987
988 ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco);
989 if (ret < 0)
990 return ret;
991
992 ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe);
993 if (ret < 0)
994 return ret;
995
996 return 0;
997}
998
999static int request_cmvs(struct uea_softc *sc,
1000 struct uea_cmvs **cmvs, const struct firmware **fw)
1001{
1002 int ret, size;
1003 u8 *data;
1004 char *file;
1005 static char cmv_name[256] = FW_DIR;
1006
1007 if (cmv_file[sc->modem_index] == NULL) {
1008 if (UEA_CHIP_VERSION(sc) == ADI930)
1009 file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin";
1010 else
1011 file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin";
1012 } else
1013 file = cmv_file[sc->modem_index];
1014
1015 strcpy(cmv_name, FW_DIR);
1016 strlcat(cmv_name, file, sizeof(cmv_name));
1017
1018 ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev);
1019 if (ret < 0) {
1020 uea_err(INS_TO_USBDEV(sc),
1021 "requesting firmware %s failed with error %d\n",
1022 cmv_name, ret);
1023 return ret;
1024 }
1025
1026 data = (u8 *) (*fw)->data;
1027 size = *data * sizeof(struct uea_cmvs) + 1;
1028 if (size != (*fw)->size) {
1029 uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
1030 cmv_name);
1031 release_firmware(*fw);
1032 return -EILSEQ;
1033 }
1034
1035 *cmvs = (struct uea_cmvs *)(data + 1);
1036 return *data;
1037}
1038
1039/* Start boot post firmware modem:
1040 * - send reset commands through usb control pipe
1041 * - start workqueue for DSP loading
1042 * - send CMV options to modem
1043 */
1044
1045static int uea_start_reset(struct uea_softc *sc)
1046{
1047 u16 zero = 0; /* ;-) */
1048 int i, len, ret;
1049 struct uea_cmvs *cmvs;
1050 const struct firmware *cmvs_fw;
1051
1052 uea_enters(INS_TO_USBDEV(sc));
1053 uea_info(INS_TO_USBDEV(sc), "(re)booting started\n");
1054
1055 sc->booting = 1;
1056 UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST);
1057
1058 /* reset statistics */
1059 memset(&sc->stats, 0, sizeof(struct uea_stats));
1060
1061 /* tell the modem that we want to boot in IDMA mode */
1062 uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
1063 uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL);
1064
1065 /* enter reset mode */
1066 uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL);
1067
1068 /* original driver use 200ms, but windows driver use 100ms */
1069 msleep(100);
1070
1071 /* leave reset mode */
1072 uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL);
1073
1074 /* clear tx and rx mailboxes */
1075 uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero);
1076 uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero);
1077 uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero);
1078
1079 msleep(1000);
1080 sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY);
1081 sc->booting = 0;
1082
1083 /* start loading DSP */
1084 sc->pageno = 0;
1085 sc->ovl = 0;
1086 schedule_work(&sc->task);
1087
1088 /* wait for modem ready CMV */
1089 ret = wait_cmv_ack(sc);
1090 if (ret < 0)
1091 return ret;
1092
1093 /* Enter in R-IDLE (cmv) until instructed otherwise */
1094 ret = uea_write_cmv(sc, SA_CNTL, 0, 1);
1095 if (ret < 0)
1096 return ret;
1097
1098 /* get options */
1099 ret = len = request_cmvs(sc, &cmvs, &cmvs_fw);
1100 if (ret < 0)
1101 return ret;
1102
1103 /* send options */
1104 for (i = 0; i < len; i++) {
1105 ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address),
1106 FW_GET_WORD(&cmvs[i].offset),
1107 FW_GET_LONG(&cmvs[i].data));
1108 if (ret < 0)
1109 goto out;
1110 }
1111 /* Enter in R-ACT-REQ */
1112 ret = uea_write_cmv(sc, SA_CNTL, 0, 2);
1113out:
1114 release_firmware(cmvs_fw);
1115 sc->reset = 0;
1116 uea_leaves(INS_TO_USBDEV(sc));
1117 return ret;
1118}
1119
1120/*
1121 * In case of an error wait 1s before rebooting the modem
1122 * if the modem don't request reboot (-EAGAIN).
1123 * Monitor the modem every 1s.
1124 */
1125
1126static int uea_kthread(void *data)
1127{
1128 struct uea_softc *sc = data;
1129 int ret = -EAGAIN;
1130
1131 uea_enters(INS_TO_USBDEV(sc));
1132 while (!kthread_should_stop()) {
1133 if (ret < 0 || sc->reset)
1134 ret = uea_start_reset(sc);
1135 if (!ret)
1136 ret = uea_stat(sc);
1137 if (ret != -EAGAIN)
1138 msleep(1000);
1139 }
1140 uea_leaves(INS_TO_USBDEV(sc));
1141 return ret;
1142}
1143
1144/* Load second usb firmware for ADI930 chip */
1145static int load_XILINX_firmware(struct uea_softc *sc)
1146{
1147 const struct firmware *fw_entry;
1148 int ret, size, u, ln;
1149 u8 *pfw, value;
1150 char *fw_name = FW_DIR "930-fpga.bin";
1151
1152 uea_enters(INS_TO_USBDEV(sc));
1153
1154 ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev);
1155 if (ret) {
1156 uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n",
1157 fw_name);
1158 goto err0;
1159 }
1160
1161 pfw = fw_entry->data;
1162 size = fw_entry->size;
1163 if (size != 0x577B) {
1164 uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
1165 fw_name);
1166 ret = -EILSEQ;
1167 goto err1;
1168 }
1169 for (u = 0; u < size; u += ln) {
1170 ln = min(size - u, 64);
1171 ret = uea_request(sc, 0xe, 0, ln, pfw + u);
1172 if (ret < 0) {
1173 uea_err(INS_TO_USBDEV(sc),
1174 "elsa download data failed (%d)\n", ret);
1175 goto err1;
1176 }
1177 }
1178
1179 /* finish to send the fpga
1180 */
1181 ret = uea_request(sc, 0xe, 1, 0, NULL);
1182 if (ret < 0) {
1183 uea_err(INS_TO_USBDEV(sc),
1184 "elsa download data failed (%d)\n", ret);
1185 goto err1;
1186 }
1187
1188 /*
1189 * Tell the modem we finish : de-assert reset
1190 */
1191 value = 0;
1192 ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value);
1193 if (ret < 0)
1194 uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret);
1195
1196
1197err1:
1198 release_firmware(fw_entry);
1199err0:
1200 uea_leaves(INS_TO_USBDEV(sc));
1201 return ret;
1202}
1203
1204static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv)
1205{
1206 uea_enters(INS_TO_USBDEV(sc));
1207 if (le16_to_cpu(cmv->wPreamble) != PREAMBLE)
1208 goto bad1;
1209
1210 if (cmv->bDirection != MODEMTOHOST)
1211 goto bad1;
1212
1213 /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to
1214 * the first MEMACESS cmv. Ignore it...
1215 */
1216 if (cmv->bFunction != sc->cmv_function) {
1217 if (UEA_CHIP_VERSION(sc) == ADI930
1218 && cmv->bFunction == MAKEFUNCTION(2, 2)) {
1219 cmv->wIndex = cpu_to_le16(sc->cmv_idx);
1220 put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress);
1221 cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset);
1222 }
1223 else
1224 goto bad2;
1225 }
1226
1227 if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) {
1228 wake_up_cmv_ack(sc);
1229 return;
1230 }
1231
1232 /* in case of MEMACCESS */
1233 if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx ||
1234 le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) !=
1235 sc->cmv_address
1236 || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset)
1237 goto bad2;
1238
1239 sc->data = le32_to_cpu(get_unaligned(&cmv->dwData));
1240 sc->data = sc->data << 16 | sc->data >> 16;
1241
1242 wake_up_cmv_ack(sc);
1243 return;
1244
1245bad2:
1246 uea_err(INS_TO_USBDEV(sc), "unexpected cmv received,"
1247 "Function : %d, Subfunction : %d\n",
1248 FUNCTION_TYPE(cmv->bFunction),
1249 FUNCTION_SUBTYPE(cmv->bFunction));
1250 return;
1251
1252bad1:
1253 uea_err(INS_TO_USBDEV(sc), "invalid cmv received, "
1254 "wPreamble %d, bDirection %d\n",
1255 le16_to_cpu(cmv->wPreamble), cmv->bDirection);
1256}
1257
1258/*
1259 * interrupt handler
1260 */
1261static void uea_intr(struct urb *urb, struct pt_regs *regs)
1262{
1263 struct uea_softc *sc = (struct uea_softc *)urb->context;
1264 struct intr_pkt *intr;
1265 uea_enters(INS_TO_USBDEV(sc));
1266
1267 if (urb->status < 0) {
1268 uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n",
1269 urb->status);
1270 return;
1271 }
1272
1273 intr = (struct intr_pkt *) urb->transfer_buffer;
1274
1275 /* device-to-host interrupt */
1276 if (intr->bType != 0x08 || sc->booting) {
1277 uea_err(INS_TO_USBDEV(sc), "wrong intr\n");
1278 // rebooting ?
1279 // sc->reset = 1;
1280 goto resubmit;
1281 }
1282
1283 switch (le16_to_cpu(intr->wInterrupt)) {
1284 case INT_LOADSWAPPAGE:
1285 sc->pageno = intr->bSwapPageNo;
1286 sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4;
1287 schedule_work(&sc->task);
1288 break;
1289
1290 case INT_INCOMINGCMV:
1291 uea_dispatch_cmv(sc, &intr->u.s2.cmv);
1292 break;
1293
1294 default:
1295 uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n",
1296 le16_to_cpu(intr->wInterrupt));
1297 }
1298
1299resubmit:
1300 usb_submit_urb(sc->urb_int, GFP_ATOMIC);
1301}
1302
1303/*
1304 * Start the modem : init the data and start kernel thread
1305 */
1306static int uea_boot(struct uea_softc *sc)
1307{
1308 int ret;
1309 struct intr_pkt *intr;
1310
1311 uea_enters(INS_TO_USBDEV(sc));
1312
1313 INIT_WORK(&sc->task, uea_load_page, sc);
1314 init_waitqueue_head(&sc->sync_q);
1315 init_waitqueue_head(&sc->cmv_ack_wait);
1316
1317 if (UEA_CHIP_VERSION(sc) == ADI930)
1318 load_XILINX_firmware(sc);
1319
1320 intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL);
1321 if (!intr) {
1322 uea_err(INS_TO_USBDEV(sc),
1323 "cannot allocate interrupt package\n");
1324 uea_leaves(INS_TO_USBDEV(sc));
1325 return -ENOMEM;
1326 }
1327
1328 sc->urb_int = usb_alloc_urb(0, GFP_KERNEL);
1329 if (!sc->urb_int) {
1330 uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n");
1331 goto err;
1332 }
1333
1334 usb_fill_int_urb(sc->urb_int, sc->usb_dev,
1335 usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
1336 intr, INTR_PKT_SIZE, uea_intr, sc,
1337 sc->usb_dev->actconfig->interface[0]->altsetting[0].
1338 endpoint[0].desc.bInterval);
1339
1340 ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
1341 if (ret < 0) {
1342 uea_err(INS_TO_USBDEV(sc),
1343 "urb submition failed with error %d\n", ret);
1344 goto err1;
1345 }
1346
1347 sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
1348 if (sc->kthread == ERR_PTR(-ENOMEM)) {
1349 uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
1350 goto err2;
1351 }
1352
1353 uea_leaves(INS_TO_USBDEV(sc));
1354 return 0;
1355
1356err2:
1357 usb_kill_urb(sc->urb_int);
1358err1:
1359 kfree(intr);
1360err:
1361 usb_free_urb(sc->urb_int);
1362 uea_leaves(INS_TO_USBDEV(sc));
1363 return -ENOMEM;
1364}
1365
1366/*
1367 * Stop the modem : kill kernel thread and free data
1368 */
1369static void uea_stop(struct uea_softc *sc)
1370{
1371 int ret;
1372 uea_enters(INS_TO_USBDEV(sc));
1373 ret = kthread_stop(sc->kthread);
1374 uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
1375
1376 /* stop any pending boot process */
1377 flush_scheduled_work();
1378
1379 uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
1380
1381 usb_kill_urb(sc->urb_int);
1382 kfree(sc->urb_int->transfer_buffer);
1383 usb_free_urb(sc->urb_int);
1384
1385 if (sc->dsp_firm)
1386 release_firmware(sc->dsp_firm);
1387 uea_leaves(INS_TO_USBDEV(sc));
1388}
1389
1390/* syfs interface */
1391static struct uea_softc *dev_to_uea(struct device *dev)
1392{
1393 struct usb_interface *intf;
1394 struct usbatm_data *usbatm;
1395
1396 intf = to_usb_interface(dev);
1397 if (!intf)
1398 return NULL;
1399
1400 usbatm = usb_get_intfdata(intf);
1401 if (!usbatm)
1402 return NULL;
1403
1404 return usbatm->driver_data;
1405}
1406
1407static ssize_t read_status(struct device *dev, struct device_attribute *attr,
1408 char *buf)
1409{
1410 int ret = -ENODEV;
1411 struct uea_softc *sc;
1412
1413 down(&uea_semaphore);
1414 sc = dev_to_uea(dev);
1415 if (!sc)
1416 goto out;
1417 ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state);
1418out:
1419 up(&uea_semaphore);
1420 return ret;
1421}
1422
1423static ssize_t reboot(struct device *dev, struct device_attribute *attr,
1424 const char *buf, size_t count)
1425{
1426 int ret = -ENODEV;
1427 struct uea_softc *sc;
1428
1429 down(&uea_semaphore);
1430 sc = dev_to_uea(dev);
1431 if (!sc)
1432 goto out;
1433 sc->reset = 1;
1434 ret = count;
1435out:
1436 up(&uea_semaphore);
1437 return ret;
1438}
1439
1440static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);
1441
1442static ssize_t read_human_status(struct device *dev, struct device_attribute *attr,
1443 char *buf)
1444{
1445 int ret = -ENODEV;
1446 struct uea_softc *sc;
1447
1448 down(&uea_semaphore);
1449 sc = dev_to_uea(dev);
1450 if (!sc)
1451 goto out;
1452
1453 switch (GET_STATUS(sc->stats.phy.state)) {
1454 case 0:
1455 ret = sprintf(buf, "Modem is booting\n");
1456 break;
1457 case 1:
1458 ret = sprintf(buf, "Modem is initializing\n");
1459 break;
1460 case 2:
1461 ret = sprintf(buf, "Modem is operational\n");
1462 break;
1463 default:
1464 ret = sprintf(buf, "Modem synchronization failed\n");
1465 break;
1466 }
1467out:
1468 up(&uea_semaphore);
1469 return ret;
1470}
1471
1472static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL);
1473
1474static ssize_t read_delin(struct device *dev, struct device_attribute *attr,
1475 char *buf)
1476{
1477 int ret = -ENODEV;
1478 struct uea_softc *sc;
1479
1480 down(&uea_semaphore);
1481 sc = dev_to_uea(dev);
1482 if (!sc)
1483 goto out;
1484
1485 if (sc->stats.phy.flags & 0x0C00)
1486 ret = sprintf(buf, "ERROR\n");
1487 else if (sc->stats.phy.flags & 0x0030)
1488 ret = sprintf(buf, "LOSS\n");
1489 else
1490 ret = sprintf(buf, "GOOD\n");
1491out:
1492 up(&uea_semaphore);
1493 return ret;
1494}
1495
1496static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);
1497
1498#define UEA_ATTR(name, reset) \
1499 \
1500static ssize_t read_##name(struct device *dev, \
1501 struct device_attribute *attr, char *buf) \
1502{ \
1503 int ret = -ENODEV; \
1504 struct uea_softc *sc; \
1505 \
1506 down(&uea_semaphore); \
1507 sc = dev_to_uea(dev); \
1508 if (!sc) \
1509 goto out; \
1510 ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name); \
1511 if (reset) \
1512 sc->stats.phy.name = 0; \
1513out: \
1514 up(&uea_semaphore); \
1515 return ret; \
1516} \
1517 \
1518static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL)
1519
1520UEA_ATTR(mflags, 1);
1521UEA_ATTR(vidcpe, 0);
1522UEA_ATTR(usrate, 0);
1523UEA_ATTR(dsrate, 0);
1524UEA_ATTR(usattenuation, 0);
1525UEA_ATTR(dsattenuation, 0);
1526UEA_ATTR(usmargin, 0);
1527UEA_ATTR(dsmargin, 0);
1528UEA_ATTR(txflow, 0);
1529UEA_ATTR(rxflow, 0);
1530UEA_ATTR(uscorr, 0);
1531UEA_ATTR(dscorr, 0);
1532UEA_ATTR(usunc, 0);
1533UEA_ATTR(dsunc, 0);
1534
1535/* Retrieve the device End System Identifier (MAC) */
1536
1537#define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10)
1538static int uea_getesi(struct uea_softc *sc, u_char * esi)
1539{
1540 unsigned char mac_str[2 * ETH_ALEN + 1];
1541 int i;
1542 if (usb_string
1543 (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str,
1544 sizeof(mac_str)) != 2 * ETH_ALEN)
1545 return 1;
1546
1547 for (i = 0; i < ETH_ALEN; i++)
1548 esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]);
1549
1550 return 0;
1551}
1552
1553/* ATM stuff */
1554static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
1555{
1556 struct uea_softc *sc = usbatm->driver_data;
1557
1558 return uea_getesi(sc, atm_dev->esi);
1559}
1560
1561static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf)
1562{
1563 struct uea_softc *sc = usbatm->driver_data;
1564
1565 wait_event(sc->sync_q, IS_OPERATIONAL(sc));
1566
1567 return 0;
1568
1569}
1570
1571static int claim_interface(struct usb_device *usb_dev,
1572 struct usbatm_data *usbatm, int ifnum)
1573{
1574 int ret;
1575 struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum);
1576
1577 if (!intf) {
1578 uea_err(usb_dev, "interface %d not found\n", ifnum);
1579 return -ENODEV;
1580 }
1581
1582 ret = usb_driver_claim_interface(&uea_driver, intf, usbatm);
1583 if (ret != 0)
1584 uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum,
1585 ret);
1586 return ret;
1587}
1588
1589static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
1590{
1591 /* sysfs interface */
1592 device_create_file(&intf->dev, &dev_attr_stat_status);
1593 device_create_file(&intf->dev, &dev_attr_stat_mflags);
1594 device_create_file(&intf->dev, &dev_attr_stat_human_status);
1595 device_create_file(&intf->dev, &dev_attr_stat_delin);
1596 device_create_file(&intf->dev, &dev_attr_stat_vidcpe);
1597 device_create_file(&intf->dev, &dev_attr_stat_usrate);
1598 device_create_file(&intf->dev, &dev_attr_stat_dsrate);
1599 device_create_file(&intf->dev, &dev_attr_stat_usattenuation);
1600 device_create_file(&intf->dev, &dev_attr_stat_dsattenuation);
1601 device_create_file(&intf->dev, &dev_attr_stat_usmargin);
1602 device_create_file(&intf->dev, &dev_attr_stat_dsmargin);
1603 device_create_file(&intf->dev, &dev_attr_stat_txflow);
1604 device_create_file(&intf->dev, &dev_attr_stat_rxflow);
1605 device_create_file(&intf->dev, &dev_attr_stat_uscorr);
1606 device_create_file(&intf->dev, &dev_attr_stat_dscorr);
1607 device_create_file(&intf->dev, &dev_attr_stat_usunc);
1608 device_create_file(&intf->dev, &dev_attr_stat_dsunc);
1609}
1610
1611static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
1612 const struct usb_device_id *id, int *heavy)
1613{
1614 struct usb_device *usb = interface_to_usbdev(intf);
1615 struct uea_softc *sc;
1616 int ret, ifnum = intf->altsetting->desc.bInterfaceNumber;
1617
1618 uea_enters(usb);
1619
1620 /* interface 0 is for firmware/monitoring */
1621 if (ifnum != UEA_INTR_IFACE_NO)
1622 return -ENODEV;
1623
1624 *heavy = sync_wait[modem_index];
1625
1626 /* interface 1 is for outbound traffic */
1627 ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO);
1628 if (ret < 0)
1629 return ret;
1630
1631 /* ADI930 has only 2 interfaces and inbound traffic
1632 * is on interface 1
1633 */
1634 if (UEA_CHIP_VERSION(id) != ADI930) {
1635 /* interface 2 is for inbound traffic */
1636 ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO);
1637 if (ret < 0)
1638 return ret;
1639 }
1640
1641 sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL);
1642 if (!sc) {
1643 uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n");
1644 return -ENOMEM;
1645 }
1646
1647 sc->usb_dev = usb;
1648 usbatm->driver_data = sc;
1649 sc->usbatm = usbatm;
1650 sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0;
1651 sc->driver_info = id->driver_info;
1652
1653 ret = uea_boot(sc);
1654 if (ret < 0) {
1655 kfree(sc);
1656 return ret;
1657 }
1658
1659 create_fs_entries(sc, intf);
1660 return 0;
1661}
1662
1663static void destroy_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
1664{
1665 /* sysfs interface */
1666 device_remove_file(&intf->dev, &dev_attr_stat_status);
1667 device_remove_file(&intf->dev, &dev_attr_stat_mflags);
1668 device_remove_file(&intf->dev, &dev_attr_stat_human_status);
1669 device_remove_file(&intf->dev, &dev_attr_stat_delin);
1670 device_remove_file(&intf->dev, &dev_attr_stat_vidcpe);
1671 device_remove_file(&intf->dev, &dev_attr_stat_usrate);
1672 device_remove_file(&intf->dev, &dev_attr_stat_dsrate);
1673 device_remove_file(&intf->dev, &dev_attr_stat_usattenuation);
1674 device_remove_file(&intf->dev, &dev_attr_stat_dsattenuation);
1675 device_remove_file(&intf->dev, &dev_attr_stat_usmargin);
1676 device_remove_file(&intf->dev, &dev_attr_stat_dsmargin);
1677 device_remove_file(&intf->dev, &dev_attr_stat_txflow);
1678 device_remove_file(&intf->dev, &dev_attr_stat_rxflow);
1679 device_remove_file(&intf->dev, &dev_attr_stat_uscorr);
1680 device_remove_file(&intf->dev, &dev_attr_stat_dscorr);
1681 device_remove_file(&intf->dev, &dev_attr_stat_usunc);
1682 device_remove_file(&intf->dev, &dev_attr_stat_dsunc);
1683}
1684
1685static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
1686{
1687 struct uea_softc *sc = usbatm->driver_data;
1688
1689 destroy_fs_entries(sc, intf);
1690 uea_stop(sc);
1691 kfree(sc);
1692}
1693
1694static struct usbatm_driver uea_usbatm_driver = {
1695 .driver_name = "ueagle-atm",
1696 .owner = THIS_MODULE,
1697 .bind = uea_bind,
1698 .atm_start = uea_atm_open,
1699 .unbind = uea_unbind,
1700 .heavy_init = uea_heavy,
1701 .in = UEA_BULK_DATA_PIPE,
1702 .out = UEA_BULK_DATA_PIPE,
1703};
1704
1705static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
1706{
1707 struct usb_device *usb = interface_to_usbdev(intf);
1708
1709 uea_enters(usb);
1710 uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n",
1711 le16_to_cpu(usb->descriptor.idVendor),
1712 le16_to_cpu(usb->descriptor.idProduct),
1713 chip_name[UEA_CHIP_VERSION(id)]);
1714
1715 usb_reset_device(usb);
1716
1717 if (UEA_IS_PREFIRM(id))
1718 return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
1719
1720 return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
1721}
1722
1723static void uea_disconnect(struct usb_interface *intf)
1724{
1725 struct usb_device *usb = interface_to_usbdev(intf);
1726 int ifnum = intf->altsetting->desc.bInterfaceNumber;
1727 uea_enters(usb);
1728
1729 /* ADI930 has 2 interfaces and eagle 3 interfaces.
1730 * Pre-firmware device has one interface
1731 */
1732 if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) {
1733 down(&uea_semaphore);
1734 usbatm_usb_disconnect(intf);
1735 up(&uea_semaphore);
1736 uea_info(usb, "ADSL device removed\n");
1737 }
1738
1739 uea_leaves(usb);
1740}
1741
1742/*
1743 * List of supported VID/PID
1744 */
1745static const struct usb_device_id uea_ids[] = {
1746 {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM},
1747 {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM},
1748 {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM},
1749 {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM},
1750 {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM},
1751 {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM},
1752 {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM},
1753 {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM},
1754 {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM},
1755 {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM},
1756 {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM},
1757 {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM},
1758 {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM},
1759 {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM},
1760 {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
1761 {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
1762 {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
1763 {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
1764 {}
1765};
1766
1767/*
1768 * USB driver descriptor
1769 */
1770static struct usb_driver uea_driver = {
1771 .owner = THIS_MODULE,
1772 .name = "ueagle-atm",
1773 .id_table = uea_ids,
1774 .probe = uea_probe,
1775 .disconnect = uea_disconnect,
1776};
1777
1778MODULE_DEVICE_TABLE(usb, uea_ids);
1779
1780/**
1781 * uea_init - Initialize the module.
1782 * Register to USB subsystem
1783 */
1784static int __init uea_init(void)
1785{
1786 printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n");
1787
1788 usb_register(&uea_driver);
1789
1790 return 0;
1791}
1792
1793module_init(uea_init);
1794
1795/**
1796 * uea_exit - Destroy module
1797 * Deregister with USB subsystem
1798 */
1799static void __exit uea_exit(void)
1800{
1801 /*
1802 * This calls automatically the uea_disconnect method if necessary:
1803 */
1804 usb_deregister(&uea_driver);
1805
1806 printk(KERN_INFO "[ueagle-atm] driver unloaded\n");
1807}
1808
1809module_exit(uea_exit);
1810
1811MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka");
1812MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver");
1813MODULE_LICENSE("Dual BSD/GPL");