^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011-2013 ASIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/usb/usbnet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <uapi/linux/mdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define AX88179_PHY_ID 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define AX_EEPROM_LEN 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define AX88179_EEPROM_MAGIC 0x17900b95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define AX_MCAST_FLTSIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define AX_MAX_MCAST 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define AX_INT_PPLS_LINK ((u32)BIT(16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define AX_RXHDR_L4_TYPE_MASK 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AX_RXHDR_L4_TYPE_UDP 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define AX_RXHDR_L4_TYPE_TCP 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define AX_RXHDR_L3CSUM_ERR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define AX_RXHDR_L4CSUM_ERR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define AX_RXHDR_CRC_ERR ((u32)BIT(29))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define AX_RXHDR_DROP_ERR ((u32)BIT(31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define AX_ACCESS_MAC 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AX_ACCESS_PHY 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define AX_ACCESS_EEPROM 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define AX_ACCESS_EFUS 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AX_RELOAD_EEPROM_EFUSE 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define AX_PAUSE_WATERLVL_HIGH 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define AX_PAUSE_WATERLVL_LOW 0x55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PHYSICAL_LINK_STATUS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define AX_USB_SS 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define AX_USB_HS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define GENERAL_STATUS 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Check AX88179 version. UA1:Bit2 = 0, UA2:Bit2 = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define AX_SECLD 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define AX_SROM_ADDR 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define AX_SROM_CMD 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define EEP_RD 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define EEP_BUSY 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define AX_SROM_DATA_LOW 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define AX_SROM_DATA_HIGH 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define AX_RX_CTL 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define AX_RX_CTL_DROPCRCERR 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define AX_RX_CTL_IPE 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define AX_RX_CTL_START 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define AX_RX_CTL_AP 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define AX_RX_CTL_AM 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define AX_RX_CTL_AB 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define AX_RX_CTL_AMALL 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define AX_RX_CTL_PRO 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define AX_RX_CTL_STOP 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define AX_NODE_ID 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define AX_MULFLTARY 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AX_MEDIUM_STATUS_MODE 0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define AX_MEDIUM_GIGAMODE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define AX_MEDIUM_FULL_DUPLEX 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define AX_MEDIUM_EN_125MHZ 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define AX_MEDIUM_RXFLOW_CTRLEN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define AX_MEDIUM_TXFLOW_CTRLEN 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define AX_MEDIUM_RECEIVE_EN 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define AX_MEDIUM_PS 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define AX_MEDIUM_JUMBO_EN 0x8040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define AX_MONITOR_MOD 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define AX_MONITOR_MODE_RWLC 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define AX_MONITOR_MODE_RWMP 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define AX_MONITOR_MODE_PMEPOL 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define AX_MONITOR_MODE_PMETYPE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define AX_GPIO_CTRL 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define AX_GPIO_CTRL_GPIO3EN 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define AX_GPIO_CTRL_GPIO2EN 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define AX_GPIO_CTRL_GPIO1EN 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define AX_PHYPWR_RSTCTL 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define AX_PHYPWR_RSTCTL_BZ 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define AX_PHYPWR_RSTCTL_IPRL 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define AX_PHYPWR_RSTCTL_AT 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define AX_RX_BULKIN_QCTRL 0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define AX_CLK_SELECT 0x33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define AX_CLK_SELECT_BCS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define AX_CLK_SELECT_ACS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define AX_CLK_SELECT_ULR 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define AX_RXCOE_CTL 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define AX_RXCOE_IP 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define AX_RXCOE_TCP 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define AX_RXCOE_UDP 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define AX_RXCOE_TCPV6 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define AX_RXCOE_UDPV6 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define AX_TXCOE_CTL 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define AX_TXCOE_IP 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define AX_TXCOE_TCP 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define AX_TXCOE_UDP 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define AX_TXCOE_TCPV6 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define AX_TXCOE_UDPV6 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define AX_LEDCTRL 0x73
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define GMII_PHY_PHYSR 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define GMII_PHY_PHYSR_SMASK 0xc000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define GMII_PHY_PHYSR_GIGA 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define GMII_PHY_PHYSR_100 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define GMII_PHY_PHYSR_FULL 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define GMII_PHY_PHYSR_LINK 0x400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define GMII_LED_ACT 0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define GMII_LED_ACTIVE_MASK 0xff8f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define GMII_LED0_ACTIVE BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define GMII_LED1_ACTIVE BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define GMII_LED2_ACTIVE BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define GMII_LED_LINK 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define GMII_LED_LINK_MASK 0xf888
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define GMII_LED0_LINK_10 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define GMII_LED0_LINK_100 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define GMII_LED0_LINK_1000 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define GMII_LED1_LINK_10 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define GMII_LED1_LINK_100 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define GMII_LED1_LINK_1000 BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define GMII_LED2_LINK_10 BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define GMII_LED2_LINK_100 BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define GMII_LED2_LINK_1000 BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define LED0_ACTIVE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define LED0_LINK_10 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define LED0_LINK_100 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define LED0_LINK_1000 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define LED0_FD BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define LED0_USB3_MASK 0x001f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define LED1_ACTIVE BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define LED1_LINK_10 BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define LED1_LINK_100 BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define LED1_LINK_1000 BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define LED1_FD BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define LED1_USB3_MASK 0x03e0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define LED2_ACTIVE BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define LED2_LINK_1000 BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define LED2_LINK_100 BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define LED2_LINK_10 BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define LED2_FD BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define LED_VALID BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define LED2_USB3_MASK 0x7c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define GMII_PHYPAGE 0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define GMII_PHY_PAGE_SELECT 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define GMII_PHY_PGSEL_EXT 0x0007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define GMII_PHY_PGSEL_PAGE0 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define GMII_PHY_PGSEL_PAGE3 0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define GMII_PHY_PGSEL_PAGE5 0x0005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct ax88179_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u8 eee_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u8 eee_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u16 rxctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u16 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct ax88179_int_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) __le32 intdata1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) __le32 intdata2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned char ctrl, timer_l, timer_h, size, ifg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } AX88179_BULKIN_SIZE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {7, 0x4f, 0, 0x12, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {7, 0x20, 3, 0x16, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {7, 0xae, 7, 0x18, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {7, 0xcc, 0x4c, 0x18, 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u16 size, void *data, int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) BUG_ON(!dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) fn = usbnet_read_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) fn = usbnet_read_cmd_nopm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) value, index, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) index, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u16 size, void *data, int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) BUG_ON(!dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) fn = usbnet_write_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) fn = usbnet_write_cmd_nopm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) value, index, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (unlikely(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) index, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return ret;
^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 void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u16 index, u16 size, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u16 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (2 == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) buf = *((u16 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) cpu_to_le16s(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) USB_RECIP_DEVICE, value, index, &buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) USB_RECIP_DEVICE, value, index, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) u16 index, u16 size, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (2 == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u16 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) le16_to_cpus(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *((u16 *)data) = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) } else if (4 == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u32 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) le32_to_cpus(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *((u32 *)data) = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u16 index, u16 size, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (2 == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) u16 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) buf = *((u16 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) cpu_to_le16s(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ret = __ax88179_write_cmd(dev, cmd, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) size, &buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ret = __ax88179_write_cmd(dev, cmd, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) size, data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u16 size, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (2 == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u16 buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) le16_to_cpus(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) *((u16 *)data) = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) } else if (4 == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u32 buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) le32_to_cpus(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) *((u32 *)data) = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u16 size, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (2 == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) u16 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) buf = *((u16 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) cpu_to_le16s(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ret = __ax88179_write_cmd(dev, cmd, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) size, &buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ret = __ax88179_write_cmd(dev, cmd, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) size, data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static void ax88179_status(struct usbnet *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct ax88179_int_data *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u32 link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (urb->actual_length < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) event = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) le32_to_cpus((void *)&event->intdata1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) link = (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (netif_carrier_ok(dev->net) != link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) usbnet_link_change(dev, link, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) netdev_info(dev->net, "ax88179 - Link status is: %d\n", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u16 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return res;
^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) static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u16 res = (u16) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static inline int ax88179_phy_mmd_indirect(struct usbnet *dev, u16 prtad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u16 devad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) tmp16 = devad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) MII_MMD_CTRL, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) tmp16 = prtad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) MII_MMD_DATA, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) tmp16 = devad | MII_MMD_CTRL_NOINCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) MII_MMD_CTRL, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ax88179_phy_read_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ax88179_phy_mmd_indirect(dev, prtad, devad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) MII_MMD_DATA, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (ret < 0)
^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) return tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ax88179_phy_write_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ax88179_phy_mmd_indirect(dev, prtad, devad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) MII_MMD_DATA, 2, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct usbnet *dev = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) u8 tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) usbnet_suspend(intf, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Disable RX path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* Force bulk-in zero length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) tmp16 |= AX_PHYPWR_RSTCTL_BZ | AX_PHYPWR_RSTCTL_IPRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* change clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) tmp8 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* Configure RX control register => stop operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) tmp16 = AX_RX_CTL_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* This function is used to enable the autodetach function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* This function is determined by offset 0x43 of EEPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static int ax88179_auto_detach(struct usbnet *dev, int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) u8 tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int (*fnr)(struct usbnet *, u8, u16, u16, u16, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int (*fnw)(struct usbnet *, u8, u16, u16, u16, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (!in_pm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) fnr = ax88179_read_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) fnw = ax88179_write_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) fnr = ax88179_read_cmd_nopm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) fnw = ax88179_write_cmd_nopm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (fnr(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if ((tmp16 == 0xFFFF) || (!(tmp16 & 0x0100)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* Enable Auto Detach bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) tmp8 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) fnr(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) tmp8 |= AX_CLK_SELECT_ULR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) fnw(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) fnr(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) tmp16 |= AX_PHYPWR_RSTCTL_AT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) fnw(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int ax88179_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct usbnet *dev = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) u8 tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) usbnet_link_change(dev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* Power up ethernet PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) tmp16 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) tmp16 = AX_PHYPWR_RSTCTL_IPRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* Ethernet PHY Auto Detach*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ax88179_auto_detach(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* Enable clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) tmp8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* Configure RX control register => start operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return usbnet_resume(intf);
^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 void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ax88179_get_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;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 1, 1, &opt) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) wolinfo->supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) wolinfo->wolopts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) wolinfo->wolopts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (opt & AX_MONITOR_MODE_RWLC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) wolinfo->wolopts |= WAKE_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (opt & AX_MONITOR_MODE_RWMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) wolinfo->wolopts |= WAKE_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u8 opt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (wolinfo->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (wolinfo->wolopts & WAKE_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) opt |= AX_MONITOR_MODE_RWLC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (wolinfo->wolopts & WAKE_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) opt |= AX_MONITOR_MODE_RWMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 1, 1, &opt) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int ax88179_get_eeprom_len(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return AX_EEPROM_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) u16 *eeprom_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int first_word, last_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (eeprom->len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) eeprom->magic = AX88179_EEPROM_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) first_word = eeprom->offset >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) last_word = (eeprom->offset + eeprom->len - 1) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (!eeprom_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* ax88179/178A returns 2 bytes from eeprom on read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) for (i = first_word; i <= last_word; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ret = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) &eeprom_buff[i - first_word],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) kfree(eeprom_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) kfree(eeprom_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ax88179_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) u16 *eeprom_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) int first_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) int last_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) netdev_dbg(net, "write EEPROM len %d, offset %d, magic 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) eeprom->len, eeprom->offset, eeprom->magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (eeprom->len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (eeprom->magic != AX88179_EEPROM_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) first_word = eeprom->offset >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) last_word = (eeprom->offset + eeprom->len - 1) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!eeprom_buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* align data to 16 bit boundaries, read the missing data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) the EEPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (eeprom->offset & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ret = ax88179_read_cmd(dev, AX_ACCESS_EEPROM, first_word, 1, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) &eeprom_buff[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", first_word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if ((eeprom->offset + eeprom->len) & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = ax88179_read_cmd(dev, AX_ACCESS_EEPROM, last_word, 1, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) &eeprom_buff[last_word - first_word]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", last_word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) memcpy((u8 *)eeprom_buff + (eeprom->offset & 1), data, eeprom->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) for (i = first_word; i <= last_word; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) netdev_dbg(net, "write to EEPROM at offset 0x%02x, data 0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) i, eeprom_buff[i - first_word]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ret = ax88179_write_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) &eeprom_buff[i - first_word]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) netdev_err(net, "Failed to write EEPROM at offset 0x%02x.\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* reload EEPROM data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ret = ax88179_write_cmd(dev, AX_RELOAD_EEPROM_EFUSE, 0x0000, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) netdev_err(net, "Failed to reload EEPROM data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) kfree(eeprom_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int ax88179_get_link_ksettings(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mii_ethtool_get_link_ksettings(&dev->mii, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int ax88179_set_link_ksettings(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) const struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return mii_ethtool_set_link_ksettings(&dev->mii, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ax88179_ethtool_get_eee(struct usbnet *dev, struct ethtool_eee *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /* Get Supported EEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) val = ax88179_phy_read_mmd_indirect(dev, MDIO_PCS_EEE_ABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) MDIO_MMD_PCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Get advertisement EEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_ADV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) MDIO_MMD_AN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Get LP advertisement EEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_LPABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) MDIO_MMD_AN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ax88179_ethtool_set_eee(struct usbnet *dev, struct ethtool_eee *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) u16 tmp16 = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return ax88179_phy_write_mmd_indirect(dev, MDIO_AN_EEE_ADV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) MDIO_MMD_AN, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static int ax88179_chk_eee(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct ax88179_data *priv = (struct ax88179_data *)dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) mii_ethtool_gset(&dev->mii, &ecmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (ecmd.duplex & DUPLEX_FULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int eee_lp, eee_cap, eee_adv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) u32 lp, cap, adv, supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) eee_cap = ax88179_phy_read_mmd_indirect(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) MDIO_PCS_EEE_ABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) MDIO_MMD_PCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (eee_cap < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) priv->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (!cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) priv->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) eee_lp = ax88179_phy_read_mmd_indirect(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) MDIO_AN_EEE_LPABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) MDIO_MMD_AN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (eee_lp < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) priv->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) eee_adv = ax88179_phy_read_mmd_indirect(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) MDIO_AN_EEE_ADV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) MDIO_MMD_AN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (eee_adv < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) priv->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return false;
^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) adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) supported = (ecmd.speed == SPEED_1000) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) SUPPORTED_1000baseT_Full :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) SUPPORTED_100baseT_Full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!(lp & adv & supported)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) priv->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) priv->eee_active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) priv->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static void ax88179_disable_eee(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) tmp16 = GMII_PHY_PGSEL_PAGE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) GMII_PHY_PAGE_SELECT, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) tmp16 = 0x3246;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) MII_PHYADDR, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) tmp16 = GMII_PHY_PGSEL_PAGE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) GMII_PHY_PAGE_SELECT, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static void ax88179_enable_eee(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) tmp16 = GMII_PHY_PGSEL_PAGE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) GMII_PHY_PAGE_SELECT, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) tmp16 = 0x3247;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) MII_PHYADDR, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) tmp16 = GMII_PHY_PGSEL_PAGE5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) GMII_PHY_PAGE_SELECT, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) tmp16 = 0x0680;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) MII_BMSR, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) tmp16 = GMII_PHY_PGSEL_PAGE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) GMII_PHY_PAGE_SELECT, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int ax88179_get_eee(struct net_device *net, struct ethtool_eee *edata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct ax88179_data *priv = (struct ax88179_data *)dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) edata->eee_enabled = priv->eee_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) edata->eee_active = priv->eee_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return ax88179_ethtool_get_eee(dev, edata);
^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 ax88179_set_eee(struct net_device *net, struct ethtool_eee *edata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct ax88179_data *priv = (struct ax88179_data *)dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) priv->eee_enabled = edata->eee_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!priv->eee_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ax88179_disable_eee(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) priv->eee_enabled = ax88179_chk_eee(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (!priv->eee_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) ax88179_enable_eee(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ret = ax88179_ethtool_set_eee(dev, edata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) mii_nway_restart(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) usbnet_link_change(dev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static const struct ethtool_ops ax88179_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .get_link = ethtool_op_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .get_msglevel = usbnet_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .set_msglevel = usbnet_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .get_wol = ax88179_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .set_wol = ax88179_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .get_eeprom_len = ax88179_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .get_eeprom = ax88179_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .set_eeprom = ax88179_set_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .get_eee = ax88179_get_eee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .set_eee = ax88179_set_eee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .nway_reset = usbnet_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .get_link_ksettings = ax88179_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .set_link_ksettings = ax88179_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .get_ts_info = ethtool_op_get_ts_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) static void ax88179_set_multicast(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) struct ax88179_data *data = (struct ax88179_data *)dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) u8 *m_filter = ((u8 *)dev->data) + 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (net->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) data->rxctl |= AX_RX_CTL_PRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) } else if (net->flags & IFF_ALLMULTI ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) netdev_mc_count(net) > AX_MAX_MCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) data->rxctl |= AX_RX_CTL_AMALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) } else if (netdev_mc_empty(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* just broadcast and directed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* We use the 20 byte dev->data for our 8 byte filter buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * to avoid allocating memory that is tricky to free later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) u32 crc_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) memset(m_filter, 0, AX_MCAST_FLTSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) netdev_for_each_mc_addr(ha, net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) *(m_filter + (crc_bits >> 3)) |= (1 << (crc_bits & 7));
^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) ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_MULFLTARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) AX_MCAST_FLTSIZE, AX_MCAST_FLTSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) m_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) data->rxctl |= AX_RX_CTL_AM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_RX_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 2, 2, &data->rxctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ax88179_set_features(struct net_device *net, netdev_features_t features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) netdev_features_t changed = net->features ^ features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (changed & NETIF_F_IP_CSUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) tmp ^= AX_TXCOE_TCP | AX_TXCOE_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (changed & NETIF_F_IPV6_CSUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) tmp ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (changed & NETIF_F_RXCSUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) tmp ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) static int ax88179_change_mtu(struct net_device *net, int new_mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) net->mtu = new_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) dev->hard_mtu = net->mtu + net->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (net->mtu > 1500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) tmp16 |= AX_MEDIUM_JUMBO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) tmp16 &= ~AX_MEDIUM_JUMBO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* max qlen depend on hard_mtu and rx_urb_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) usbnet_update_max_qlen(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static int ax88179_set_mac_addr(struct net_device *net, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct sockaddr *addr = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (netif_running(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (!is_valid_ether_addr(addr->sa_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) /* Set the MAC address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ETH_ALEN, net->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static const struct net_device_ops ax88179_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .ndo_open = usbnet_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .ndo_stop = usbnet_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .ndo_start_xmit = usbnet_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .ndo_tx_timeout = usbnet_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .ndo_get_stats64 = usbnet_get_stats64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .ndo_change_mtu = ax88179_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .ndo_set_mac_address = ax88179_set_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .ndo_do_ioctl = ax88179_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .ndo_set_rx_mode = ax88179_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .ndo_set_features = ax88179_set_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static int ax88179_check_eeprom(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) u8 i, buf, eeprom[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) u16 csum, delay = HZ / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unsigned long jtimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) /* Read EEPROM content */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) for (i = 0; i < 6; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) buf = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 1, 1, &buf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) buf = EEP_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 1, 1, &buf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) jtimeout = jiffies + delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 1, 1, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (time_after(jiffies, jtimeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) } while (buf & EEP_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) __ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 2, 2, &eeprom[i * 2], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if ((i == 0) && (eeprom[0] == 0xFF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return -EINVAL;
^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) csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) csum = (csum >> 8) + (csum & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if ((csum + eeprom[10]) != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int ax88179_check_efuse(struct usbnet *dev, u16 *ledmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) u8 efuse[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) u16 csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (ax88179_read_cmd(dev, AX_ACCESS_EFUS, 0, 64, 64, efuse) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (*efuse == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) for (i = 0; i < 64; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) csum = csum + efuse[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) while (csum > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (csum != 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) *ledmode = (efuse[51] << 8) | efuse[52];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static int ax88179_convert_old_led(struct usbnet *dev, u16 *ledvalue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) u16 led;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /* Loaded the old eFuse LED Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x3C, 1, 2, &led) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) led >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) switch (led) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) case 0xFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) case 0xFE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) case 0xFD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) LED2_LINK_10 | LED_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) case 0xFC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) LED2_LINK_100 | LED2_LINK_10 | LED_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) *ledvalue = led;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return 0;
^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) static int ax88179_led_setting(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) u8 ledfd, value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) u16 tmp, ledact, ledlink, ledvalue = 0, delay = HZ / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) unsigned long jtimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) /* Check AX88179 version. UA1 or UA2*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ax88179_read_cmd(dev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (!(value & AX_SECLD)) { /* UA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) AX_GPIO_CTRL_GPIO1EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_GPIO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 1, 1, &value) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) /* Check EEPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (!ax88179_check_eeprom(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) value = 0x42;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 1, 1, &value) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) value = EEP_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 1, 1, &value) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) jtimeout = jiffies + delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 1, 1, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (time_after(jiffies, jtimeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) } while (value & EEP_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 1, 1, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ledvalue = (value << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 1, 1, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ledvalue |= value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /* load internal ROM for defaule setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ax88179_convert_old_led(dev, &ledvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) } else if (!ax88179_check_efuse(dev, &ledvalue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ax88179_convert_old_led(dev, &ledvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) ax88179_convert_old_led(dev, &ledvalue);
^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) tmp = GMII_PHY_PGSEL_EXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) GMII_PHY_PAGE_SELECT, 2, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) tmp = 0x2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) GMII_PHYPAGE, 2, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) GMII_LED_ACT, 2, &ledact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) GMII_LED_LINK, 2, &ledlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) ledact &= GMII_LED_ACTIVE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) ledlink &= GMII_LED_LINK_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (ledvalue & LED0_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ledact |= GMII_LED0_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (ledvalue & LED1_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) ledact |= GMII_LED1_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (ledvalue & LED2_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ledact |= GMII_LED2_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (ledvalue & LED0_LINK_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) ledlink |= GMII_LED0_LINK_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (ledvalue & LED1_LINK_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) ledlink |= GMII_LED1_LINK_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (ledvalue & LED2_LINK_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ledlink |= GMII_LED2_LINK_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (ledvalue & LED0_LINK_100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ledlink |= GMII_LED0_LINK_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (ledvalue & LED1_LINK_100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) ledlink |= GMII_LED1_LINK_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (ledvalue & LED2_LINK_100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) ledlink |= GMII_LED2_LINK_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (ledvalue & LED0_LINK_1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ledlink |= GMII_LED0_LINK_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (ledvalue & LED1_LINK_1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) ledlink |= GMII_LED1_LINK_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (ledvalue & LED2_LINK_1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) ledlink |= GMII_LED2_LINK_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) tmp = ledact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) GMII_LED_ACT, 2, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) tmp = ledlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) GMII_LED_LINK, 2, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) tmp = GMII_PHY_PGSEL_PAGE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) GMII_PHY_PAGE_SELECT, 2, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /* LED full duplex setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ledfd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (ledvalue & LED0_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) ledfd |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) else if ((ledvalue & LED0_USB3_MASK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) ledfd |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (ledvalue & LED1_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) ledfd |= 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) else if ((ledvalue & LED1_USB3_MASK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) ledfd |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (ledvalue & LED2_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) ledfd |= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) else if ((ledvalue & LED2_USB3_MASK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ledfd |= 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_LEDCTRL, 1, 1, &ledfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) return 0;
^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) static void ax88179_get_mac_addr(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) u8 mac[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) memset(mac, 0, sizeof(mac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /* Maybe the boot loader passed the MAC address via device tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (!eth_platform_get_mac_address(&dev->udev->dev, mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) netif_dbg(dev, ifup, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) "MAC address read from device tree");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ETH_ALEN, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) netif_dbg(dev, ifup, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) "MAC address read from ASIX chip");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (is_valid_ether_addr(mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) memcpy(dev->net->dev_addr, mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) netdev_info(dev->net, "invalid MAC address, using random\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) eth_hw_addr_random(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) dev->net->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) u8 buf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) u16 *tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) u8 *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) struct ethtool_eee eee_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) usbnet_get_endpoints(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) tmp16 = (u16 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) tmp = (u8 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) memset(ax179_data, 0, sizeof(*ax179_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) /* Power up ethernet PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) *tmp16 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /* Read MAC address from DTB or asix chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) ax88179_get_mac_addr(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) /* RX bulk configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) dev->rx_urb_size = 1024 * 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) *tmp = 0x34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) *tmp = 0x52;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) dev->net->netdev_ops = &ax88179_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) dev->net->ethtool_ops = &ax88179_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) dev->net->needed_headroom = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) dev->net->max_mtu = 4088;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* Initialize MII structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) dev->mii.dev = dev->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) dev->mii.mdio_read = ax88179_mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) dev->mii.mdio_write = ax88179_mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) dev->mii.phy_id_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) dev->mii.reg_num_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) dev->mii.phy_id = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) dev->mii.supports_gmii = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) /* Enable checksum offload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /* Configure RX control register => start operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) AX_MONITOR_MODE_RWMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) /* Configure default medium type => giga */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) AX_MEDIUM_GIGAMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) ax88179_led_setting(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) ax179_data->eee_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) ax179_data->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) ax88179_disable_eee(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) ax88179_ethtool_get_eee(dev, &eee_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) eee_data.advertised = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) ax88179_ethtool_set_eee(dev, &eee_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /* Restart autoneg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) mii_nway_restart(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) usbnet_link_change(dev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) /* Configure RX control register => stop operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) tmp16 = AX_RX_CTL_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) tmp16 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* Power down ethernet PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) tmp16 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* checksum error bit is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) (*pkt_hdr & AX_RXHDR_L4CSUM_ERR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) /* It must be a TCP or UDP packet with a valid checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_UDP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) skb->ip_summed = CHECKSUM_UNNECESSARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) struct sk_buff *ax_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) int pkt_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) u32 rx_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) u16 hdr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) u32 *pkt_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) /* At the end of the SKB, there's a header telling us how many packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * are bundled into this buffer and where we can find an array of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * per-packet metadata (which contains elements encoded into u16).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (skb->len < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) skb_trim(skb, skb->len - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) rx_hdr = get_unaligned_le32(skb_tail_pointer(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) pkt_cnt = (u16)rx_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) hdr_off = (u16)(rx_hdr >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (pkt_cnt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) /* Make sure that the bounds of the metadata array are inside the SKB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) * (and in front of the counter at the end).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (pkt_cnt * 2 + hdr_off > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) pkt_hdr = (u32 *)(skb->data + hdr_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) /* Packets must not overlap the metadata array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) skb_trim(skb, hdr_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) for (; ; pkt_cnt--, pkt_hdr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) u16 pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) le32_to_cpus(pkt_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) pkt_len = (*pkt_hdr >> 16) & 0x1fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (pkt_len > skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) /* Check CRC or runt packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) pkt_len >= 2 + ETH_HLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) bool last = (pkt_cnt == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) ax_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) ax_skb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (!ax_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) ax_skb->len = pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) /* Skip IP alignment pseudo header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) skb_pull(ax_skb, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) skb_set_tail_pointer(ax_skb, ax_skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) ax88179_rx_checksum(ax_skb, pkt_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) usbnet_skb_return(dev, ax_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) /* Trim this packet away from the SKB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (!skb_pull(skb, (pkt_len + 7) & 0xFFF8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) static struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) u32 tx_hdr1, tx_hdr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) int frame_size = dev->maxpacket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) int mss = skb_shinfo(skb)->gso_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) int headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) void *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) tx_hdr1 = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) tx_hdr2 = mss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (((skb->len + 8) % frame_size) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) tx_hdr2 |= 0x80008000; /* Enable padding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) headroom = skb_headroom(skb) - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if ((skb_header_cloned(skb) || headroom < 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) ptr = skb_push(skb, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) put_unaligned_le32(tx_hdr1, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) put_unaligned_le32(tx_hdr2, ptr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static int ax88179_link_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) u8 tmp[5], link_sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) u16 mode, tmp16, delay = HZ / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) u32 tmp32 = 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) unsigned long jtimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) jtimeout = jiffies + delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) while (tmp32 & 0x40000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) &ax179_data->rxctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /*link up, check the usb device control TX FIFO full or empty*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (time_after(jiffies, jtimeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) AX_MEDIUM_RXFLOW_CTRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 1, 1, &link_sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) GMII_PHY_PHYSR, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (!(tmp16 & GMII_PHY_PHYSR_LINK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (dev->net->mtu > 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) mode |= AX_MEDIUM_JUMBO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (link_sts & AX_USB_SS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) else if (link_sts & AX_USB_HS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) } else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) mode |= AX_MEDIUM_PS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (link_sts & (AX_USB_SS | AX_USB_HS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) /* RX bulk configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) dev->rx_urb_size = (1024 * (tmp[3] + 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (tmp16 & GMII_PHY_PHYSR_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) mode |= AX_MEDIUM_FULL_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 2, 2, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) ax179_data->eee_enabled = ax88179_chk_eee(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) netif_carrier_on(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) static int ax88179_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) u8 buf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) u16 *tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) u8 *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) struct ethtool_eee eee_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) tmp16 = (u16 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) tmp = (u8 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* Power up ethernet PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) *tmp16 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) /* Ethernet PHY Auto Detach*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) ax88179_auto_detach(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /* Read MAC address from DTB or asix chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) ax88179_get_mac_addr(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /* RX bulk configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) dev->rx_urb_size = 1024 * 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) *tmp = 0x34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) *tmp = 0x52;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /* Enable checksum offload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) /* Configure RX control register => start operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) AX_MONITOR_MODE_RWMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) /* Configure default medium type => giga */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) AX_MEDIUM_GIGAMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 2, 2, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) ax88179_led_setting(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) ax179_data->eee_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) ax179_data->eee_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) ax88179_disable_eee(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) ax88179_ethtool_get_eee(dev, &eee_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) eee_data.advertised = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) ax88179_ethtool_set_eee(dev, &eee_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) /* Restart autoneg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) mii_nway_restart(&dev->mii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) usbnet_link_change(dev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) static int ax88179_stop(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 2, 2, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) static const struct driver_info ax88179_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) .description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) static const struct driver_info ax88178a_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) .description = "ASIX AX88178A USB 2.0 Gigabit Ethernet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) static const struct driver_info cypress_GX3_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .description = "Cypress GX3 SuperSpeed to Gigabit Ethernet Controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) static const struct driver_info dlink_dub1312_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) .description = "D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) static const struct driver_info sitecom_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) .description = "Sitecom USB 3.0 to Gigabit Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) static const struct driver_info samsung_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) .description = "Samsung USB Ethernet Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) static const struct driver_info lenovo_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) .description = "Lenovo OneLinkDock Gigabit LAN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) static const struct driver_info belkin_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) .description = "Belkin USB Ethernet Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) static const struct driver_info toshiba_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) .description = "Toshiba USB Ethernet Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) static const struct driver_info mct_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) .description = "MCT USB 3.0 Gigabit Ethernet Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) .bind = ax88179_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) .unbind = ax88179_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) .status = ax88179_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) .link_reset = ax88179_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) .reset = ax88179_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) .stop = ax88179_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) .flags = FLAG_ETHER | FLAG_FRAMING_AX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) .rx_fixup = ax88179_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) .tx_fixup = ax88179_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static const struct usb_device_id products[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) /* ASIX AX88179 10/100/1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) USB_DEVICE(0x0b95, 0x1790),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) .driver_info = (unsigned long)&ax88179_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) /* ASIX AX88178A 10/100/1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) USB_DEVICE(0x0b95, 0x178a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) .driver_info = (unsigned long)&ax88178a_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) /* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) USB_DEVICE(0x04b4, 0x3610),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) .driver_info = (unsigned long)&cypress_GX3_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) /* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) USB_DEVICE(0x2001, 0x4a00),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) .driver_info = (unsigned long)&dlink_dub1312_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) /* Sitecom USB 3.0 to Gigabit Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) USB_DEVICE(0x0df6, 0x0072),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) .driver_info = (unsigned long)&sitecom_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /* Samsung USB Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) USB_DEVICE(0x04e8, 0xa100),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) .driver_info = (unsigned long)&samsung_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) /* Lenovo OneLinkDock Gigabit LAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) USB_DEVICE(0x17ef, 0x304b),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) .driver_info = (unsigned long)&lenovo_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /* Belkin B2B128 USB 3.0 Hub + Gigabit Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) USB_DEVICE(0x050d, 0x0128),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) .driver_info = (unsigned long)&belkin_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) /* Toshiba USB 3.0 GBit Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) USB_DEVICE(0x0930, 0x0a13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) .driver_info = (unsigned long)&toshiba_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) /* Magic Control Technology U3-A9003 USB 3.0 Gigabit Ethernet Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) USB_DEVICE(0x0711, 0x0179),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) .driver_info = (unsigned long)&mct_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) MODULE_DEVICE_TABLE(usb, products);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) static struct usb_driver ax88179_178a_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) .name = "ax88179_178a",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) .id_table = products,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) .probe = usbnet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) .suspend = ax88179_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) .resume = ax88179_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) .reset_resume = ax88179_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) .disconnect = usbnet_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) .supports_autosuspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) .disable_hub_initiated_lpm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) module_usb_driver(ax88179_178a_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) MODULE_LICENSE("GPL");