Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Copyright (c) 2003, 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *	Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (c) 2005-2007 Matthieu Castet <castet.matthieu@free.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (c) 2005-2007 Stanislaw Gruszka <stf_xl@wp.pl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * HISTORY : some part of the code was base on ueagle 1.3 BSD driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Damien Bergamini agree to put his code under a DUAL GPL/BSD license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * The rest of the code was was rewritten from scratch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include "usbatm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define EAGLEUSBVERSION "ueagle 1.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  * Debug macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define uea_dbg(usb_dev, format, args...)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 		if (debug >= 1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 			dev_dbg(&(usb_dev)->dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 				"[ueagle-atm dbg] %s: " format, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 					__func__, ##args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define uea_vdbg(usb_dev, format, args...)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		if (debug >= 2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 			dev_dbg(&(usb_dev)->dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 				"[ueagle-atm vdbg]  " format, ##args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define uea_enters(usb_dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	uea_vdbg(usb_dev, "entering %s\n" , __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define uea_leaves(usb_dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	uea_vdbg(usb_dev, "leaving  %s\n" , __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define uea_err(usb_dev, format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	dev_err(&(usb_dev)->dev , "[UEAGLE-ATM] " format , ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define uea_warn(usb_dev, format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	dev_warn(&(usb_dev)->dev , "[Ueagle-atm] " format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define uea_info(usb_dev, format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	dev_info(&(usb_dev)->dev , "[ueagle-atm] " format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) struct intr_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) /* cmv's from firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) struct uea_cmvs_v1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	u32 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) struct uea_cmvs_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	u32 group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	u32 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) /* information about currently processed cmv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) struct cmv_dsc_e1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	u8 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	u16 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	u32 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) struct cmv_dsc_e4 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	u16 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	u16 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	u16 group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) union cmv_dsc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	struct cmv_dsc_e1 e1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct cmv_dsc_e4 e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) struct uea_softc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	struct usb_device *usb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	struct usbatm_data *usbatm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	int modem_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	unsigned int driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	int annex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define ANNEXA 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define ANNEXB 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	int booting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	int reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	wait_queue_head_t sync_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	struct task_struct *kthread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	u32 data1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	int cmv_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	union cmv_dsc cmv_dsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	struct work_struct task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	u16 pageno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	u16 ovl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	const struct firmware *dsp_firm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	struct urb *urb_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	void (*dispatch_cmv)(struct uea_softc *, struct intr_pkt *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	void (*schedule_load_page)(struct uea_softc *, struct intr_pkt *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	int (*stat)(struct uea_softc *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	int (*send_cmvs)(struct uea_softc *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	/* keep in sync with eaglectl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	struct uea_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 			u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 			u32 mflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 			u32 vidcpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 			u32 vidco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			u32 dsrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 			u32 usrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 			u32 dsunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 			u32 usunc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 			u32 dscorr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 			u32 uscorr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 			u32 txflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 			u32 rxflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 			u32 usattenuation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 			u32 dsattenuation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 			u32 dsmargin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			u32 usmargin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 			u32 firmid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		} phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	} stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  * Elsa IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) #define ELSA_VID		0x05CC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) #define ELSA_PID_PSTFIRM	0x3350
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) #define ELSA_PID_PREFIRM	0x3351
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) #define ELSA_PID_A_PREFIRM	0x3352
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) #define ELSA_PID_A_PSTFIRM	0x3353
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) #define ELSA_PID_B_PREFIRM	0x3362
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) #define ELSA_PID_B_PSTFIRM	0x3363
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)  * Devolo IDs : pots if (pid & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) #define DEVOLO_VID			0x1039
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) #define DEVOLO_EAGLE_I_A_PID_PSTFIRM	0x2110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) #define DEVOLO_EAGLE_I_A_PID_PREFIRM	0x2111
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) #define DEVOLO_EAGLE_I_B_PID_PSTFIRM	0x2100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) #define DEVOLO_EAGLE_I_B_PID_PREFIRM	0x2101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) #define DEVOLO_EAGLE_II_A_PID_PSTFIRM	0x2130
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) #define DEVOLO_EAGLE_II_A_PID_PREFIRM	0x2131
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) #define DEVOLO_EAGLE_II_B_PID_PSTFIRM	0x2120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) #define DEVOLO_EAGLE_II_B_PID_PREFIRM	0x2121
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  * Reference design USB IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) #define ANALOG_VID		0x1110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) #define ADI930_PID_PREFIRM	0x9001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) #define ADI930_PID_PSTFIRM	0x9000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) #define EAGLE_I_PID_PREFIRM	0x9010	/* Eagle I */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) #define EAGLE_I_PID_PSTFIRM	0x900F	/* Eagle I */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) #define EAGLE_IIC_PID_PREFIRM	0x9024	/* Eagle IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) #define EAGLE_IIC_PID_PSTFIRM	0x9023	/* Eagle IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) #define EAGLE_II_PID_PREFIRM	0x9022	/* Eagle II */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) #define EAGLE_II_PID_PSTFIRM	0x9021	/* Eagle II */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) #define EAGLE_III_PID_PREFIRM	0x9032	/* Eagle III */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) #define EAGLE_III_PID_PSTFIRM	0x9031	/* Eagle III */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) #define EAGLE_IV_PID_PREFIRM	0x9042  /* Eagle IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) #define EAGLE_IV_PID_PSTFIRM	0x9041  /* Eagle IV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214)  * USR USB IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) #define USR_VID			0x0BAF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) #define MILLER_A_PID_PREFIRM	0x00F2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) #define MILLER_A_PID_PSTFIRM	0x00F1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) #define MILLER_B_PID_PREFIRM	0x00FA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) #define MILLER_B_PID_PSTFIRM	0x00F9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) #define HEINEKEN_A_PID_PREFIRM	0x00F6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) #define HEINEKEN_A_PID_PSTFIRM	0x00F5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) #define HEINEKEN_B_PID_PREFIRM	0x00F8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) #define HEINEKEN_B_PID_PSTFIRM	0x00F7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) #define PREFIRM 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) #define PSTFIRM (1<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) #define AUTO_ANNEX_A (1<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) #define AUTO_ANNEX_B (1<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	ADI930 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	EAGLE_I,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	EAGLE_II,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	EAGLE_III,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	EAGLE_IV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) /* macros for both struct usb_device_id and struct uea_softc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) #define UEA_IS_PREFIRM(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	(!((x)->driver_info & PSTFIRM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) #define UEA_CHIP_VERSION(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	((x)->driver_info & 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) #define IS_ISDN(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	((x)->annex & ANNEXB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) #define INS_TO_USBDEV(ins) (ins->usb_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) #define GET_STATUS(data) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	((data >> 8) & 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) #define IS_OPERATIONAL(sc) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	((UEA_CHIP_VERSION(sc) != EAGLE_IV) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	(GET_STATUS(sc->stats.phy.state) == 2) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	(sc->stats.phy.state == 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)  * Set of macros to handle unaligned data in the firmware blob.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260)  * The FW_GET_BYTE() macro is provided only for consistency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) #define FW_GET_BYTE(p) (*((__u8 *) (p)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) #define FW_DIR "ueagle-atm/"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) #define EAGLE_FIRMWARE FW_DIR "eagle.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) #define ADI930_FIRMWARE FW_DIR "adi930.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) #define EAGLE_I_FIRMWARE FW_DIR "eagleI.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) #define EAGLE_II_FIRMWARE FW_DIR "eagleII.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) #define EAGLE_III_FIRMWARE FW_DIR "eagleIII.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) #define EAGLE_IV_FIRMWARE FW_DIR "eagleIV.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) #define DSP4I_FIRMWARE FW_DIR "DSP4i.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) #define DSP4P_FIRMWARE FW_DIR "DSP4p.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) #define DSP9I_FIRMWARE FW_DIR "DSP9i.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) #define DSP9P_FIRMWARE FW_DIR "DSP9p.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) #define DSPEI_FIRMWARE FW_DIR "DSPei.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) #define DSPEP_FIRMWARE FW_DIR "DSPep.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) #define FPGA930_FIRMWARE FW_DIR "930-fpga.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) #define CMV4P_FIRMWARE FW_DIR "CMV4p.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) #define CMV4PV2_FIRMWARE FW_DIR "CMV4p.bin.v2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) #define CMV4I_FIRMWARE FW_DIR "CMV4i.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) #define CMV4IV2_FIRMWARE FW_DIR "CMV4i.bin.v2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) #define CMV9P_FIRMWARE FW_DIR "CMV9p.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) #define CMV9PV2_FIRMWARE FW_DIR "CMV9p.bin.v2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) #define CMV9I_FIRMWARE FW_DIR "CMV9i.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) #define CMV9IV2_FIRMWARE FW_DIR "CMV9i.bin.v2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) #define CMVEP_FIRMWARE FW_DIR "CMVep.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) #define CMVEPV2_FIRMWARE FW_DIR "CMVep.bin.v2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) #define CMVEI_FIRMWARE FW_DIR "CMVei.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) #define CMVEIV2_FIRMWARE FW_DIR "CMVei.bin.v2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) #define UEA_FW_NAME_MAX 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) #define NB_MODEM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) #define BULK_TIMEOUT 300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) #define CTRL_TIMEOUT 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) #define ACK_TIMEOUT msecs_to_jiffies(3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) #define UEA_INTR_IFACE_NO	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) #define UEA_US_IFACE_NO		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) #define UEA_DS_IFACE_NO		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) #define FASTEST_ISO_INTF	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) #define UEA_BULK_DATA_PIPE	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) #define UEA_IDMA_PIPE		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) #define UEA_INTR_PIPE		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) #define UEA_ISO_DATA_PIPE	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) #define UEA_E1_SET_BLOCK	0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) #define UEA_E4_SET_BLOCK	0x002c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) #define UEA_SET_MODE		0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) #define UEA_SET_2183_DATA	0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) #define UEA_SET_TIMEOUT		0x0011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) #define UEA_LOOPBACK_OFF	0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) #define UEA_LOOPBACK_ON		0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) #define UEA_BOOT_IDMA		0x0006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) #define UEA_START_RESET		0x0007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) #define UEA_END_RESET		0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) #define UEA_SWAP_MAILBOX	(0x3fcd | 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) #define UEA_MPTX_START		(0x3fce | 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) #define UEA_MPTX_MAILBOX	(0x3fd6 | 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) #define UEA_MPRX_MAILBOX	(0x3fdf | 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) /* block information in eagle4 dsp firmware  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) struct block_index {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	__le32 PageOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	__le32 NotLastBlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	__le32 dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	__le32 PageSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	__le32 PageAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	__le16 dummy1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	__le16 PageNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) #define E4_IS_BOOT_PAGE(PageSize) ((le32_to_cpu(PageSize)) & 0x80000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) #define E4_PAGE_BYTES(PageSize) ((le32_to_cpu(PageSize) & 0x7fffffff) * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) #define E4_L1_STRING_HEADER 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) #define E4_MAX_PAGE_NUMBER 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) #define E4_NO_SWAPPAGE_HEADERS 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) /* l1_code is eagle4 dsp firmware format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) struct l1_code {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	u8 string_header[E4_L1_STRING_HEADER];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	u8 page_number_to_block_index[E4_MAX_PAGE_NUMBER];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	struct block_index page_header[E4_NO_SWAPPAGE_HEADERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	u8 code[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) /* structures describing a block within a DSP page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) struct block_info_e1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	__le16 wHdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	__le16 wAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	__le16 wSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	__le16 wOvlOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	__le16 wOvl;		/* overlay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	__le16 wLast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) #define E1_BLOCK_INFO_SIZE 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) struct block_info_e4 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	__be16 wHdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	__u8 bBootPage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	__u8 bPageNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	__be32 dwSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	__be32 dwAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	__be16 wReserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) #define E4_BLOCK_INFO_SIZE 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) #define UEA_BIHDR 0xabcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) #define UEA_RESERVED 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) /* constants describing cmv type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) #define E1_PREAMBLE 0x535c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) #define E1_MODEMTOHOST 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) #define E1_HOSTTOMODEM 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) #define E1_MEMACCESS 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) #define E1_ADSLDIRECTIVE 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) #define E1_FUNCTION_TYPE(f) ((f) >> 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) #define E1_FUNCTION_SUBTYPE(f) ((f) & 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) #define E4_MEMACCESS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) #define E4_ADSLDIRECTIVE 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) #define E4_FUNCTION_TYPE(f) ((f) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) #define E4_FUNCTION_SIZE(f) ((f) & 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) #define E4_FUNCTION_SUBTYPE(f) (((f) >> 4) & 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) /* for MEMACCESS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) #define E1_REQUESTREAD	0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) #define E1_REQUESTWRITE	0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) #define E1_REPLYREAD	0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) #define E1_REPLYWRITE	0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) #define E4_REQUESTREAD	0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) #define E4_REQUESTWRITE	0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) #define E4_REPLYREAD	(E4_REQUESTREAD | 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) #define E4_REPLYWRITE	(E4_REQUESTWRITE | 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) /* for ADSLDIRECTIVE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) #define E1_KERNELREADY 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) #define E1_MODEMREADY  0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) #define E4_KERNELREADY 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) #define E4_MODEMREADY  0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) #define E1_MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) #define E4_MAKEFUNCTION(t, st, s) (((t) & 0xf) << 8 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	((st) & 0xf) << 4 | ((s) & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) #define E1_MAKESA(a, b, c, d)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	(((c) & 0xff) << 24 |						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	 ((d) & 0xff) << 16 |						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	 ((a) & 0xff) << 8  |						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	 ((b) & 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) #define E1_GETSA1(a) ((a >> 8) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) #define E1_GETSA2(a) (a & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) #define E1_GETSA3(a) ((a >> 24) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) #define E1_GETSA4(a) ((a >> 16) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) #define E1_SA_CNTL E1_MAKESA('C', 'N', 'T', 'L')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) #define E1_SA_DIAG E1_MAKESA('D', 'I', 'A', 'G')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) #define E1_SA_INFO E1_MAKESA('I', 'N', 'F', 'O')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) #define E1_SA_OPTN E1_MAKESA('O', 'P', 'T', 'N')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) #define E1_SA_RATE E1_MAKESA('R', 'A', 'T', 'E')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) #define E1_SA_STAT E1_MAKESA('S', 'T', 'A', 'T')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) #define E4_SA_CNTL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) #define E4_SA_STAT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) #define E4_SA_INFO 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) #define E4_SA_TEST 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) #define E4_SA_OPTN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) #define E4_SA_RATE 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) #define E4_SA_DIAG 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) #define E4_SA_CNFG 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) /* structures representing a CMV (Configuration and Management Variable) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) struct cmv_e1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	__le16 wPreamble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	__u8 bDirection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	__u8 bFunction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	__le16 wIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	__le32 dwSymbolicAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	__le16 wOffsetAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	__le32 dwData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) struct cmv_e4 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	__be16 wGroup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	__be16 wFunction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	__be16 wOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	__be16 wAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	__be32 dwData[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) /* structures representing swap information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) struct swap_info_e1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	__u8 bSwapPageNo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	__u8 bOvl;		/* overlay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) struct swap_info_e4 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	__u8 bSwapPageNo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) /* structures representing interrupt data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) #define e1_bSwapPageNo	u.e1.s1.swapinfo.bSwapPageNo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) #define e1_bOvl		u.e1.s1.swapinfo.bOvl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) #define e4_bSwapPageNo  u.e4.s1.swapinfo.bSwapPageNo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) #define INT_LOADSWAPPAGE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) #define INT_INCOMINGCMV  0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) union intr_data_e1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		struct swap_info_e1 swapinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		__le16 wDataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	} __packed s1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		struct cmv_e1 cmv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		__le16 wDataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	} __packed s2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) union intr_data_e4 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		struct swap_info_e4 swapinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		__le16 wDataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	} __packed s1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		struct cmv_e4 cmv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		__le16 wDataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	} __packed s2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) struct intr_pkt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	__u8 bType;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	__u8 bNotification;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	__le16 wValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	__le16 wIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	__le16 wLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	__le16 wInterrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		union intr_data_e1 e1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		union intr_data_e4 e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	} u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) #define E1_INTR_PKT_SIZE 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) #define E4_INTR_PKT_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) static struct usb_driver uea_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static DEFINE_MUTEX(uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static const char * const chip_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	"ADI930", "Eagle I", "Eagle II", "Eagle III", "Eagle IV"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) static int modem_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) static unsigned int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) static unsigned int altsetting[NB_MODEM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 				[0 ... (NB_MODEM - 1)] = FASTEST_ISO_INTF};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) static bool sync_wait[NB_MODEM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) static char *cmv_file[NB_MODEM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) static int annex[NB_MODEM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) module_param(debug, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) module_param_array(altsetting, uint, NULL, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) MODULE_PARM_DESC(altsetting, "alternate setting for incoming traffic: 0=bulk, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			     "1=isoc slowest, ... , 8=isoc fastest (default)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) module_param_array(sync_wait, bool, NULL, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) module_param_array(cmv_file, charp, NULL, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) MODULE_PARM_DESC(cmv_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		"file name with configuration and management variables");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) module_param_array(annex, uint, NULL, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) MODULE_PARM_DESC(annex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		"manually set annex a/b (0=auto, 1=annex a, 2=annex b)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) #define uea_wait(sc, cond, timeo) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	int _r = wait_event_interruptible_timeout(sc->sync_q, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 			(cond) || kthread_should_stop(), timeo); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	if (kthread_should_stop()) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		_r = -ENODEV; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	_r; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) #define UPDATE_ATM_STAT(type, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		if (sc->usbatm->atm_dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			sc->usbatm->atm_dev->type = val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) #define UPDATE_ATM_SIGNAL(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		if (sc->usbatm->atm_dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 			atm_dev_signal_change(sc->usbatm->atm_dev, val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) /* Firmware loading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) #define LOAD_INTERNAL     0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) #define F8051_USBCS       0x7f92
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  * uea_send_modem_cmd - Send a command for pre-firmware devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) static int uea_send_modem_cmd(struct usb_device *usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 			      u16 addr, u16 size, const u8 *buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	u8 *xfer_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	xfer_buff = kmemdup(buff, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	if (xfer_buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		ret = usb_control_msg(usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 				      usb_sndctrlpipe(usb, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 				      LOAD_INTERNAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 				      USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 				      USB_RECIP_DEVICE, addr, 0, xfer_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 				      size, CTRL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		kfree(xfer_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	return (ret == size) ? 0 : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) static void uea_upload_pre_firmware(const struct firmware *fw_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 								void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	struct usb_device *usb = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	const u8 *pfw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	u32 crc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	int ret, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	uea_enters(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	if (!fw_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		uea_err(usb, "firmware is not available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	pfw = fw_entry->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	size = fw_entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	if (size < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	crc = get_unaligned_le32(pfw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	pfw += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	size -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	if (crc32_be(0, pfw, size) != crc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	 * Start to upload firmware : send reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	value = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		uea_err(usb, "modem reset failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	while (size > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		u8 len = FW_GET_BYTE(pfw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		u16 add = get_unaligned_le16(pfw + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		size -= len + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		if (size < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		ret = uea_send_modem_cmd(usb, add, len, pfw + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			uea_err(usb, "uploading firmware data failed "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 					"with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		pfw += len + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	if (size != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	 * Tell the modem we finish : de-assert reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		uea_err(usb, "modem de-assert failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		uea_info(usb, "firmware uploaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) err_fw_corrupted:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	uea_err(usb, "firmware is corrupted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	release_firmware(fw_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	uea_leaves(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  * uea_load_firmware - Load usb firmware for pre-firmware devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	char *fw_name = EAGLE_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	uea_enters(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	uea_info(usb, "pre-firmware device, uploading firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	switch (ver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	case ADI930:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		fw_name = ADI930_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	case EAGLE_I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		fw_name = EAGLE_I_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	case EAGLE_II:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		fw_name = EAGLE_II_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	case EAGLE_III:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		fw_name = EAGLE_III_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	case EAGLE_IV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		fw_name = EAGLE_IV_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 					GFP_KERNEL, usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 					uea_upload_pre_firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		uea_err(usb, "firmware %s is not available\n", fw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		uea_info(usb, "loading firmware %s\n", fw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	uea_leaves(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) /* modem management : dsp firmware, send/read CMV, monitoring statistic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720)  * Make sure that the DSP code provided is safe to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) static int check_dsp_e1(const u8 *dsp, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	u8 pagecount, blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	u16 blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	u32 pageoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	unsigned int i, j, p, pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	pagecount = FW_GET_BYTE(dsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	/* enough space for page offsets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	if (p + 4 * pagecount > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	for (i = 0; i < pagecount; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		pageoffset = get_unaligned_le32(dsp + p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		p += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		if (pageoffset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		/* enough space for blockcount? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		if (pageoffset >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		pp = pageoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		blockcount = FW_GET_BYTE(dsp + pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		pp += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		for (j = 0; j < blockcount; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			/* enough space for block header? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 			if (pp + 4 > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			pp += 2;	/* skip blockaddr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 			blocksize = get_unaligned_le16(dsp + pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			pp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			/* enough space for block data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			if (pp + blocksize > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 			pp += blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) static int check_dsp_e4(const u8 *dsp, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	struct l1_code *p = (struct l1_code *) dsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	unsigned int sum = p->code - dsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	if (len < sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	if (strcmp("STRATIPHY ANEXA", p->string_header) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	    strcmp("STRATIPHY ANEXB", p->string_header) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	for (i = 0; i < E4_MAX_PAGE_NUMBER; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		struct block_index *blockidx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		u8 blockno = p->page_number_to_block_index[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		if (blockno >= E4_NO_SWAPPAGE_HEADERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			u64 l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			if (blockno >= E4_NO_SWAPPAGE_HEADERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			blockidx = &p->page_header[blockno++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			if ((u8 *)(blockidx + 1) - dsp  >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			if (le16_to_cpu(blockidx->PageNumber) != i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			l = E4_PAGE_BYTES(blockidx->PageSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			sum += l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 			l += le32_to_cpu(blockidx->PageOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			if (l > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		/* zero is zero regardless endianes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		} while (blockidx->NotLastBlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	return (sum == len) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819)  * send data to the idma pipe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820)  * */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) static int uea_idma_write(struct uea_softc *sc, const void *data, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	u8 *xfer_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	int bytes_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	xfer_buff = kmemdup(data, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	if (!xfer_buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	ret = usb_bulk_msg(sc->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			 usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 			 xfer_buff, size, &bytes_read, BULK_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	kfree(xfer_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	if (size != bytes_read) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		       bytes_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static int request_dsp(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	char *dsp_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		if (IS_ISDN(sc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			dsp_name = DSP4I_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			dsp_name = DSP4P_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	} else if (UEA_CHIP_VERSION(sc) == ADI930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		if (IS_ISDN(sc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 			dsp_name = DSP9I_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			dsp_name = DSP9P_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		if (IS_ISDN(sc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			dsp_name = DSPEI_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			dsp_name = DSPEP_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		       "requesting firmware %s failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			dsp_name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	if (UEA_CHIP_VERSION(sc) == EAGLE_IV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		ret = check_dsp_e1(sc->dsp_firm->data, sc->dsp_firm->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		       dsp_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		release_firmware(sc->dsp_firm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		sc->dsp_firm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896)  * The uea_load_page() function must be called within a process context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) static void uea_load_page_e1(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	struct uea_softc *sc = container_of(work, struct uea_softc, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	u16 pageno = sc->pageno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	u16 ovl = sc->ovl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	struct block_info_e1 bi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	const u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	u8 pagecount, blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	u16 blockaddr, blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	u32 pageoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	/* reload firmware when reboot start and it's loaded already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	if (ovl == 0 && pageno == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		release_firmware(sc->dsp_firm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		sc->dsp_firm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	if (sc->dsp_firm == NULL && request_dsp(sc) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	p = sc->dsp_firm->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	pagecount = FW_GET_BYTE(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	p += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	if (pageno >= pagecount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		goto bad1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	p += 4 * pageno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	pageoffset = get_unaligned_le32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	if (pageoffset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		goto bad1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	p = sc->dsp_firm->data + pageoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	blockcount = FW_GET_BYTE(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	p += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	uea_dbg(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	       "sending %u blocks for DSP page %u\n", blockcount, pageno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	bi.wHdr = cpu_to_le16(UEA_BIHDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	bi.wOvl = cpu_to_le16(ovl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	bi.wOvlOffset = cpu_to_le16(ovl | 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	for (i = 0; i < blockcount; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		blockaddr = get_unaligned_le16(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		p += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		blocksize = get_unaligned_le16(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		p += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		bi.wSize = cpu_to_le16(blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		bi.wAddress = cpu_to_le16(blockaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		/* send block info through the IDMA pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		if (uea_idma_write(sc, &bi, E1_BLOCK_INFO_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			goto bad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		/* send block data through the IDMA pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		if (uea_idma_write(sc, p, blocksize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 			goto bad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		p += blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) bad2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) bad1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) static void __uea_load_page_e4(struct uea_softc *sc, u8 pageno, int boot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	struct block_info_e4 bi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	struct block_index *blockidx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	struct l1_code *p = (struct l1_code *) sc->dsp_firm->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	u8 blockno = p->page_number_to_block_index[pageno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	bi.wHdr = cpu_to_be16(UEA_BIHDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	bi.bBootPage = boot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	bi.bPageNumber = pageno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	bi.wReserved = cpu_to_be16(UEA_RESERVED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		const u8 *blockoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		unsigned int blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		blockidx = &p->page_header[blockno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		blocksize = E4_PAGE_BYTES(blockidx->PageSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		blockoffset = sc->dsp_firm->data + le32_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 							blockidx->PageOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		bi.dwSize = cpu_to_be32(blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		bi.dwAddress = cpu_to_be32(le32_to_cpu(blockidx->PageAddress));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		uea_dbg(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			"sending block %u for DSP page "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 			"%u size %u address %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 			blockno, pageno, blocksize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			le32_to_cpu(blockidx->PageAddress));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		/* send block info through the IDMA pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		/* send block data through the IDMA pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		if (uea_idma_write(sc, blockoffset, blocksize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 			goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		blockno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	} while (blockidx->NotLastBlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", blockno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static void uea_load_page_e4(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	struct uea_softc *sc = container_of(work, struct uea_softc, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	u8 pageno = sc->pageno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	struct block_info_e4 bi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	struct l1_code *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	uea_dbg(INS_TO_USBDEV(sc), "sending DSP page %u\n", pageno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	/* reload firmware when reboot start and it's loaded already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (pageno == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		release_firmware(sc->dsp_firm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		sc->dsp_firm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	if (sc->dsp_firm == NULL && request_dsp(sc) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	p = (struct l1_code *) sc->dsp_firm->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (pageno >= le16_to_cpu(p->page_header[0].PageNumber)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		uea_err(INS_TO_USBDEV(sc), "invalid DSP "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 						"page %u requested\n", pageno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	if (pageno != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		__uea_load_page_e4(sc, pageno, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	uea_dbg(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	       "sending Main DSP page %u\n", p->page_header[0].PageNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	for (i = 0; i < le16_to_cpu(p->page_header[0].PageNumber); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		if (E4_IS_BOOT_PAGE(p->page_header[i].PageSize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			__uea_load_page_e4(sc, i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	uea_dbg(INS_TO_USBDEV(sc) , "sending start bi\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	bi.wHdr = cpu_to_be16(UEA_BIHDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	bi.bBootPage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	bi.bPageNumber = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	bi.wReserved = cpu_to_be16(UEA_RESERVED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	bi.dwSize = cpu_to_be32(E4_PAGE_BYTES(p->page_header[0].PageSize));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	bi.dwAddress = cpu_to_be32(le32_to_cpu(p->page_header[0].PageAddress));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	/* send block info through the IDMA pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		uea_err(INS_TO_USBDEV(sc), "sending DSP start bi failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static inline void wake_up_cmv_ack(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	BUG_ON(sc->cmv_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	sc->cmv_ack = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	wake_up(&sc->sync_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static inline int wait_cmv_ack(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	int ret = uea_wait(sc, sc->cmv_ack , ACK_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	sc->cmv_ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			jiffies_to_msecs(ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	return (ret == 0) ? -ETIMEDOUT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static int uea_request(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		u16 value, u16 index, u16 size, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	u8 *xfer_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	xfer_buff = kmemdup(data, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	if (!xfer_buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			      UCDC_SEND_ENCAPSULATED_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 			      value, index, xfer_buff, size, CTRL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	kfree(xfer_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	if (ret != size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		       "usb_control_msg send only %d bytes (instead of %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		       ret, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static int uea_cmv_e1(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		u8 function, u32 address, u16 offset, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	struct cmv_e1 cmv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 			"offset : 0x%04x, data : 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 			E1_FUNCTION_TYPE(function),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 			E1_FUNCTION_SUBTYPE(function),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 			E1_GETSA1(address), E1_GETSA2(address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 			E1_GETSA3(address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			E1_GETSA4(address), offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	/* we send a request, but we expect a reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	sc->cmv_dsc.e1.function = function | 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	sc->cmv_dsc.e1.idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	sc->cmv_dsc.e1.address = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	sc->cmv_dsc.e1.offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	cmv.wPreamble = cpu_to_le16(E1_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	cmv.bDirection = E1_HOSTTOMODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	cmv.bFunction = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	cmv.wIndex = cpu_to_le16(sc->cmv_dsc.e1.idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	put_unaligned_le32(address, &cmv.dwSymbolicAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	cmv.wOffsetAddress = cpu_to_le16(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	put_unaligned_le32(data >> 16 | data << 16, &cmv.dwData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	ret = uea_request(sc, UEA_E1_SET_BLOCK, UEA_MPTX_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 							sizeof(cmv), &cmv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	ret = wait_cmv_ack(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) static int uea_cmv_e4(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		u16 function, u16 group, u16 address, u16 offset, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	struct cmv_e4 cmv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	memset(&cmv, 0, sizeof(cmv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Group : 0x%04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		 "Address : 0x%04x, offset : 0x%04x, data : 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		 E4_FUNCTION_TYPE(function), E4_FUNCTION_SUBTYPE(function),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		 group, address, offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	/* we send a request, but we expect a reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	sc->cmv_dsc.e4.function = function | (0x1 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	sc->cmv_dsc.e4.offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	sc->cmv_dsc.e4.address = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	sc->cmv_dsc.e4.group = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	cmv.wFunction = cpu_to_be16(function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	cmv.wGroup = cpu_to_be16(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	cmv.wAddress = cpu_to_be16(address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	cmv.wOffset = cpu_to_be16(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	cmv.dwData[0] = cpu_to_be32(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	ret = uea_request(sc, UEA_E4_SET_BLOCK, UEA_MPTX_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 							sizeof(cmv), &cmv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	ret = wait_cmv_ack(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static inline int uea_read_cmv_e1(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		u32 address, u16 offset, u32 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTREAD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 			  address, offset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 			"reading cmv failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		*data = sc->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) static inline int uea_read_cmv_e4(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		u8 size, u16 group, u16 address, u16 offset, u32 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 							E4_REQUESTREAD, size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			  group, address, offset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			"reading cmv failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		*data = sc->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		/* size is in 16-bit word quantities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		if (size > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 			*(data + 1) = sc->data1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static inline int uea_write_cmv_e1(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		u32 address, u16 offset, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTWRITE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 			  address, offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 			"writing cmv failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static inline int uea_write_cmv_e4(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		u8 size, u16 group, u16 address, u16 offset, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 							E4_REQUESTWRITE, size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 			  group, address, offset, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			"writing cmv failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	u16 timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	/* in bulk mode the modem have problem with high rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	 * changing internal timing could improve things, but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	 * value is mysterious.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	 * ADI930 don't support it (-EPIPE error).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	if (UEA_CHIP_VERSION(sc) == ADI930 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	    altsetting[sc->modem_index] > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	    sc->stats.phy.dsrate == dsrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	/* Original timming (1Mbit/s) from ADI (used in windows driver) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	timeout = (dsrate <= 1024*1024) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	uea_info(INS_TO_USBDEV(sc), "setting new timeout %d%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		 timeout,  ret < 0 ? " failed" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)  * Monitor the modem and update the stat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)  * return 0 if everything is ok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)  * return < 0 if an error occurs (-EAGAIN reboot needed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static int uea_stat_e1(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	data = sc->stats.phy.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	ret = uea_read_cmv_e1(sc, E1_SA_STAT, 0, &sc->stats.phy.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	switch (GET_STATUS(sc->stats.phy.state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	case 0:		/* not yet synchronized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		uea_dbg(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 		       "modem not yet synchronized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	case 1:		/* initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	case 2:		/* operational */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	case 3:		/* fail ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		uea_info(INS_TO_USBDEV(sc), "modem synchronization failed"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 					" (may be try other cmv/dsp)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	case 4 ... 6:	/* test state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		uea_warn(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 				"modem in test mode - not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	case 7:		/* fast-retain ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 			GET_STATUS(sc->stats.phy.state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	if (GET_STATUS(data) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		uea_info(INS_TO_USBDEV(sc), "modem operational\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		/* release the dsp firmware as it is not needed until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		 * the next failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		release_firmware(sc->dsp_firm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		sc->dsp_firm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	/* always update it as atm layer could not be init when we switch to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	 * operational state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	UPDATE_ATM_SIGNAL(ATM_PHY_SIG_FOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	/* wake up processes waiting for synchronization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	wake_up(&sc->sync_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 2, &sc->stats.phy.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	sc->stats.phy.mflags |= sc->stats.phy.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	/* in case of a flags ( for example delineation LOSS (& 0x10)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	 * we check the status again in order to detect the failure earlier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	if (sc->stats.phy.flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		       sc->stats.phy.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	ret = uea_read_cmv_e1(sc, E1_SA_RATE, 0, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	uea_set_bulk_timeout(sc, (data >> 16) * 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	sc->stats.phy.dsrate = (data >> 16) * 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	sc->stats.phy.usrate = (data & 0xffff) * 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 23, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	sc->stats.phy.dsattenuation = (data & 0xff) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 47, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	sc->stats.phy.usattenuation = (data & 0xff) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 25, &sc->stats.phy.dsmargin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 49, &sc->stats.phy.usmargin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 51, &sc->stats.phy.rxflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 52, &sc->stats.phy.txflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 54, &sc->stats.phy.dsunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	/* only for atu-c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 58, &sc->stats.phy.usunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 53, &sc->stats.phy.dscorr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	/* only for atu-c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 57, &sc->stats.phy.uscorr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	ret = uea_read_cmv_e1(sc, E1_SA_INFO, 8, &sc->stats.phy.vidco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	ret = uea_read_cmv_e1(sc, E1_SA_INFO, 13, &sc->stats.phy.vidcpe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) static int uea_stat_e4(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	u32 tmp_arr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	data = sc->stats.phy.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	/* XXX only need to be done before operationnal... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	ret = uea_read_cmv_e4(sc, 1, E4_SA_STAT, 0, 0, &sc->stats.phy.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	switch (sc->stats.phy.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	case 0x0:	/* not yet synchronized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	case 0x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	case 0x3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	case 0x4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		uea_dbg(INS_TO_USBDEV(sc), "modem not yet "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 						"synchronized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	case 0x5:	/* initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	case 0x6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	case 0x9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	case 0xa:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	case 0x2:	/* fail ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		uea_info(INS_TO_USBDEV(sc), "modem synchronization "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 				"failed (may be try other cmv/dsp)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	case 0x7:	/* operational */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		uea_warn(INS_TO_USBDEV(sc), "unknown state: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 						sc->stats.phy.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	if (data != 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		uea_info(INS_TO_USBDEV(sc), "modem operational\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		/* release the dsp firmware as it is not needed until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		 * the next failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		release_firmware(sc->dsp_firm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		sc->dsp_firm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	/* always update it as atm layer could not be init when we switch to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	 * operational state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	UPDATE_ATM_SIGNAL(ATM_PHY_SIG_FOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	/* wake up processes waiting for synchronization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	wake_up(&sc->sync_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	/* TODO improve this state machine :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	 * we need some CMV info : what they do and their unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	 * we should find the equivalent of eagle3- CMV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	/* check flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	ret = uea_read_cmv_e4(sc, 1, E4_SA_DIAG, 0, 0, &sc->stats.phy.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	sc->stats.phy.mflags |= sc->stats.phy.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	/* in case of a flags ( for example delineation LOSS (& 0x10)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	 * we check the status again in order to detect the failure earlier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	if (sc->stats.phy.flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		       sc->stats.phy.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		if (sc->stats.phy.flags & 1) /* delineation LOSS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		if (sc->stats.phy.flags & 0x4000) /* Reset Flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	/* rate data may be in upper or lower half of 64 bit word, strange */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 0, 0, tmp_arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	sc->stats.phy.usrate = data / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 1, 0, tmp_arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	uea_set_bulk_timeout(sc, data / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	sc->stats.phy.dsrate = data / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 1, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	sc->stats.phy.dsattenuation = data / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 1, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	sc->stats.phy.usattenuation = data / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 3, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	sc->stats.phy.dsmargin = data / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 3, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	sc->stats.phy.usmargin = data / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	char file_arr[] = "CMVxy.bin";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	char *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	kernel_param_lock(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	/* set proper name corresponding modem version and line type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	if (cmv_file[sc->modem_index] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		if (UEA_CHIP_VERSION(sc) == ADI930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 			file_arr[3] = '9';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		else if (UEA_CHIP_VERSION(sc) == EAGLE_IV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 			file_arr[3] = '4';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 			file_arr[3] = 'e';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		file_arr[4] = IS_ISDN(sc) ? 'i' : 'p';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		file = file_arr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		file = cmv_file[sc->modem_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	strcpy(cmv_name, FW_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	strlcat(cmv_name, file, UEA_FW_NAME_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	if (ver == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	kernel_param_unlock(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) static int request_cmvs_old(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		 void **cmvs, const struct firmware **fw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	int ret, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	char cmv_name[UEA_FW_NAME_MAX]; /* 30 bytes stack variable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	cmvs_file_name(sc, cmv_name, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		       "requesting firmware %s failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		       cmv_name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	data = (u8 *) (*fw)->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	size = (*fw)->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	if (size < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	if (size != *data * sizeof(struct uea_cmvs_v1) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	*cmvs = (void *)(data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	return *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) err_fw_corrupted:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	release_firmware(*fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static int request_cmvs(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 		 void **cmvs, const struct firmware **fw, int *ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	int ret, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	char cmv_name[UEA_FW_NAME_MAX]; /* 30 bytes stack variable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	cmvs_file_name(sc, cmv_name, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		/* if caller can handle old version, try to provide it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		if (*ver == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 			uea_warn(INS_TO_USBDEV(sc), "requesting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 							"firmware %s failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 				"try to get older cmvs\n", cmv_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 			return request_cmvs_old(sc, cmvs, fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 		       "requesting firmware %s failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		       cmv_name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	size = (*fw)->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	data = (u8 *) (*fw)->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	if (size < 4 || strncmp(data, "cmv2", 4) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		if (*ver == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			uea_warn(INS_TO_USBDEV(sc), "firmware %s is corrupted,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 				" try to get older cmvs\n", cmv_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 			release_firmware(*fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 			return request_cmvs_old(sc, cmvs, fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	*ver = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	data += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	size -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	if (size < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	crc = get_unaligned_le32(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	data += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	size -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	if (crc32_be(0, data, size) != crc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	if (size != *data * sizeof(struct uea_cmvs_v2) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		goto err_fw_corrupted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	*cmvs = (void *) (data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	return *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) err_fw_corrupted:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	release_firmware(*fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) static int uea_send_cmvs_e1(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	int i, ret, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	void *cmvs_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	const struct firmware *cmvs_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	int ver = 1; /* we can handle v1 cmv firmware version; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	/* Enter in R-IDLE (cmv) until instructed otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	/* Dump firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	ret = uea_read_cmv_e1(sc, E1_SA_INFO, 10, &sc->stats.phy.firmid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 			sc->stats.phy.firmid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	/* get options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	/* send options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	if (ver == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 		struct uea_cmvs_v1 *cmvs_v1 = cmvs_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		uea_warn(INS_TO_USBDEV(sc), "use deprecated cmvs version, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 			"please update your firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 			ret = uea_write_cmv_e1(sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 				get_unaligned_le32(&cmvs_v1[i].address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 				get_unaligned_le16(&cmvs_v1[i].offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 				get_unaligned_le32(&cmvs_v1[i].data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	} else if (ver == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			ret = uea_write_cmv_e1(sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 				get_unaligned_le32(&cmvs_v2[i].address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 				(u16) get_unaligned_le32(&cmvs_v2[i].offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 				get_unaligned_le32(&cmvs_v2[i].data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		/* This really should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 		uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	/* Enter in R-ACT-REQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	uea_info(INS_TO_USBDEV(sc), "modem started, waiting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 						"synchronization...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	release_firmware(cmvs_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) static int uea_send_cmvs_e4(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	int i, ret, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	void *cmvs_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	const struct firmware *cmvs_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	int ver = 2; /* we can only handle v2 cmv firmware version; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	/* Enter in R-IDLE (cmv) until instructed otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	/* Dump firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	/* XXX don't read the 3th byte as it is always 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	ret = uea_read_cmv_e4(sc, 2, E4_SA_INFO, 55, 0, &sc->stats.phy.firmid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 			sc->stats.phy.firmid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	/* get options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	/* send options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	if (ver == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 		struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 			ret = uea_write_cmv_e4(sc, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 				get_unaligned_le32(&cmvs_v2[i].group),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 				get_unaligned_le32(&cmvs_v2[i].address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 				get_unaligned_le32(&cmvs_v2[i].offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 				get_unaligned_le32(&cmvs_v2[i].data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 		/* This really should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 		uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	/* Enter in R-ACT-REQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	uea_info(INS_TO_USBDEV(sc), "modem started, waiting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 						"synchronization...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	release_firmware(cmvs_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /* Start boot post firmware modem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)  * - send reset commands through usb control pipe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)  * - start workqueue for DSP loading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)  * - send CMV options to modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) static int uea_start_reset(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	u16 zero = 0;	/* ;-) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	uea_info(INS_TO_USBDEV(sc), "(re)booting started\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	/* mask interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	sc->booting = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	/* We need to set this here because, a ack timeout could have occurred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	 * but before we start the reboot, the ack occurs and set this to 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	 * So we will failed to wait Ready CMV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	sc->cmv_ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	/* reset statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	memset(&sc->stats, 0, sizeof(struct uea_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	/* tell the modem that we want to boot in IDMA mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	/* enter reset mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	/* original driver use 200ms, but windows driver use 100ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	ret = uea_wait(sc, 0, msecs_to_jiffies(100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	/* leave reset mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	if (UEA_CHIP_VERSION(sc) != EAGLE_IV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 		/* clear tx and rx mailboxes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 		uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 		uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	ret = uea_wait(sc, 0, msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	if (UEA_CHIP_VERSION(sc) == EAGLE_IV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		sc->cmv_dsc.e4.function = E4_MAKEFUNCTION(E4_ADSLDIRECTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 							E4_MODEMREADY, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 		sc->cmv_dsc.e1.function = E1_MAKEFUNCTION(E1_ADSLDIRECTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 							E1_MODEMREADY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	/* demask interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	sc->booting = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	/* start loading DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	sc->pageno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	sc->ovl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	schedule_work(&sc->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	/* wait for modem ready CMV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	ret = wait_cmv_ack(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	ret = sc->send_cmvs(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	sc->reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)  * In case of an error wait 1s before rebooting the modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)  * if the modem don't request reboot (-EAGAIN).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)  * Monitor the modem every 1s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) static int uea_kthread(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	struct uea_softc *sc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	int ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	set_freezable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	while (!kthread_should_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 		if (ret < 0 || sc->reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 			ret = uea_start_reset(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 			ret = sc->stat(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 		if (ret != -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 			uea_wait(sc, 0, msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 		try_to_freeze();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) /* Load second usb firmware for ADI930 chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) static int load_XILINX_firmware(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	const struct firmware *fw_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	int ret, size, u, ln;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	const u8 *pfw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	char *fw_name = FPGA930_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 		       fw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 		goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	pfw = fw_entry->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	size = fw_entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	if (size != 0x577B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 		       fw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		ret = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	for (u = 0; u < size; u += ln) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		ln = min(size - u, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 		ret = uea_request(sc, 0xe, 0, ln, pfw + u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 			uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 			       "elsa download data failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 			goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	/* finish to send the fpga */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	ret = uea_request(sc, 0xe, 1, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 				"elsa download data failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 		goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	/* Tell the modem we finish : de-assert reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 		uea_err(sc->usb_dev, "elsa de-assert failed with error"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 								" %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	release_firmware(fw_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) err0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) /* The modem send us an ack. First with check if it right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	struct cmv_dsc_e1 *dsc = &sc->cmv_dsc.e1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	struct cmv_e1 *cmv = &intr->u.e1.s2.cmv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	if (le16_to_cpu(cmv->wPreamble) != E1_PREAMBLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 		goto bad1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	if (cmv->bDirection != E1_MODEMTOHOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 		goto bad1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	/* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	 * the first MEMACCESS cmv. Ignore it...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	if (cmv->bFunction != dsc->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 		if (UEA_CHIP_VERSION(sc) == ADI930
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 				&& cmv->bFunction ==  E1_MAKEFUNCTION(2, 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 			cmv->wIndex = cpu_to_le16(dsc->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 			put_unaligned_le32(dsc->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 						&cmv->dwSymbolicAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 			cmv->wOffsetAddress = cpu_to_le16(dsc->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 			goto bad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	if (cmv->bFunction == E1_MAKEFUNCTION(E1_ADSLDIRECTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 							E1_MODEMREADY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 		wake_up_cmv_ack(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	/* in case of MEMACCESS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	if (le16_to_cpu(cmv->wIndex) != dsc->idx ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	    get_unaligned_le32(&cmv->dwSymbolicAddress) != dsc->address ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	    le16_to_cpu(cmv->wOffsetAddress) != dsc->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 		goto bad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	sc->data = get_unaligned_le32(&cmv->dwData);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	sc->data = sc->data << 16 | sc->data >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	wake_up_cmv_ack(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) bad2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	uea_err(INS_TO_USBDEV(sc), "unexpected cmv received, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 			"Function : %d, Subfunction : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 			E1_FUNCTION_TYPE(cmv->bFunction),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 			E1_FUNCTION_SUBTYPE(cmv->bFunction));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) bad1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	uea_err(INS_TO_USBDEV(sc), "invalid cmv received, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 			"wPreamble %d, bDirection %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 			le16_to_cpu(cmv->wPreamble), cmv->bDirection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) /* The modem send us an ack. First with check if it right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	struct cmv_dsc_e4 *dsc = &sc->cmv_dsc.e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	struct cmv_e4 *cmv = &intr->u.e4.s2.cmv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	uea_dbg(INS_TO_USBDEV(sc), "cmv %x %x %x %x %x %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		be16_to_cpu(cmv->wGroup), be16_to_cpu(cmv->wFunction),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 		be16_to_cpu(cmv->wOffset), be16_to_cpu(cmv->wAddress),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 		be32_to_cpu(cmv->dwData[0]), be32_to_cpu(cmv->dwData[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	if (be16_to_cpu(cmv->wFunction) != dsc->function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 		goto bad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	if (be16_to_cpu(cmv->wFunction) == E4_MAKEFUNCTION(E4_ADSLDIRECTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 						E4_MODEMREADY, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 		wake_up_cmv_ack(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	/* in case of MEMACCESS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	if (be16_to_cpu(cmv->wOffset) != dsc->offset ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	    be16_to_cpu(cmv->wGroup) != dsc->group ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	    be16_to_cpu(cmv->wAddress) != dsc->address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 		goto bad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	sc->data = be32_to_cpu(cmv->dwData[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	sc->data1 = be32_to_cpu(cmv->dwData[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	wake_up_cmv_ack(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) bad2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	uea_err(INS_TO_USBDEV(sc), "unexpected cmv received, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 			"Function : %d, Subfunction : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 			E4_FUNCTION_TYPE(cmv->wFunction),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 			E4_FUNCTION_SUBTYPE(cmv->wFunction));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) static void uea_schedule_load_page_e1(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 						struct intr_pkt *intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	sc->pageno = intr->e1_bSwapPageNo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	sc->ovl = intr->e1_bOvl >> 4 | intr->e1_bOvl << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	schedule_work(&sc->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) static void uea_schedule_load_page_e4(struct uea_softc *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 						struct intr_pkt *intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	sc->pageno = intr->e4_bSwapPageNo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	schedule_work(&sc->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)  * interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) static void uea_intr(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	struct uea_softc *sc = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	struct intr_pkt *intr = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	if (unlikely(status < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 		       status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	/* device-to-host interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	if (intr->bType != 0x08 || sc->booting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 		uea_err(INS_TO_USBDEV(sc), "wrong interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	switch (le16_to_cpu(intr->wInterrupt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	case INT_LOADSWAPPAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 		sc->schedule_load_page(sc, intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	case INT_INCOMINGCMV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 		sc->dispatch_cmv(sc, intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 		uea_err(INS_TO_USBDEV(sc), "unknown interrupt %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 		       le16_to_cpu(intr->wInterrupt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) resubmit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	usb_submit_urb(sc->urb_int, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)  * Start the modem : init the data and start kernel thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) static int uea_boot(struct uea_softc *sc, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	struct intr_pkt *intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		size = E4_INTR_PKT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 		sc->dispatch_cmv = uea_dispatch_cmv_e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		sc->schedule_load_page = uea_schedule_load_page_e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		sc->stat = uea_stat_e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 		sc->send_cmvs = uea_send_cmvs_e4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		INIT_WORK(&sc->task, uea_load_page_e4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		size = E1_INTR_PKT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		sc->dispatch_cmv = uea_dispatch_cmv_e1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 		sc->schedule_load_page = uea_schedule_load_page_e1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		sc->stat = uea_stat_e1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		sc->send_cmvs = uea_send_cmvs_e1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 		INIT_WORK(&sc->task, uea_load_page_e1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	init_waitqueue_head(&sc->sync_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	if (UEA_CHIP_VERSION(sc) == ADI930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		load_XILINX_firmware(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 		goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	intr = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	if (!intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	sc->urb_int = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	if (!sc->urb_int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 		goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	usb_fill_int_urb(sc->urb_int, sc->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 			 usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 			 intr, size, uea_intr, sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 			 intf->cur_altsetting->endpoint[0].desc.bInterval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 		uea_err(INS_TO_USBDEV(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 		       "urb submission failed with error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 		goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 	/* Create worker thread, but don't start it here.  Start it after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	 * all usbatm generic initialization is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 	if (IS_ERR(sc->kthread)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 		ret = PTR_ERR(sc->kthread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 		goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	usb_kill_urb(sc->urb_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	usb_free_urb(sc->urb_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	sc->urb_int = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	kfree(intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) err0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)  * Stop the modem : kill kernel thread and free data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) static void uea_stop(struct uea_softc *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	uea_enters(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	ret = kthread_stop(sc->kthread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	usb_kill_urb(sc->urb_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	kfree(sc->urb_int->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	usb_free_urb(sc->urb_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	/* flush the work item, when no one can schedule it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	flush_work(&sc->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	release_firmware(sc->dsp_firm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	uea_leaves(INS_TO_USBDEV(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) /* syfs interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) static struct uea_softc *dev_to_uea(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	struct usb_interface *intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	struct usbatm_data *usbatm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	intf = to_usb_interface(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	if (!intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	usbatm = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	if (!usbatm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	return usbatm->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) static ssize_t stat_status_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	struct uea_softc *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	mutex_lock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	sc = dev_to_uea(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	mutex_unlock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) static ssize_t stat_status_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	struct uea_softc *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	mutex_lock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	sc = dev_to_uea(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	sc->reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	mutex_unlock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) static DEVICE_ATTR_RW(stat_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static ssize_t stat_human_status_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 			struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	int modem_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	struct uea_softc *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	mutex_lock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	sc = dev_to_uea(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 		switch (sc->stats.phy.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 		case 0x0:	/* not yet synchronized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		case 0x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 		case 0x3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 		case 0x4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 			modem_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		case 0x5:	/* initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 		case 0x6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 		case 0x9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		case 0xa:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 			modem_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		case 0x7:	/* operational */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 			modem_state = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 		case 0x2:	/* fail ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 			modem_state = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		default:	/* unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 			modem_state = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		modem_state = GET_STATUS(sc->stats.phy.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	switch (modem_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		ret = sprintf(buf, "Modem is booting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 		ret = sprintf(buf, "Modem is initializing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 		ret = sprintf(buf, "Modem is operational\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 		ret = sprintf(buf, "Modem synchronization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 		ret = sprintf(buf, "Modem state is unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	mutex_unlock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) static DEVICE_ATTR_RO(stat_human_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) static ssize_t stat_delin_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	struct uea_softc *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	char *delin = "GOOD";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	mutex_lock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	sc = dev_to_uea(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 		if (sc->stats.phy.flags & 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 			delin = "RESET";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 		else if (sc->stats.phy.flags & 0x0001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 			delin = "LOSS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 		if (sc->stats.phy.flags & 0x0C00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 			delin = "ERROR";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 		else if (sc->stats.phy.flags & 0x0030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 			delin = "LOSS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	ret = sprintf(buf, "%s\n", delin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	mutex_unlock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) static DEVICE_ATTR_RO(stat_delin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) #define UEA_ATTR(name, reset)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) static ssize_t stat_##name##_show(struct device *dev,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 		struct device_attribute *attr, char *buf)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	int ret = -ENODEV;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	struct uea_softc *sc;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	mutex_lock(&uea_mutex);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	sc = dev_to_uea(dev);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	if (!sc)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		goto out;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 	if (reset)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 		sc->stats.phy.name = 0;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) out:								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	mutex_unlock(&uea_mutex);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	return ret;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) }								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) static DEVICE_ATTR_RO(stat_##name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) UEA_ATTR(mflags, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) UEA_ATTR(vidcpe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) UEA_ATTR(usrate, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) UEA_ATTR(dsrate, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) UEA_ATTR(usattenuation, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) UEA_ATTR(dsattenuation, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) UEA_ATTR(usmargin, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) UEA_ATTR(dsmargin, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) UEA_ATTR(txflow, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) UEA_ATTR(rxflow, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) UEA_ATTR(uscorr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) UEA_ATTR(dscorr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) UEA_ATTR(usunc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) UEA_ATTR(dsunc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) UEA_ATTR(firmid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) /* Retrieve the device End System Identifier (MAC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) static int uea_getesi(struct uea_softc *sc, u_char *esi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	unsigned char mac_str[2 * ETH_ALEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	if (usb_string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	    (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	     sizeof(mac_str)) != 2 * ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	for (i = 0; i < ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		esi[i] = hex_to_bin(mac_str[2 * i]) * 16 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 			 hex_to_bin(mac_str[2 * i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) /* ATM stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	struct uea_softc *sc = usbatm->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	return uea_getesi(sc, atm_dev->esi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	struct uea_softc *sc = usbatm->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	wait_event_interruptible(sc->sync_q, IS_OPERATIONAL(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) static int claim_interface(struct usb_device *usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 			   struct usbatm_data *usbatm, int ifnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	if (!intf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 		uea_err(usb_dev, "interface %d not found\n", ifnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	ret = usb_driver_claim_interface(&uea_driver, intf, usbatm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 		uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 		       ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) static struct attribute *uea_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	&dev_attr_stat_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	&dev_attr_stat_mflags.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	&dev_attr_stat_human_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	&dev_attr_stat_delin.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	&dev_attr_stat_vidcpe.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	&dev_attr_stat_usrate.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	&dev_attr_stat_dsrate.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	&dev_attr_stat_usattenuation.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	&dev_attr_stat_dsattenuation.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	&dev_attr_stat_usmargin.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 	&dev_attr_stat_dsmargin.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	&dev_attr_stat_txflow.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 	&dev_attr_stat_rxflow.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	&dev_attr_stat_uscorr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	&dev_attr_stat_dscorr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	&dev_attr_stat_usunc.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	&dev_attr_stat_dsunc.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	&dev_attr_stat_firmid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) ATTRIBUTE_GROUPS(uea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 		   const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	struct usb_device *usb = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	struct uea_softc *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	int ret, ifnum = intf->altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	unsigned int alt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	uea_enters(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	/* interface 0 is for firmware/monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	if (ifnum != UEA_INTR_IFACE_NO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	usbatm->flags = (sync_wait[modem_index] ? 0 : UDSL_SKIP_HEAVY_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	/* interface 1 is for outbound traffic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	/* ADI930 has only 2 interfaces and inbound traffic is on interface 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	if (UEA_CHIP_VERSION(id) != ADI930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 		/* interface 2 is for inbound traffic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	sc->usb_dev = usb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	usbatm->driver_data = sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	sc->usbatm = usbatm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	sc->driver_info = id->driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	/* first try to use module parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	if (annex[sc->modem_index] == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		sc->annex = ANNEXA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	else if (annex[sc->modem_index] == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		sc->annex = ANNEXB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	/* try to autodetect annex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	else if (sc->driver_info & AUTO_ANNEX_A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 		sc->annex = ANNEXA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	else if (sc->driver_info & AUTO_ANNEX_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 		sc->annex = ANNEXB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 		sc->annex = (le16_to_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 		(sc->usb_dev->descriptor.bcdDevice) & 0x80) ? ANNEXB : ANNEXA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	alt = altsetting[sc->modem_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	/* ADI930 don't support iso */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	if (UEA_CHIP_VERSION(id) != ADI930 && alt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 		if (alt <= 8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 			usb_set_interface(usb, UEA_DS_IFACE_NO, alt) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 			uea_dbg(usb, "set alternate %u for 2 interface\n", alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 			uea_info(usb, "using iso mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 			usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 			uea_err(usb, "setting alternate %u failed for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 					"2 interface, using bulk mode\n", alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	ret = uea_boot(sc, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	kfree(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	struct uea_softc *sc = usbatm->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	uea_stop(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	kfree(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) static struct usbatm_driver uea_usbatm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	.driver_name = "ueagle-atm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 	.bind = uea_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	.atm_start = uea_atm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	.unbind = uea_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	.heavy_init = uea_heavy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	.bulk_in = UEA_BULK_DATA_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	.bulk_out = UEA_BULK_DATA_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	.isoc_in = UEA_ISO_DATA_PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	struct usb_device *usb = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	uea_enters(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 		le16_to_cpu(usb->descriptor.idVendor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 		le16_to_cpu(usb->descriptor.idProduct),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		le16_to_cpu(usb->descriptor.bcdDevice),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 		chip_name[UEA_CHIP_VERSION(id)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	usb_reset_device(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	if (UEA_IS_PREFIRM(id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 		struct usbatm_data *usbatm = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 		struct uea_softc *sc = usbatm->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		/* Ensure carrier is initialized to off as early as possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 		UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 		/* Only start the worker thread when all init is done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		wake_up_process(sc->kthread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) static void uea_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	struct usb_device *usb = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	int ifnum = intf->altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	uea_enters(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	/* ADI930 has 2 interfaces and eagle 3 interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	 * Pre-firmware device has one interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 		mutex_lock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 		usbatm_usb_disconnect(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 		mutex_unlock(&uea_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 		uea_info(usb, "ADSL device removed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	uea_leaves(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639)  * List of supported VID/PID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) static const struct usb_device_id uea_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	{USB_DEVICE(ANALOG_VID,	ADI930_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 		.driver_info = ADI930 | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	{USB_DEVICE(ANALOG_VID,	ADI930_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		.driver_info = ADI930 | PSTFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	{USB_DEVICE(ANALOG_VID,	EAGLE_I_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 		.driver_info = EAGLE_I | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	{USB_DEVICE(ANALOG_VID,	EAGLE_I_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 		.driver_info = EAGLE_I | PSTFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	{USB_DEVICE(ANALOG_VID,	EAGLE_II_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 		.driver_info = EAGLE_II | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	{USB_DEVICE(ANALOG_VID,	EAGLE_II_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		.driver_info = EAGLE_II | PSTFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	{USB_DEVICE(ANALOG_VID,	EAGLE_IIC_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 		.driver_info = EAGLE_II | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	{USB_DEVICE(ANALOG_VID,	EAGLE_IIC_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 		.driver_info = EAGLE_II | PSTFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	{USB_DEVICE(ANALOG_VID,	EAGLE_III_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		.driver_info = EAGLE_III | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	{USB_DEVICE(ANALOG_VID,	EAGLE_III_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 		.driver_info = EAGLE_III | PSTFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 	{USB_DEVICE(ANALOG_VID,	EAGLE_IV_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 		.driver_info = EAGLE_IV | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	{USB_DEVICE(ANALOG_VID,	EAGLE_IV_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 		.driver_info = EAGLE_IV | PSTFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_I_A_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 		.driver_info = EAGLE_I | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_I_A_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_I_B_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		.driver_info = EAGLE_I | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_I_B_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 		.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_II_A_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		.driver_info = EAGLE_II | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_II_A_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		.driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_II_B_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 		.driver_info = EAGLE_II | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	{USB_DEVICE(DEVOLO_VID,	DEVOLO_EAGLE_II_B_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 		.driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	{USB_DEVICE(ELSA_VID,	ELSA_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		.driver_info = ADI930 | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	{USB_DEVICE(ELSA_VID,	ELSA_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 		.driver_info = ADI930 | PSTFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	{USB_DEVICE(ELSA_VID,	ELSA_PID_A_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 		.driver_info = ADI930 | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	{USB_DEVICE(ELSA_VID,	ELSA_PID_A_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 		.driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	{USB_DEVICE(ELSA_VID,	ELSA_PID_B_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 		.driver_info = ADI930 | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	{USB_DEVICE(ELSA_VID,	ELSA_PID_B_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		.driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 	{USB_DEVICE(USR_VID,	MILLER_A_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 		.driver_info = EAGLE_I | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 	{USB_DEVICE(USR_VID,	MILLER_A_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 		.driver_info = EAGLE_I | PSTFIRM  | AUTO_ANNEX_A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 	{USB_DEVICE(USR_VID,	MILLER_B_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 		.driver_info = EAGLE_I | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	{USB_DEVICE(USR_VID,	MILLER_B_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 		.driver_info = EAGLE_I | PSTFIRM  | AUTO_ANNEX_B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	{USB_DEVICE(USR_VID,	HEINEKEN_A_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 		.driver_info = EAGLE_I | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	{USB_DEVICE(USR_VID,	HEINEKEN_A_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 		.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	{USB_DEVICE(USR_VID,	HEINEKEN_B_PID_PREFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		.driver_info = EAGLE_I | PREFIRM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	{USB_DEVICE(USR_VID,	HEINEKEN_B_PID_PSTFIRM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)  * USB driver descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) static struct usb_driver uea_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 	.name = "ueagle-atm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	.id_table = uea_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	.probe = uea_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	.disconnect = uea_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	.dev_groups = uea_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) MODULE_DEVICE_TABLE(usb, uea_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) module_usb_driver(uea_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) MODULE_LICENSE("Dual BSD/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) MODULE_FIRMWARE(EAGLE_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) MODULE_FIRMWARE(ADI930_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) MODULE_FIRMWARE(EAGLE_I_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) MODULE_FIRMWARE(EAGLE_II_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) MODULE_FIRMWARE(EAGLE_III_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) MODULE_FIRMWARE(EAGLE_IV_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) MODULE_FIRMWARE(DSP4I_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) MODULE_FIRMWARE(DSP4P_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) MODULE_FIRMWARE(DSP9I_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) MODULE_FIRMWARE(DSP9P_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) MODULE_FIRMWARE(DSPEI_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) MODULE_FIRMWARE(DSPEP_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) MODULE_FIRMWARE(FPGA930_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) MODULE_FIRMWARE(CMV4P_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) MODULE_FIRMWARE(CMV4PV2_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) MODULE_FIRMWARE(CMV4I_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) MODULE_FIRMWARE(CMV4IV2_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) MODULE_FIRMWARE(CMV9P_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) MODULE_FIRMWARE(CMV9PV2_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) MODULE_FIRMWARE(CMV9I_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) MODULE_FIRMWARE(CMV9IV2_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) MODULE_FIRMWARE(CMVEP_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) MODULE_FIRMWARE(CMVEPV2_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) MODULE_FIRMWARE(CMVEI_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) MODULE_FIRMWARE(CMVEIV2_FIRMWARE);