📄 ueagle-atm.c
字号:
/*- * Copyright (c) 2003, 2004 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. * * Copyright (c) 2005-2007 Matthieu Castet <castet.matthieu@free.fr> * Copyright (c) 2005-2007 Stanislaw Gruszka <stf_xl@wp.pl> * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * BSD license below: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * GPL license : * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * HISTORY : some part of the code was base on ueagle 1.3 BSD driver, * Damien Bergamini agree to put his code under a DUAL GPL/BSD license. * * The rest of the code was was rewritten from scratch. */#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/crc32.h>#include <linux/usb.h>#include <linux/firmware.h>#include <linux/ctype.h>#include <linux/sched.h>#include <linux/kthread.h>#include <linux/version.h>#include <linux/mutex.h>#include <linux/freezer.h>#include <asm/unaligned.h>#include "usbatm.h"#define EAGLEUSBVERSION "ueagle 1.4"/* * Debug macros */#define uea_dbg(usb_dev, format, args...) \ do { \ if (debug >= 1) \ dev_dbg(&(usb_dev)->dev, \ "[ueagle-atm dbg] %s: " format, \ __FUNCTION__, ##args); \ } while (0)#define uea_vdbg(usb_dev, format, args...) \ do { \ if (debug >= 2) \ dev_dbg(&(usb_dev)->dev, \ "[ueagle-atm vdbg] " format, ##args); \ } while (0)#define uea_enters(usb_dev) \ uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)#define uea_leaves(usb_dev) \ uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__)#define uea_err(usb_dev, format,args...) \ dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)#define uea_warn(usb_dev, format,args...) \ dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args)#define uea_info(usb_dev, format,args...) \ dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args)struct intr_pkt;/* cmv's from firmware */struct uea_cmvs_v1 { u32 address; u16 offset; u32 data;} __attribute__ ((packed));struct uea_cmvs_v2 { u32 group; u32 address; u32 offset; u32 data;} __attribute__ ((packed));/* information about currently processed cmv */struct cmv_dsc_e1 { u8 function; u16 idx; u32 address; u16 offset;};struct cmv_dsc_e4 { u16 function; u16 offset; u16 address; u16 group;};union cmv_dsc { struct cmv_dsc_e1 e1; struct cmv_dsc_e4 e4;};struct uea_softc { struct usb_device *usb_dev; struct usbatm_data *usbatm; int modem_index; unsigned int driver_info; int annex;#define ANNEXA 0#define ANNEXB 1 int booting; int reset; wait_queue_head_t sync_q; struct task_struct *kthread; u32 data; u32 data1; int cmv_ack; union cmv_dsc cmv_dsc; struct work_struct task; struct workqueue_struct *work_q; u16 pageno; u16 ovl; const struct firmware *dsp_firm; struct urb *urb_int; void (*dispatch_cmv) (struct uea_softc *, struct intr_pkt *); void (*schedule_load_page) (struct uea_softc *, struct intr_pkt *); int (*stat) (struct uea_softc *); int (*send_cmvs) (struct uea_softc *); /* keep in sync with eaglectl */ struct uea_stats { struct { u32 state; u32 flags; u32 mflags; u32 vidcpe; u32 vidco; u32 dsrate; u32 usrate; u32 dsunc; u32 usunc; u32 dscorr; u32 uscorr; u32 txflow; u32 rxflow; u32 usattenuation; u32 dsattenuation; u32 dsmargin; u32 usmargin; u32 firmid; } phy; } stats;};/* * Elsa IDs */#define ELSA_VID 0x05CC#define ELSA_PID_PSTFIRM 0x3350#define ELSA_PID_PREFIRM 0x3351#define ELSA_PID_A_PREFIRM 0x3352#define ELSA_PID_A_PSTFIRM 0x3353#define ELSA_PID_B_PREFIRM 0x3362#define ELSA_PID_B_PSTFIRM 0x3363/* * Devolo IDs : pots if (pid & 0x10) */#define DEVOLO_VID 0x1039#define DEVOLO_EAGLE_I_A_PID_PSTFIRM 0x2110#define DEVOLO_EAGLE_I_A_PID_PREFIRM 0x2111#define DEVOLO_EAGLE_I_B_PID_PSTFIRM 0x2100#define DEVOLO_EAGLE_I_B_PID_PREFIRM 0x2101#define DEVOLO_EAGLE_II_A_PID_PSTFIRM 0x2130#define DEVOLO_EAGLE_II_A_PID_PREFIRM 0x2131#define DEVOLO_EAGLE_II_B_PID_PSTFIRM 0x2120#define DEVOLO_EAGLE_II_B_PID_PREFIRM 0x2121/* * Reference design USB IDs */#define ANALOG_VID 0x1110#define ADI930_PID_PREFIRM 0x9001#define ADI930_PID_PSTFIRM 0x9000#define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */#define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */#define EAGLE_IIC_PID_PREFIRM 0x9024 /* Eagle IIC */#define EAGLE_IIC_PID_PSTFIRM 0x9023 /* Eagle IIC */#define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */#define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */#define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */#define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */#define EAGLE_IV_PID_PREFIRM 0x9042 /* Eagle IV */#define EAGLE_IV_PID_PSTFIRM 0x9041 /* Eagle IV *//* * USR USB IDs */#define USR_VID 0x0BAF#define MILLER_A_PID_PREFIRM 0x00F2#define MILLER_A_PID_PSTFIRM 0x00F1#define MILLER_B_PID_PREFIRM 0x00FA#define MILLER_B_PID_PSTFIRM 0x00F9#define HEINEKEN_A_PID_PREFIRM 0x00F6#define HEINEKEN_A_PID_PSTFIRM 0x00F5#define HEINEKEN_B_PID_PREFIRM 0x00F8#define HEINEKEN_B_PID_PSTFIRM 0x00F7#define PREFIRM 0#define PSTFIRM (1<<7)#define AUTO_ANNEX_A (1<<8)#define AUTO_ANNEX_B (1<<9)enum { ADI930 = 0, EAGLE_I, EAGLE_II, EAGLE_III, EAGLE_IV};/* macros for both struct usb_device_id and struct uea_softc */#define UEA_IS_PREFIRM(x) \ (!((x)->driver_info & PSTFIRM))#define UEA_CHIP_VERSION(x) \ ((x)->driver_info & 0xf)#define IS_ISDN(x) \ ((x)->annex & ANNEXB)#define INS_TO_USBDEV(ins) ins->usb_dev#define GET_STATUS(data) \ ((data >> 8) & 0xf)#define IS_OPERATIONAL(sc) \ ((UEA_CHIP_VERSION(sc) != EAGLE_IV) ? \ (GET_STATUS(sc->stats.phy.state) == 2) : \ (sc->stats.phy.state == 7))/* * Set of macros to handle unaligned data in the firmware blob. * The FW_GET_BYTE() macro is provided only for consistency. */#define FW_GET_BYTE(p) *((__u8 *) (p))#define FW_GET_WORD(p) le16_to_cpu(get_unaligned((__le16 *) (p)))#define FW_GET_LONG(p) le32_to_cpu(get_unaligned((__le32 *) (p)))#define FW_DIR "ueagle-atm/"#define NB_MODEM 4#define BULK_TIMEOUT 300#define CTRL_TIMEOUT 1000#define ACK_TIMEOUT msecs_to_jiffies(3000)#define UEA_INTR_IFACE_NO 0#define UEA_US_IFACE_NO 1#define UEA_DS_IFACE_NO 2#define FASTEST_ISO_INTF 8#define UEA_BULK_DATA_PIPE 0x02#define UEA_IDMA_PIPE 0x04#define UEA_INTR_PIPE 0x04#define UEA_ISO_DATA_PIPE 0x08#define UEA_E1_SET_BLOCK 0x0001#define UEA_E4_SET_BLOCK 0x002c#define UEA_SET_MODE 0x0003#define UEA_SET_2183_DATA 0x0004#define UEA_SET_TIMEOUT 0x0011#define UEA_LOOPBACK_OFF 0x0002#define UEA_LOOPBACK_ON 0x0003#define UEA_BOOT_IDMA 0x0006#define UEA_START_RESET 0x0007#define UEA_END_RESET 0x0008#define UEA_SWAP_MAILBOX (0x3fcd | 0x4000)#define UEA_MPTX_START (0x3fce | 0x4000)#define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000)#define UEA_MPRX_MAILBOX (0x3fdf | 0x4000)/* block information in eagle4 dsp firmware */struct block_index { __le32 PageOffset; __le32 NotLastBlock; __le32 dummy; __le32 PageSize; __le32 PageAddress; __le16 dummy1; __le16 PageNumber;} __attribute__ ((packed));#define E4_IS_BOOT_PAGE(PageSize) ((le32_to_cpu(PageSize)) & 0x80000000)#define E4_PAGE_BYTES(PageSize) ((le32_to_cpu(PageSize) & 0x7fffffff) * 4)#define E4_L1_STRING_HEADER 0x10#define E4_MAX_PAGE_NUMBER 0x58#define E4_NO_SWAPPAGE_HEADERS 0x31/* l1_code is eagle4 dsp firmware format */struct l1_code { u8 string_header[E4_L1_STRING_HEADER]; u8 page_number_to_block_index[E4_MAX_PAGE_NUMBER]; struct block_index page_header[E4_NO_SWAPPAGE_HEADERS]; u8 code [0];} __attribute__ ((packed));/* structures describing a block within a DSP page */struct block_info_e1 { __le16 wHdr; __le16 wAddress; __le16 wSize; __le16 wOvlOffset; __le16 wOvl; /* overlay */ __le16 wLast;} __attribute__ ((packed));#define E1_BLOCK_INFO_SIZE 12struct block_info_e4 { __be16 wHdr; __u8 bBootPage; __u8 bPageNumber; __be32 dwSize; __be32 dwAddress; __be16 wReserved;} __attribute__ ((packed));#define E4_BLOCK_INFO_SIZE 14#define UEA_BIHDR 0xabcd#define UEA_RESERVED 0xffff/* constants describing cmv type */#define E1_PREAMBLE 0x535c#define E1_MODEMTOHOST 0x01#define E1_HOSTTOMODEM 0x10#define E1_MEMACCESS 0x1#define E1_ADSLDIRECTIVE 0x7#define E1_FUNCTION_TYPE(f) ((f) >> 4)#define E1_FUNCTION_SUBTYPE(f) ((f) & 0x0f)#define E4_MEMACCESS 0#define E4_ADSLDIRECTIVE 0xf#define E4_FUNCTION_TYPE(f) ((f) >> 8)#define E4_FUNCTION_SIZE(f) ((f) & 0x0f)#define E4_FUNCTION_SUBTYPE(f) (((f) >> 4) & 0x0f)/* for MEMACCESS */#define E1_REQUESTREAD 0x0#define E1_REQUESTWRITE 0x1#define E1_REPLYREAD 0x2#define E1_REPLYWRITE 0x3#define E4_REQUESTREAD 0x0#define E4_REQUESTWRITE 0x4#define E4_REPLYREAD (E4_REQUESTREAD | 1)#define E4_REPLYWRITE (E4_REQUESTWRITE | 1)/* for ADSLDIRECTIVE */#define E1_KERNELREADY 0x0#define E1_MODEMREADY 0x1#define E4_KERNELREADY 0x0#define E4_MODEMREADY 0x1#define E1_MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf))#define E4_MAKEFUNCTION(t, st, s) (((t) & 0xf) << 8 | ((st) & 0xf) << 4 | ((s) & 0xf))#define E1_MAKESA(a, b, c, d) \ (((c) & 0xff) << 24 | \ ((d) & 0xff) << 16 | \ ((a) & 0xff) << 8 | \ ((b) & 0xff))#define E1_GETSA1(a) ((a >> 8) & 0xff)#define E1_GETSA2(a) (a & 0xff)#define E1_GETSA3(a) ((a >> 24) & 0xff)#define E1_GETSA4(a) ((a >> 16) & 0xff)#define E1_SA_CNTL E1_MAKESA('C', 'N', 'T', 'L')#define E1_SA_DIAG E1_MAKESA('D', 'I', 'A', 'G')#define E1_SA_INFO E1_MAKESA('I', 'N', 'F', 'O')#define E1_SA_OPTN E1_MAKESA('O', 'P', 'T', 'N')#define E1_SA_RATE E1_MAKESA('R', 'A', 'T', 'E')#define E1_SA_STAT E1_MAKESA('S', 'T', 'A', 'T')#define E4_SA_CNTL 1#define E4_SA_STAT 2#define E4_SA_INFO 3#define E4_SA_TEST 4#define E4_SA_OPTN 5#define E4_SA_RATE 6#define E4_SA_DIAG 7#define E4_SA_CNFG 8/* structures representing a CMV (Configuration and Management Variable) */struct cmv_e1 { __le16 wPreamble; __u8 bDirection; __u8 bFunction; __le16 wIndex; __le32 dwSymbolicAddress; __le16 wOffsetAddress; __le32 dwData;} __attribute__ ((packed));struct cmv_e4 { __be16 wGroup; __be16 wFunction; __be16 wOffset; __be16 wAddress; __be32 dwData [6];} __attribute__ ((packed));/* structures representing swap information */struct swap_info_e1 { __u8 bSwapPageNo; __u8 bOvl; /* overlay */} __attribute__ ((packed));struct swap_info_e4 { __u8 bSwapPageNo;} __attribute__ ((packed));/* structures representing interrupt data */#define e1_bSwapPageNo u.e1.s1.swapinfo.bSwapPageNo#define e1_bOvl u.e1.s1.swapinfo.bOvl#define e4_bSwapPageNo u.e4.s1.swapinfo.bSwapPageNo#define INT_LOADSWAPPAGE 0x0001#define INT_INCOMINGCMV 0x0002union intr_data_e1 { struct { struct swap_info_e1 swapinfo; __le16 wDataSize; } __attribute__ ((packed)) s1; struct { struct cmv_e1 cmv; __le16 wDataSize; } __attribute__ ((packed)) s2;} __attribute__ ((packed));union intr_data_e4 { struct { struct swap_info_e4 swapinfo; __le16 wDataSize; } __attribute__ ((packed)) s1; struct { struct cmv_e4 cmv; __le16 wDataSize; } __attribute__ ((packed)) s2;} __attribute__ ((packed));struct intr_pkt { __u8 bType; __u8 bNotification; __le16 wValue; __le16 wIndex; __le16 wLength; __le16 wInterrupt; union {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -