^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);