^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Davicom DM9620 USB 2.0 10/100Mbps ethernet devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Peter Korsgaard <jacmet@sunsite.dk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file is licensed under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * version 2. This program is licensed "as is" without any warranty of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * V1.0 - ftp fail fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * V1.1 - model name checking, & ether plug function enhancement [0x4f, 0x20]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * V1.2 - init tx/rx checksum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * - fix dm_write_shared_word(), bug fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * - fix 10 Mbps link at power saving mode fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * V1.3 - Support kernel 2.6.31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * V1.4 - Support eeprom write of ethtool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Support DM9685
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Transmit Check Sum Control by Optopn (Source Code Default: Disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Recieve Drop Check Sum Error Packet Disable as chip default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * V1.5 - Support RK2818 (Debug the Register Function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * V1.6 - Solve compiler issue for Linux 2.6.35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * V1.7 - Enable MAC Layer Flow Control and define debug_message for linux version update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * V1.8 - Enable PHY Layer Flow Control, clear debug code, setup default phy_id value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Update dm9620_mdio_read and dm9620_mdio_write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Fix bug of ethtool eeprom write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * V1.9 - Fixed "deverr" line 367 error in Linux 2.6.38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * V2.0 - Fixed "dm9620_set_multicast" function CRC bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * V2.1 - Add 802.3az for dm9621a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * V2.2 - Add PID=0x1269 support CDC mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * V2.3 - Add PID=0x0269 support CDC mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * V2.41 - Support Linux 3.6.9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * V2.42 - Work to V2.42 according to "DM9620 BulkOut ¸É¤B¤À¸Ñ.doc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * V2.43 - Special suport for DM9621A in the table 'products'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * V2.45 - Fix the function TxStyle(), correct to be (len%2) from (len%1). 20131211.
^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) //#define DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define LNX_DM9620_VER_STR "V2.45"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/usb/usbnet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/version.h> // new v1.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) http://www.davicom.com.tw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* control requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define DM_READ_REGS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define DM_WRITE_REGS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DM_READ_MEMS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define DM_WRITE_REG 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define DM_WRITE_MEMS 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define DM_WRITE_MEM 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define DM_NET_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define DM_RX_CTRL 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define DM_FLOW_CTRL 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define DM_SHARED_CTRL 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define DM_SHARED_ADDR 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define DM_SHARED_DATA 0x0d /* low + high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define DM_EE_PHY_L 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define DM_EE_PHY_H 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define DM_WAKEUP_CTRL 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define DM_PHY_ADDR 0x10 /* 6 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define DM_MCAST_ADDR 0x16 /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define DM_GPR_CTRL 0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define DM_GPR_DATA 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define DM_PID 0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define DM_XPHY_CTRL 0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define DM_TX_CRC_CTRL 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define DM_RX_CRC_CTRL 0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define DM_SMIREG 0x91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define USB_CTRL 0xf4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define PHY_SPEC_CFG 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define DM_TXRX_M 0x5C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define MD96XX_EEPROM_MAGIC 0x9620
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define DM_MAX_MCAST 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define DM_MCAST_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define DM_EEPROM_LEN 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define DM_TX_OVERHEAD 2 /* 2 byte header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define DM_RX_OVERHEAD_9601 7 /* 3 byte header + 4 byte crc tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define DM_RX_OVERHEAD 8 /* 4 byte header + 4 byte crc tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define DM_TIMEOUT 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define DM_MODE9620 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define DM_TX_CS_EN 0 /* Transmit Check Sum Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define DM9620_PHY_ID 1 /* Stone add For kernel read phy register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct dm96xx_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) //int flag_fail_count; // EVER RX-DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int flg_txdbg; // NOW TX-DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u8 mode_9620;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u8 tx_fix_mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #if defined(DEBUG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define dm9620_print(__dev, format, args...) netdev_dbg((__dev)->net, format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define dm9620_err(__dev, format, args...) netdev_err((__dev)->net, format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #else if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define dm9620_print(dev, format, args...) devdbg(dev, format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define dm9620_err(dev, format, args...) deverr(dev, format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define dm9620_print(dev, format, args...) printk(format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define dm9620_err(dev, format, args...) printk(format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) // dm9620_print(dev, "dm_read() reg=0x%02x length=%d", reg, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) usb_rcvctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) DM_READ_REGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 0, reg, data, length, USB_CTRL_SET_TIMEOUT); //USB_CTRL_SET_TIMEOUT V.S. USB_CTRL_GET_TIMEOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u16 *tmpwPtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) tmpwPtr= kmalloc (2, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!tmpwPtr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) printk("+++++++++++ JJ5 dm_read_reg() Error: can not kmalloc!\n"); //usbnet_suspend (intf, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ret = dm_read(dev, reg, 2, tmpwPtr); // usb_submit_urb v.s. usb_control_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *value= (u8)(*tmpwPtr & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) kfree (tmpwPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) // dm9620_print(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) usb_sndctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) DM_WRITE_REGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 0, reg, data, length, USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) // dm9620_print(dev , "dm_write_reg() reg=0x%02x, value=0x%02x", reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) usb_sndctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) DM_WRITE_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) value, reg, NULL, 0, USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static void dm_write_async_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (urb->status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) printk(KERN_DEBUG "dm_write_async_callback() failed with %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct usb_ctrlrequest *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) urb = usb_alloc_urb(0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (!urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dm9620_err(dev, "Error allocating URB in dm_write_async_helper!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dm9620_err(dev, "Failed to allocate memory for control request");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) req->bRequest = length ? DM_WRITE_REGS : DM_WRITE_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) req->wValue = cpu_to_le16(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) req->wIndex = cpu_to_le16(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) req->wLength = cpu_to_le16(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) usb_fill_control_urb(urb, dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) usb_sndctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) (void *)req, data, length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dm_write_async_callback, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) status = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) dm9620_err(dev, "Error submitting the control message: status=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) // dm9620_print(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dm_write_async_helper(dev, reg, 0, length, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) // dm9620_print(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) // reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dm_write_async_helper(dev, reg, value, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u16 *tmpwPtr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0xc : 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) for (i = 0; i < DM_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if ((tmp & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (i == DM_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dm9620_err(dev, "%s read timed out!", phy ? "phy" : "eeprom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto out;
^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) dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) // ret = dm_read(dev, DM_SHARED_DATA, 2, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) //Stone add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) tmpwPtr1= kmalloc (2, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!tmpwPtr1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) printk("+++++++++++ JJ5 dm_read_reg() Error: can not kmalloc!\n"); //usbnet_suspend (intf, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = dm_read(dev, DM_SHARED_DATA, 2, tmpwPtr1); // usb_submit_urb v.s. usb_control_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) *value= (u16)(*tmpwPtr1 & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) kfree (tmpwPtr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) // dm9620_print(dev, "read shared %d 0x%02x returned 0x%04x, %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) // phy, reg, *value, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = dm_write(dev, DM_SHARED_DATA, 2, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!phy) dm_write_reg(dev, DM_SHARED_CTRL, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x0a : 0x12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dm_write_reg(dev, DM_SHARED_CTRL, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) for (i = 0; i < DM_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if ((tmp & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (i == DM_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dm9620_err(dev,"%s write timed out!", phy ? "phy" : "eeprom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int dm_write_eeprom_word(struct usbnet *dev, int phy, u8 offset, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u8 reg,dloc,tmp_H,tmp_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) __le16 eeword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) //devwarn(dev, " offset =0x%x value = 0x%x ", offset,value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* hank: from offset to determin eeprom word register location,reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) reg = (offset >> 1)&0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* hank: high/low byte by odd/even of offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dloc = (offset & 0x01)? DM_EE_PHY_H:DM_EE_PHY_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* retrieve high and low byte from the corresponding reg*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret=dm_read_shared_word(dev,0,reg,&eeword);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) //devwarn(dev, " reg =0x%x dloc = 0x%x eeword = 0x%4x", reg,dloc,eeword);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) //printk(" reg =0x%x dloc = 0x%x eeword = 0x%4x\n", reg,dloc,eeword);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) tmp_H = (eeword & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) tmp_L = (eeword >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) printk("tmp_L =0x%2x tmp_H =0x%2x eeword = 0x%4x\n", tmp_L,tmp_H,eeword);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* determine new high and low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (offset & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) tmp_L = value; } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) tmp_H = value; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) //printk("updated new: tmp_L =0x%2x tmp_H =0x%2x\n", tmp_L,tmp_H);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* hank: write low byte data first to eeprom reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) // dm_write(dev, (offset & 0x01)? DM_EE_PHY_H:DM_EE_PHY_L, 1, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) dm_write(dev,DM_EE_PHY_L, 1, &tmp_H);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* high byte will be zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) //(offset & 0x01)? (value = eeword << 8):(value = eeword >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* write the not modified 8 bits back to its origional high/low byte reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dm_write(dev,DM_EE_PHY_H, 1, &tmp_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* hank : write word location to reg 0x0c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ret = dm_write_reg(dev, DM_SHARED_ADDR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!phy) dm_write_reg(dev, DM_SHARED_CTRL, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dm_write_reg(dev, DM_SHARED_CTRL, 0x12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dm_write_reg(dev, DM_SHARED_CTRL, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) for (i = 0; i < DM_TIMEOUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if ((tmp & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (i == DM_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dm9620_err(dev, "%s write timed out!", phy ? "phy" : "eeprom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) //dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static int dm_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return dm_read_shared_word(dev, 0, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int dm9620_set_eeprom(struct net_device *net,struct ethtool_eeprom *eeprom, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dm9620_print(dev, "EEPROM: magic value, magic = 0x%x offset =0x%x data = 0x%x ",eeprom->magic, eeprom->offset,*data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (eeprom->magic != MD96XX_EEPROM_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dm9620_print(dev, "EEPROM: magic value mismatch, magic = 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) eeprom->magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if(dm_write_eeprom_word(dev, 0, eeprom->offset, *data) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static int dm9620_get_eeprom_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return DM_EEPROM_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int dm9620_get_eeprom(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct ethtool_eeprom *eeprom, u8 * data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) __le16 *ebuf = (__le16 *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* access is 16bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if ((eeprom->offset % 2) || (eeprom->len % 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) for (i = 0; i < eeprom->len / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (dm_read_eeprom_word(dev, eeprom->offset / 2 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) &ebuf[i]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int dm9620_mdio_read(struct net_device *netdev, int phy_id, int loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) __le16 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dm_read_shared_word(dev, phy_id, loc, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) // dm9620_print(dev, "dm9620_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) // phy_id, loc, le16_to_cpu(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return le16_to_cpu(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static void dm9620_mdio_write(struct net_device *netdev, int phy_id, int loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) __le16 res = cpu_to_le16(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int mdio_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) // dm9620_print(dev, "dm9620_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) // phy_id, loc, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dm_write_shared_word(dev, phy_id, loc, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) mdio_val = dm9620_mdio_read(netdev, phy_id, loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void dm9620_get_drvinfo(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Inherit standard device info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) usbnet_get_drvinfo(net, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) info->eedump_len = DM_EEPROM_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static u32 dm9620_get_link(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return mii_link_ok(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int dm9620_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #define DM_LINKEN (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #define DM_MAGICEN (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #define DM_LINKST (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #define DM_MAGICST (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) dm9620_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) u8 opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (dm_read_reg(dev, DM_WAKEUP_CTRL, &opt) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) wolinfo->supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) wolinfo->wolopts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) wolinfo->wolopts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (opt & DM_LINKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) wolinfo->wolopts |= WAKE_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (opt & DM_MAGICEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) wolinfo->wolopts |= WAKE_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dm9620_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) u8 opt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (wolinfo->wolopts & WAKE_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) opt |= DM_LINKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (wolinfo->wolopts & WAKE_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) opt |= DM_MAGICEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) dm_write_reg(dev, DM_NET_CTRL, 0x48); // enable WAKEEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) // dm_write_reg(dev, 0x92, 0x3f); //keep clock on Hank Jun 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return dm_write_reg(dev, DM_WAKEUP_CTRL, opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static struct ethtool_ops dm9620_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .get_drvinfo = dm9620_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .get_link = dm9620_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .get_msglevel = usbnet_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .set_msglevel = usbnet_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .get_eeprom_len = dm9620_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .get_eeprom = dm9620_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .set_eeprom = dm9620_set_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .get_settings = usbnet_get_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .set_settings = usbnet_set_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .nway_reset = usbnet_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .get_wol = dm9620_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .set_wol = dm9620_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static void dm9620_set_multicast(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* We use the 20 byte dev->data for our 8 byte filter buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * to avoid allocating memory that is tricky to free later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) u8 *hashes = (u8 *) & dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u8 rx_ctl = 0x31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) memset(hashes, 0x00, DM_MCAST_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (net->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) rx_ctl |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) } else if (net->flags & IFF_ALLMULTI || netdev_mc_count(net) > DM_MAX_MCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) rx_ctl |= 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) } else if (!netdev_mc_empty(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) netdev_for_each_mc_addr(ha, net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) u32 crc = crc32_le(~0, ha->addr, ETH_ALEN) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) hashes[crc>>3] |= 1 << (crc & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) } else if (net->flags & IFF_ALLMULTI || net->mc_count > DM_MAX_MCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) rx_ctl |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) } else if (net->mc_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct dev_mc_list *mc_list = net->mc_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) for (i = 0; i < net->mc_count; i++, mc_list = mc_list->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) u32 crc = crc32_le(~0, mc_list->dmi_addr, ETH_ALEN) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) hashes[crc>>3] |= 1 << (crc & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) dm_write_async(dev, DM_MCAST_ADDR, DM_MCAST_SIZE, hashes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static void __dm9620_set_mac_address(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dm_write_async(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static int dm9620_set_mac_address(struct net_device *net, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct sockaddr *addr = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) printk("[dm96] Set mac addr %pM\n", addr->sa_data); // %x:%x:...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) printk("[dm96] ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) for (i=0; i<net->addr_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) printk("[%02x] ", addr->sa_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (!is_valid_ether_addr(addr->sa_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dev_err(&net->dev, "not setting invalid mac address %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) addr->sa_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) memcpy(net->dev_addr, addr->sa_data, net->addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) __dm9620_set_mac_address(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static const struct net_device_ops vm_netdev_ops= { // new kernel 2.6.31 (20091217JJ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .ndo_open = usbnet_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .ndo_stop = usbnet_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .ndo_start_xmit = usbnet_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .ndo_tx_timeout = usbnet_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .ndo_change_mtu = usbnet_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .ndo_do_ioctl = dm9620_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) .ndo_set_rx_mode = dm9620_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .ndo_set_multicast_list = dm9620_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .ndo_set_mac_address = dm9620_set_mac_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int dm9620_bind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) u16 *tmpwPtr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int ret,mdio_val,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct dm96xx_priv* priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) u8 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ret = usbnet_get_endpoints(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) dev->net->netdev_ops = &vm_netdev_ops; // new kernel 2.6.31 (20091217JJ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) dev->net->ethtool_ops = &dm9620_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dev->net->do_ioctl = dm9620_ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev->net->set_multicast_list = dm9620_set_multicast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dev->net->ethtool_ops = &dm9620_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dev->net->hard_header_len += DM_TX_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD+1; // ftp fail fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dev->rx_urb_size = (dev->rx_urb_size > 2048) ? dev->rx_urb_size : 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dev->mii.dev = dev->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) dev->mii.mdio_read = dm9620_mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) dev->mii.mdio_write = dm9620_mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) dev->mii.phy_id_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) dev->mii.reg_num_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) dev->mii.phy_id = DM9620_PHY_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) printk("[dm962] Linux Driver = %s\n", LNX_DM9620_VER_STR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) //JJ1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if ( (ret= dm_read_reg(dev, 0x29, &tmp)) >=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) printk("++++++[dm962]+++++ dm_read_reg() 0x29 0x%02x\n",tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) printk("++++++[dm962]+++++ dm_read_reg() 0x29 fail-func-return %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if ( (ret= dm_read_reg(dev, 0x28, &tmp)) >=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) printk("++++++[dm962]+++++ dm_read_reg() 0x28 0x%02x\n",tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) printk("++++++[dm962]+++++ dm_read_reg() 0x28 fail-func-return %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if ( (ret= dm_read_reg(dev, 0x2b, &tmp)) >=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) printk("++++++[dm962]+++++ dm_read_reg() 0x2b 0x%02x\n",tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) printk("++++++[dm962]+++++ dm_read_reg() 0x2b fail-func-return %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if ( (ret= dm_read_reg(dev, 0x2a, &tmp)) >=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) printk("++++++[dm962]+++++ dm_read_reg() 0x2a 0x%02x\n",tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) printk("++++++[dm962]+++++ dm_read_reg() 0x2a fail-func-return %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) //JJ3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if ( (ret= dm_read_reg(dev, 0xF2, &tmp)) >=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) printk("++++++[dm962]+++++ dm_read_reg() 0xF2 0x%02x\n",tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) printk("++++++[dm962]+++++ dm_read_reg() 0xF2 fail-func-return %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) printk("++++++[dm962]+++++ [Analysis.2] 0xF2, D[7] %d %s\n", tmp>>7, (tmp&(1<<7))? "Err: RX Unexpected condition": "OK" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) printk("++++++[dm962]+++++ [Analysis.2] 0xF2, D[6] %d %s\n", (tmp>>6)&1, (tmp&(1<<6))? "Err: Host Suspend condition": "OK" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) printk("++++++[dm962]+++++ [Analysis.2] 0xF2, D[5] %d %s\n", (tmp>>5)&1, (tmp&(1<<5))? "EP1: Data Ready": "EP1: Empty" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) printk("++++++[dm962]+++++ [Analysis.2] 0xF2, D[3] %d %s\n", (tmp>>3)&1, (tmp&(1<<3))? "Err: Bulk out condition": "OK" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) printk("++++++[dm962]+++++ [Analysis.2] 0xF2, D[2] %d %s\n", (tmp>>2)&1, (tmp&(1<<2))? "Err: TX Buffer full": "OK" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) printk("++++++[dm962]+++++ [Analysis.2] 0xF2, D[1] %d %s\n", (tmp>>1)&1, (tmp&(1<<1))? "Warn: TX buffer Almost full": "OK" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) printk("++++++[dm962]+++++ [Analysis.2] 0xF2, D[0] %d %s\n", (tmp>>0)&1, (tmp&(1<<0))? "Status: TX buffer has pkts": "Status: TX buffer 0 pkts" );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) dm_write_reg(dev, DM_NET_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) //Stone add Enable "MAC layer" Flow Control, TX Pause Packet Enable and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) dm_write_reg(dev, DM_FLOW_CTRL, 0x29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) //Stone add Enable "PHY layer" Flow Control support (phy register 0x04 bit 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) temp = dm9620_mdio_read(dev->net, dev->mii.phy_id, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) dm9620_mdio_write(dev->net, dev->mii.phy_id, 0x04, temp | 0x400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* Add V1.1, Enable auto link while plug in RJ45, Hank July 20, 2009*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) dm_write_reg(dev, USB_CTRL, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* read MAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) printk(KERN_ERR "Error reading MAC address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) printk("[dm96] Chk mac addr %pM\n", dev->net->dev_addr); // %x:%x...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) printk("[dm96] ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) for (i=0; i<ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) printk("[%02x] ", dev->net->dev_addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* read SMI mode register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) priv = dev->driver_priv = kmalloc(sizeof(struct dm96xx_priv), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (!priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) dm9620_err(dev,"Failed to allocate memory for dm96xx_priv");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* work-around for 9620 mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) dm_read_reg(dev, 0x5c, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) priv->tx_fix_mod = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) printk(KERN_WARNING "[dm96] 9620 tx_fix_mod (DM9_NREV= %d)\n", priv->tx_fix_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) printk("[dm96] Fixme: work around for 9620 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) printk("[dm96] Add tx_fixup() debug...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) dm_write_reg(dev, DM_MCAST_ADDR, 0); // clear data bus to 0s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) dm_read_reg(dev, DM_MCAST_ADDR, &temp); // clear data bus to 0s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ret = dm_read_reg(dev, DM_SMIREG, &temp); // Must clear data bus before we can read the 'MODE9620' bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) priv->flg_txdbg= 0; //->flag_fail_count= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (ret<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) printk(KERN_ERR "[dm96] Error read SMI register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) else priv->mode_9620 = temp & DM_MODE9620;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) printk(KERN_WARNING "[dm96] 9620 Mode = %d\n", priv->mode_9620);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) dm_read_reg(dev, DM_TXRX_M, &temp); // Need to check the Chipset version (register 0x5c is 0x02?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (temp == 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dm_read_reg(dev, 0x3f, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) temp |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) dm_write_reg(dev, 0x3f, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) //Stone add for check Product ID == 0x1269
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) tmpwPtr2= kmalloc (2, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (!tmpwPtr2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) printk("+++++++++++ JJ5 dm_read_reg() Error: can not kmalloc!\n"); //usbnet_suspend (intf, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ret =dm_read(dev, DM_PID, 2, tmpwPtr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (*tmpwPtr2 == 0x1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dm_write_reg(dev, DM_SMIREG, 0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (*tmpwPtr2 == 0x0269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) dm_write_reg(dev, DM_SMIREG, 0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) kfree (tmpwPtr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /* power up phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dm_write_reg(dev, DM_GPR_CTRL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) dm_write_reg(dev, DM_GPR_DATA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* Init tx/rx checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) #if DM_TX_CS_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) dm_write_reg(dev, DM_TX_CRC_CTRL, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dm_write_reg(dev, DM_RX_CRC_CTRL, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* receive broadcast packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) dm9620_set_multicast(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dm9620_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* Hank add, work for comapubility issue (10M Power control) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) dm9620_mdio_write(dev->net, dev->mii.phy_id, PHY_SPEC_CFG, 0x800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) mdio_val = dm9620_mdio_read(dev->net, dev->mii.phy_id, PHY_SPEC_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dm9620_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) mii_nway_restart(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) void dm9620_unbind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) struct dm96xx_priv* priv= dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) printk("dm9620_unbind():\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) //printk("flag_fail_count %lu\n", (long unsigned int)priv->flag_fail_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) printk("flg_txdbg %lu\n", (long unsigned int)priv->flg_txdbg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) kfree(dev->driver_priv); // displayed dev->.. above, then can free dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) printk("rx_length_errors %lu\n",dev->net->stats.rx_length_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) printk("rx_over_errors %lu\n",dev->net->stats.rx_over_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) printk("rx_crc_errors %lu\n",dev->net->stats.rx_crc_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) printk("rx_frame_errors %lu\n",dev->net->stats.rx_frame_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) printk("rx_fifo_errors %lu\n",dev->net->stats.rx_fifo_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) printk("rx_missed_errors %lu\n",dev->net->stats.rx_missed_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) printk("rx_length_errors %lu\n",dev->stats.rx_length_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) printk("rx_over_errors %lu\n",dev->stats.rx_over_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) printk("rx_crc_errors %lu\n",dev->stats.rx_crc_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) printk("rx_frame_errors %lu\n",dev->stats.rx_frame_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) printk("rx_fifo_errors %lu\n",dev->stats.rx_fifo_errors );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) printk("rx_missed_errors %lu\n",dev->stats.rx_missed_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static int dm9620_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct dm96xx_priv* priv = (struct dm96xx_priv *)dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* 9620 format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) b0: rx status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) b1: packet length (incl crc) low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) b2: packet length (incl crc) high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) b3..n-4: packet data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) bn-3..bn: ethernet crc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* 9620 format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) one additional byte then 9620 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) rx_flag in the first pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (unlikely(skb->len < DM_RX_OVERHEAD_9601)) { // 20090623
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (priv->mode_9620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* mode 9620 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (unlikely(skb->len < DM_RX_OVERHEAD)) { // 20090623
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) // if (skb->data[0]!=0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) // priv->flag_fail_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) status = skb->data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) len = (skb->data[2] | (skb->data[3] << 8)) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (unlikely(status & 0xbf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (status & 0x01) dev->net->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (status & 0x02) dev->net->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (status & 0x04) dev->net->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (status & 0x20) dev->net->stats.rx_missed_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (status & 0x90) dev->net->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (status & 0x01) dev->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (status & 0x02) dev->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (status & 0x04) dev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (status & 0x20) dev->stats.rx_missed_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (status & 0x90) dev->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) skb_pull(skb, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) skb_trim(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) else { /* mode 9620 (original driver code) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) status = skb->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) len = (skb->data[1] | (skb->data[2] << 8)) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (unlikely(status & 0xbf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (status & 0x01) dev->net->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (status & 0x02) dev->net->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (status & 0x04) dev->net->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (status & 0x20) dev->net->stats.rx_missed_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (status & 0x90) dev->net->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (status & 0x01) dev->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (status & 0x02) dev->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (status & 0x04) dev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (status & 0x20) dev->stats.rx_missed_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (status & 0x90) dev->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) skb_pull(skb, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) skb_trim(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) } // 'priv'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) #define TX_LEN_E (1<<0) //EVEN, No action
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) #define TX_LEN_O (1<<1) //ODD, Odd to even workaround
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) #define TX_LEN_F (1<<2) //FULL, Full payload workaround
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) u8 TxStyle(int len, unsigned full_payload){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) u8 s= (len%2)? TX_LEN_O: TX_LEN_E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) len= ((len+1)/2)*2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) len += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if ((len % full_payload)==0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) s |= TX_LEN_F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct sk_buff *TxExpend(struct dm96xx_priv* priv, u8 ts, struct sk_buff *skb, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int newheadroom= 2, newtailroom= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (ts&TX_LEN_O) newtailroom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (ts&TX_LEN_F) newtailroom += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (skb_headroom(skb) >= newheadroom) newheadroom= 0; // head no need expend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (skb_tailroom(skb) >= newtailroom) newtailroom= 0; // tail no need expend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (newheadroom || newtailroom){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct sk_buff *skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) skb2 = skb_copy_expand(skb, newheadroom, newtailroom, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) skb = skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (!skb){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) printk("[dm96-TxRound].%d expend copy fail, for head, tail= %d, %d\n", priv->flg_txdbg++, newheadroom, newtailroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) printk("[dm96-TxRound].%d expend copy OK, for head, tail= %d, %d\n", priv->flg_txdbg++, newheadroom, newtailroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static struct sk_buff *dm9620_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) int newheadroom, newtailroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct dm96xx_priv* priv = (struct dm96xx_priv *)dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /* format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) b0: packet length low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) b1: packet length high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) b3..n: packet data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (priv->tx_fix_mod<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (skb_headroom(skb) < DM_TX_OVERHEAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct sk_buff *skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) skb = skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) __skb_push(skb, DM_TX_OVERHEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if ((skb->len % dev->maxpacket) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) //;DM9620-E4,E5, and E6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* usbnet adds padding 1 byte if odd len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /* usbnet adds padding 2 bytes if length is a multiple of packet size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if so, adjust length value in header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) u8 TS= TxStyle(len, dev->maxpacket); //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!(skb= TxExpend(priv, TS, skb, flags))) return NULL; //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (TS & TX_LEN_F) len += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) newheadroom= 2; //2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) newtailroom= 0; //0, 1, 2, or 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (TS & TX_LEN_O) newtailroom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (TS & TX_LEN_F) newtailroom += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (TS & TX_LEN_O) printk("[dm96-TxRound].%d for LEN_ODD tail_room +1, rslt add %d\n", priv->flg_txdbg, newtailroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (TS & TX_LEN_F) printk("[dm96-TxRound].%d for LEN_PLOAD tail_room +2, rslt add %d\n", priv->flg_txdbg, newtailroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (TS & TX_LEN_F) printk("[dm96-TxRound].%d for LEN_PLOAD data_len +2, len from %d to %d\n", priv->flg_txdbg, len-2, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (TS & (TX_LEN_O|TX_LEN_F)) priv->flg_txdbg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) __skb_push(skb, newheadroom); //2 bytes,for data[0],data[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) __skb_put(skb, newtailroom); //0, 1, 2, or 3 bytes (for tailer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) //Note: 0, NOTHING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) //Note: 1, Odd to even WORKAROUND.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) //Note: 2 or 3, the condition is full payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) // This is the add more two bytes WORKAROUND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) // for bulkout and buffLen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) //;DM9620-E7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (skb_headroom(skb) < DM_TX_OVERHEAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct sk_buff *skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) skb = skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) newheadroom= 2; //2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) __skb_push(skb, newheadroom); //2 bytes, for data[0],data[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) skb->data[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) skb->data[1] = len >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* hank, recalcute checksum of TCP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) } // 'kb'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static void dm9620_status(struct usbnet *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) int link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) /* format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) b0: net status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) b1: tx status 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) b2: tx status 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) b3: rx status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) b4: rx overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) b5: rx count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) b6: tx count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) b7: gpr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (urb->actual_length < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) buf = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) link = !!(buf[0] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (netif_carrier_ok(dev->net) != link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) netif_carrier_on(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) usbnet_defer_kevent (dev, EVENT_LINK_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) netif_carrier_off(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) dm9620_print(dev, "Link Status is: %d", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static int dm9620_link_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct ethtool_cmd ecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) mii_check_media(&dev->mii, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) mii_ethtool_gset(&dev->mii, &ecmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /* hank add*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) dm9620_mdio_write(dev->net, dev->mii.phy_id, PHY_SPEC_CFG, 0x800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) dm9620_print(dev, "link_reset() speed: %d duplex: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ecmd.speed, ecmd.duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static const struct driver_info dm9620_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .description = "Davicom DM9620 USB Ethernet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .flags = FLAG_ETHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .bind = dm9620_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .rx_fixup = dm9620_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .tx_fixup = dm9620_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .status = dm9620_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .link_reset = dm9620_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .reset = dm9620_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .unbind = dm9620_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static const struct usb_device_id products[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) USB_DEVICE(0x07aa, 0x9601), /* Corega FEther USB-TXC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) USB_DEVICE(0x0a46, 0x9601), /* Davicom USB-100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) .driver_info = (unsigned long)&dm9620_info,
^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) USB_DEVICE(0x0a46, 0x6688), /* ZT6688 USB NIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) USB_DEVICE(0x0a46, 0x0268), /* ShanTou ST268 USB NIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) USB_DEVICE(0x0a46, 0x9620), /* Davicom 9620 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) USB_DEVICE(0x0a46, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) USB_DEVICE(0x0a46, 0x9622), /* Davicom 9622 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) USB_DEVICE(0x0fe6, 0x8101), /* Davicom 9601 USB to Fast Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) USB_DEVICE(0x0a46, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) USB_DEVICE(0x0a46, 0x0269), /* Davicom 9620A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) //+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) //VID.00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) //0.0000 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) USB_DEVICE(0x0000, 0x9620), /* Davicom 9620 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) USB_DEVICE(0x0000, 0x0269), /* Davicom 9620A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) USB_DEVICE(0x0000, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) USB_DEVICE(0x0000, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) //1.0000 0000 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) //2.0000 0000 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) //3.0000 0000 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) //4.0000 0100 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) //5.0000 0100 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) //6.0000 0100 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) //7.0000 0100 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) USB_DEVICE(0x0002, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) USB_DEVICE(0x0002, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) USB_DEVICE(0x0004, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) USB_DEVICE(0x0004, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) USB_DEVICE(0x0006, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) USB_DEVICE(0x0006, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .driver_info = (unsigned long)&dm9620_info,
^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) USB_DEVICE(0x0040, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) USB_DEVICE(0x0040, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) USB_DEVICE(0x0042, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) USB_DEVICE(0x0042, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) USB_DEVICE(0x0044, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) USB_DEVICE(0x0044, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) //7.0000 0100 0110 (0A46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) USB_DEVICE(0x0046, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) USB_DEVICE(0x0046, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) // ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) //8.0010 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) //9.0010 0000 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) //A.0010 0000 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) //B.0010 0000 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) //C.0010 0100 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) //D.0010 0100 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) //E.0010 0100 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) //F.0010 0100 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) USB_DEVICE(0x0200, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) USB_DEVICE(0x0200, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) USB_DEVICE(0x0202, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) USB_DEVICE(0x0202, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) USB_DEVICE(0x0204, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) USB_DEVICE(0x0204, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) .driver_info = (unsigned long)&dm9620_info,
^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) USB_DEVICE(0x0206, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) USB_DEVICE(0x0206, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) USB_DEVICE(0x0240, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) USB_DEVICE(0x0240, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) USB_DEVICE(0x0242, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) USB_DEVICE(0x0242, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) USB_DEVICE(0x0244, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) USB_DEVICE(0x0244, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) //F.0010 0100 0110 (0A46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) USB_DEVICE(0x0246, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) USB_DEVICE(0x0246, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) // ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) //10.1000 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) //11.1000 0000 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) //12.1000 0000 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) //13.1000 0000 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) //14.1000 0100 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) //15.1000 0100 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) //16.1000 0100 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) //17.1000 0100 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) USB_DEVICE(0x0800, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) USB_DEVICE(0x0800, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) USB_DEVICE(0x0802, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) USB_DEVICE(0x0802, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) USB_DEVICE(0x0804, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) USB_DEVICE(0x0804, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) USB_DEVICE(0x0806, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) USB_DEVICE(0x0806, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) .driver_info = (unsigned long)&dm9620_info,
^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) USB_DEVICE(0x0840, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) USB_DEVICE(0x0840, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) USB_DEVICE(0x0842, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) USB_DEVICE(0x0842, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) USB_DEVICE(0x0844, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) USB_DEVICE(0x0844, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) //17.1010 0100 0110 (0A46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) USB_DEVICE(0x0846, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) USB_DEVICE(0x0846, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) // ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) //18.1010 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) //19.1010 0000 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) //1A.1010 0000 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) //1B.1010 0000 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) //1C.1010 0100 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) //1D.1010 0100 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) //1E.1010 0100 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) USB_DEVICE(0x0A00, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) USB_DEVICE(0x0A00, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) USB_DEVICE(0x0A02, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) USB_DEVICE(0x0A02, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) USB_DEVICE(0x0A04, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) USB_DEVICE(0x0A04, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) USB_DEVICE(0x0A06, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) USB_DEVICE(0x0A06, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) USB_DEVICE(0x0A40, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) USB_DEVICE(0x0A40, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) USB_DEVICE(0x0A42, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) USB_DEVICE(0x0A42, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) USB_DEVICE(0x0A44, 0x9621), /* Davicom 9621 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) USB_DEVICE(0x0A44, 0x1269), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) //1F.1010 0100 0110 (0A46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) // .Original Default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) //+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) //1268, 1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) USB_DEVICE(0x0000, 0x1268), /* Davicom 9621A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) USB_DEVICE(0x0000, 0x1200), /* Davicom 9620A CDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) USB_DEVICE(0x0000, 0x1220), /* Davicom 9620A CDC, 1220 test mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) .driver_info = (unsigned long)&dm9620_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {}, // END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) MODULE_DEVICE_TABLE(usb, products);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static struct usb_driver dm9620_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .name = "dm9620",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .id_table = products,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .probe = usbnet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) .disconnect = usbnet_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) .suspend = usbnet_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) .resume = usbnet_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) static int __init dm9620_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return usb_register(&dm9620_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) static void __exit dm9620_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) usb_deregister(&dm9620_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) module_init(dm9620_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) module_exit(dm9620_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) MODULE_DESCRIPTION("Davicom DM9620 USB 2.0 ethernet devices");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)