/* SPDX-License-Identifier: GPL-2.0 */ /******************************************************************************* * Copyright (c) 2022 ASIX Electronic Corporation All rights reserved. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details * * You should have received a copy of the GNU General Public License along with * this program. If not, see . ******************************************************************************/ #ifndef __ASIX_MAIN_H #define __ASIX_MAIN_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ax_ioctl.h" #define napi_alloc_skb(napi, length) netdev_alloc_skb_ip_align(netdev, length) #define napi_complete_done(n, d) napi_complete(n) typedef int (*_usb_read_function)(struct ax_device *dev, u8 cmd, u8 reqtype, u16 value, u16 index, void *data, u16 size); typedef int (*_usb_write_function)(struct ax_device *dev, u8 cmd, u8 reqtype, u16 value, u16 index, const void *data, u16 size); typedef int (*usb_read_function)(struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data, int eflag); typedef int (*usb_write_function)(struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data); #define USB_VENDOR_ID_ASIX 0x0B95 #define USB_VENDOR_ID_SITECOM 0x0DF6 #define USB_VENDOR_ID_LENOVO 0x17EF #define USB_VENDOR_ID_TOSHIBA 0x0930 #define USB_VENDOR_ID_SAMSUNG 0x04E8 #define USB_VENDOR_ID_DLINK 0x2001 #define USB_VENDOR_ID_MAGIC_CONTROL 0x0711 #define AX_DEVICE_ID_179X 0x1790 #define AX_BCDDEVICE_ID_179 0x0100 #define AX_BCDDEVICE_ID_179A 0x0200 #define AX_DEVICE_ID_178A 0x178A #define AX_BCDDEVICE_ID_178A 0x0100 #define AX_DEVICE_ID_772D AX_DEVICE_ID_179X #define AX_BCDDEVICE_ID_772D 0x0300 #define AX_DRIVER_STRING_179_178A \ "ASIX AX88179_178A USB Ethernet Controller" #define AX_DRIVER_STRING_179A_772D \ "ASIX AX88179A_772D USB Ethernet Controller" #define DRIVER_VERSION "1.0.0" #define DRIVER_AUTHOR "ASIX" #define DRIVER_DESC "ASIX USB Ethernet Controller" #define MODULENAME "ax_usb_nic" #define AX88179_MAX_TX 4 #define AX88179_MAX_RX 10 #define AX88179_BUF_TX_SIZE (48 * 1024) #define AX_GSO_DEFAULT_SIZE (15 * 1024) #define INTBUFSIZE 8 #define TX_ALIGN 4 #define RX_ALIGN 8 #define TX_CASECADES_SIZE AX_GSO_DEFAULT_SIZE #define AX_TX_HEADER_LEN 8 #define AX_TX_TIMEOUT (5 * HZ) #define AX_MCAST_FILTER_SIZE 8 #define AX_MAX_MCAST 64 #define AX_TX_QUEUE_SIZE 1 #define US_TO_NS 1000 #define AX_ACCESS_MAC 0x01 #define AX_ACCESS_PHY 0x02 #define AX_ACCESS_WAKEUP 0x03 #define AX_ACCESS_EEPROM 0x04 #define AX_ACCESS_EFUSE 0x05 #define AX_RELOAD_EEPROM_EFUSE 0x06 #define AX_RELOAD_FLASH_EFUSE 0x06 #define AX_FW_MODE 0x08 #define AX_FW_MODE_179A 0x0001 #define AX_USB_EP5_EN 0x0001 #define AX_WRITE_EFUSE_EN 0x09 #define AX_WRITE_EFUSE_DIS 0x0A #define AX_ACCESS_MFAB 0x10 #define AX_PHY_POLLING 0x90 #define PHYSICAL_LINK_STATUS 0x02 #define AX_USB_SS 0x04 #define AX_USB_HS 0x02 #define AX_USB_FS 0x01 #define GENERAL_STATUS 0x03 #define AX_SECLD 0x04 #define AX_CHIP_STATUS 0x05 #define AX_CHIP_CODE_MASK 0x70 #define CHIP_CODE(x) (((x) & AX_CHIP_CODE_MASK) >> 4) #define AX_SROM_ADDR 0x07 #define AX_SROM_CMD 0x0a #define EEP_RD 0x04 #define EEP_WR 0x08 #define EEP_BUSY 0x10 #define AX_SROM_DATA_LOW 0x08 #define AX_SROM_DATA_HIGH 0x09 #define AX_RX_CTL 0x0b #define AX_RX_CTL_HI 0x0c #define AX_RX_CTL_DROPCRCERR_HI 0x01 #define AX_RX_CTL_DROPCRCERR 0x0100 #define AX_RX_CTL_IPE 0x0200 #define AX_RX_CTL_TXPADCRC 0x0400 #define AX_RX_CTL_START 0x0080 #define AX_RX_CTL_AP 0x0020 #define AX_RX_CTL_AM 0x0010 #define AX_RX_CTL_AB 0x0008 #define AX_RX_CTL_HA8B 0x0004 #define AX_RX_CTL_AMALL 0x0002 #define AX_RX_CTL_PRO 0x0001 #define AX_RX_CTL_STOP 0x0000 #define AX_NODE_ID 0x10 #define AX_MULTI_FILTER_ARRY 0x16 #define AX_MEDIUM_STATUS_MODE 0x22 #define AX_MEDIUM_GIGAMODE 0x0001 #define AX_MEDIUM_FULL_DUPLEX 0x0002 #define AX_MEDIUM_RXFLOW_CTRLEN 0x0010 #define AX_MEDIUM_TXFLOW_CTRLEN 0x0020 #define AX_MEDIUM_RECEIVE_EN 0x0100 #define AX_MEDIUM_PS 0x0200 #define AX_MEDIUM_JUMBO_EN 0x8040 #define AX_MONITOR_MODE 0x24 #define AX_MONITOR_MODE_RWLC 0x02 #define AX_MONITOR_MODE_RWMP 0x04 #define AX_MONITOR_MODE_RWWF 0x08 #define AX_MONITOR_MODE_RW_FLAG 0x10 #define AX_MONITOR_MODE_PMEPOL 0x20 #define AX_MONITOR_MODE_PMETYPE 0x40 #define AX_GPIO_CTRL 0x25 #define AX_GPIO_CTRL_GPIO3EN 0x80 #define AX_GPIO_CTRL_GPIO2EN 0x40 #define AX_GPIO_CTRL_GPIO1EN 0x20 #define AX_PHYPWR_RSTCTL 0x26 #define AX_PHYPWR_RSTCTL_BZ 0x0010 #define AX_PHYPWR_RSTCTL_IPRL 0x0020 #define AX_PHYPWR_RSTCTL_AUTODETACH 0x1000 #define AX_RX_BULKIN_QCTRL 0x2e #define AX_RX_BULKIN_QCTRL_TIME 0x01 #define AX_RX_BULKIN_QCTRL_IFG 0x02 #define AX_RX_BULKIN_QCTRL_SIZE 0x04 #define AX_RX_BULKIN_QTIMR_LOW 0x2f #define AX_RX_BULKIN_QTIMR_HIGH 0x30 #define AX_RX_BULKIN_QSIZE 0x31 #define AX_RX_BULKIN_QIFG 0x32 #define AX_CLK_SELECT 0x33 #define AX_CLK_SELECT_BCS 0x01 #define AX_CLK_SELECT_ACS 0x02 #define AX_CLK_SELECT_ACSREQ 0x10 #define AX_CLK_SELECT_ULR 0x08 #define AX_RXCOE_CTL 0x34 #define AX_RXCOE_IP 0x01 #define AX_RXCOE_TCP 0x02 #define AX_RXCOE_UDP 0x04 #define AX_RXCOE_ICMP 0x08 #define AX_RXCOE_IGMP 0x10 #define AX_RXCOE_TCPV6 0x20 #define AX_RXCOE_UDPV6 0x40 #define AX_RXCOE_ICMV6 0x80 #define AX_RXCOE_DEF_CSUM (AX_RXCOE_IP | AX_RXCOE_TCP | \ AX_RXCOE_UDP | AX_RXCOE_ICMV6 | \ AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6) #define AX_TXCOE_CTL 0x35 #define AX_TXCOE_IP 0x01 #define AX_TXCOE_TCP 0x02 #define AX_TXCOE_UDP 0x04 #define AX_TXCOE_ICMP 0x08 #define AX_TXCOE_IGMP 0x10 #define AX_TXCOE_TCPV6 0x20 #define AX_TXCOE_UDPV6 0x40 #define AX_TXCOE_ICMV6 0x80 #define AX_TXCOE_DEF_CSUM (AX_TXCOE_TCP | AX_TXCOE_UDP | \ AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6) #define AX_PAUSE_WATERLVL_HIGH 0x54 #define AX_PAUSE_WATERLVL_LOW 0x55 #define AX_RX_FREE_BUF_LOW 0x57 #define GMII_PHY_CONTROL 0x00 #define GMII_CONTROL_RESET 0x8000 #define GMII_CONTROL_LOOPBACK 0x4000 #define GMII_CONTROL_10MB 0x0000 #define GMII_CONTROL_100MB 0x2000 #define GMII_CONTROL_1000MB 0x0040 #define GMII_CONTROL_SPEED_BITS 0x2040 #define GMII_CONTROL_ENABLE_AUTO 0x1000 #define GMII_CONTROL_POWER_DOWN 0x0800 #define GMII_CONTROL_ISOLATE 0x0400 #define GMII_CONTROL_START_AUTO 0x0200 #define GMII_CONTROL_FULL_DUPLEX 0x0100 #define GMII_PHY_STATUS 0x01 #define GMII_STATUS_100MB_MASK 0xE000 #define GMII_STATUS_10MB_MASK 0x1800 #define GMII_STATUS_AUTO_DONE 0x0020 #define GMII_STATUS_AUTO 0x0008 #define GMII_STATUS_LINK_UP 0x0004 #define GMII_STATUS_EXTENDED 0x0001 #define GMII_STATUS_100T4 0x8000 #define GMII_STATUS_100TXFD 0x4000 #define GMII_STATUS_100TX 0x2000 #define GMII_STATUS_10TFD 0x1000 #define GMII_STATUS_10T 0x0800 #define GMII_PHY_OUI 0x02 #define GMII_PHY_MODEL 0x03 #define GMII_PHY_ANAR 0x04 #define GMII_ANAR_ASYM_PAUSE 0x0800 #define GMII_ANAR_PAUSE 0x0400 #define GMII_ANAR_100T4 0x0200 #define GMII_ANAR_100TXFD 0x0100 #define GMII_ANAR_100TX 0x0080 #define GMII_ANAR_10TFD 0x0040 #define GMII_ANAR_10T 0x0020 #define GMII_SELECTOR_FIELD 0x001F #define GMII_PHY_ANLPAR 0x05 #define GMII_ANLPAR_100T4 0x0200 #define GMII_ANLPAR_100TXFD 0x0100 #define GMII_ANLPAR_100TX 0x0080 #define GMII_ANLPAR_10TFD 0x0040 #define GMII_ANLPAR_10T 0x0020 #define GMII_ANLPAR_PAUSE 0x0400 #define GMII_ANLPAR_ASYM_PAUSE 0x0800 #define GMII_ANLPAR_ACK 0x4000 #define GMII_SELECTOR_8023 0x0001 #define GMII_PHY_ANER 0x06 #define GMII_PHY_1000BT_CONTROL 0x09 #define GMII_PHY_1000BT_STATUS 0x0A #define GMII_PHY_MACR 0x0D #define GMII_PHY_MAADR 0x0E #define GMII_PHY_PHYSR 0x11 #define GMII_PHY_PHYSR_SMASK 0xc000 #define GMII_PHY_PHYSR_GIGA 0x8000 #define GMII_PHY_PHYSR_100 0x4000 #define GMII_PHY_PHYSR_FULL 0x2000 #define GMII_PHY_PHYSR_LINK 0x400 #define GMII_1000_AUX_CTRL_MASTER_SLAVE 0x1000 #define GMII_1000_AUX_CTRL_FD_CAPABLE 0x0200 #define GMII_1000_AUX_CTRL_HD_CAPABLE 0x0100 #define GMII_1000_AUX_STATUS_FD_CAPABLE 0x0800 #define GMII_1000_AUX_STATUS_HD_CAPABLE 0x0400 #define GMII_AUX_CTRL_STATUS 0x1C #define GMII_AUX_ANEG_CPLT 0x8000 #define GMII_AUX_FDX 0x0020 #define GMII_AUX_SPEED_1000 0x0010 #define GMII_AUX_SPEED_100 0x0008 #define GMII_LED_ACTIVE 0x1a #define GMII_LED_ACTIVE_MASK 0xff8f #define GMII_LED0_ACTIVE BIT(4) #define GMII_LED1_ACTIVE BIT(5) #define GMII_LED2_ACTIVE BIT(6) #define GMII_LED_LINK 0x1c #define GMII_LED_LINK_MASK 0xf888 #define GMII_LED0_LINK_10 BIT(0) #define GMII_LED0_LINK_100 BIT(1) #define GMII_LED0_LINK_1000 BIT(2) #define GMII_LED1_LINK_10 BIT(4) #define GMII_LED1_LINK_100 BIT(5) #define GMII_LED1_LINK_1000 BIT(6) #define GMII_LED2_LINK_10 BIT(8) #define GMII_LED2_LINK_100 BIT(9) #define GMII_LED2_LINK_1000 BIT(10) #define LED_VALID BIT(15) #define LED0_ACTIVE BIT(0) #define LED0_LINK_10 BIT(1) #define LED0_LINK_100 BIT(2) #define LED0_LINK_1000 BIT(3) #define LED0_FD BIT(4) #define LED0_USB3_MASK 0x001f #define LED1_ACTIVE BIT(5) #define LED1_LINK_10 BIT(6) #define LED1_LINK_100 BIT(7) #define LED1_LINK_1000 BIT(8) #define LED1_FD BIT(9) #define LED1_USB3_MASK 0x03e0 #define LED2_ACTIVE BIT(10) #define LED2_LINK_1000 BIT(13) #define LED2_LINK_100 BIT(12) #define LED2_LINK_10 BIT(11) #define LED2_FD BIT(14) #define LED2_USB3_MASK 0x7c00 #define GMII_PHYPAGE 0x1e #define GMII_PHY_PAGE_SELECT 0x1f #define GMII_PHY_PAGE_SELECT_EXT 0x0007 #define GMII_PHY_PAGE_SELECT_PAGE0 0X0000 #define GMII_PHY_PAGE_SELECT_PAGE1 0X0001 #define GMII_PHY_PAGE_SELECT_PAGE2 0X0002 #define GMII_PHY_PAGE_SELECT_PAGE3 0X0003 #define GMII_PHY_PAGE_SELECT_PAGE4 0X0004 #define GMII_PHY_PAGE_SELECT_PAGE5 0X0005 #define GMII_PHY_PAGE_SELECT_PAGE6 0X0006 enum ax_driver_flags { AX_UNPLUG = 0, AX_ENABLE, AX_LINK_CHG, AX_SELECTIVE_SUSPEND, AX_SCHEDULE_NAPI, }; enum ax_chip_version { AX_VERSION_INVALID = 0, AX_VERSION_AX88179 = 4, AX_VERSION_AX88179A_772D = 6, }; struct ax_device; struct rx_desc { struct list_head list; struct urb *urb; struct ax_device *context; void *buffer; void *head; }; enum __ax_tx_flags { AX_TX_NONE = 0, AX_TX_TIMESTAMPS = 1, }; enum __mac_pass_ctrl { MAC_PASS_DISABLED = 0, MAC_PASS_ENABLE_0 = 1, MAC_PASS_ENABLE_1 = 2, }; struct mac_pass { u8 control; u8 mac0[8]; u8 mac1[8]; } __packed; struct tx_desc { struct list_head list; struct urb *urb; struct ax_device *context; void *buffer; void *head; u32 skb_num; u32 skb_len; unsigned long flags; int q_index; }; struct ax_bulkin_setting { u8 custom; u8 bulkin_setting[5]; }; enum ax_ether_link_speed { ETHER_LINK_NONE = 0, ETHER_LINK_10 = 1, ETHER_LINK_100 = 2, ETHER_LINK_1000 = 3, ETHER_LINK_2500 = 4, }; struct ax_link_info { u8 eth_speed : 3, full_duplex : 1, usb_speed : 4; } __packed; struct ax_device { unsigned long flags; struct usb_device *udev; struct usb_interface *intf; struct net_device *netdev; const struct driver_info *driver_info; struct napi_struct napi; struct urb *intr_urb; struct tx_desc tx_list[32]; struct rx_desc rx_list[32]; struct list_head rx_done, tx_free; struct sk_buff_head tx_queue[AX_TX_QUEUE_SIZE]; struct sk_buff_head rx_queue; spinlock_t rx_lock, tx_lock; struct delayed_work schedule, hw_phy_work; struct mii_if_info mii; struct mutex control; /* protects device */ int intr_interval; u32 saved_wolopts; u32 msg_enable; u32 tx_qlen; u32 coalesce; u16 speed; u8 *intr_buff; u8 tx_align_len; u8 link; u16 rxctl; u8 m_filter[8]; u32 tx_casecade_size; u32 gso_max_size; u8 fw_version[4]; struct ax_link_info link_info; struct ax_link_info intr_link_info; u8 eee_enabled; u8 eee_active; int autodetach; struct ax_bulkin_setting bin_setting; bool tx_header_cksum; unsigned char chip_version; unsigned char sub_version; #define AX_ETH_SPEED_MASK 0xF #define AX_ETH_DUPLEX_FULL 0x10 u8 int_link_info; u64 bulkin_complete; u64 bulkin_error; u64 bulkout_complete; u64 bulkout_error; u64 bulkint_complete; u64 bulkint_error; }; struct driver_info { int (*bind)(struct ax_device *axdev); void (*unbind)(struct ax_device *axdev); int (*hw_init)(struct ax_device *axdev); int (*stop)(struct ax_device *axdev); void (*rx_fixup)(struct ax_device *axdev, struct rx_desc *desc, int *work_done, int budget); int (*tx_fixup)(struct ax_device *axdev, struct tx_desc *desc); int (*link_reset)(struct ax_device *axdev); int (*system_suspend)(struct ax_device *axdev); int (*system_resume)(struct ax_device *axdev); unsigned long napi_weight; size_t buf_rx_size; }; struct _async_cmd_handle { struct ax_device *axdev; struct usb_ctrlrequest *req; u8 m_filter[8]; u16 rxctl; } __packed; struct ax_device_int_data { u8 res1; struct ax_link_info link_info; #define AX_INT_PPLS_LINK BIT(0) #define AX_INT_SPLS_LINK BIT(1) #define AX_INT_CABOFF_UNPLUG BIT(7) u8 link; __le16 res2; u8 status; __le16 res3; } __packed; struct _ax_buikin_setting { u8 ctrl; u8 timer_l; u8 timer_h; u8 size; u8 ifg; } __packed; #define AX_RXHDR_L4_ERR BIT(8) #define AX_RXHDR_L3_ERR BIT(9) #define AX_RXHDR_L4_TYPE_ICMP 2 #define AX_RXHDR_L4_TYPE_IGMP 3 #define AX_RXHDR_L4_TYPE_TCMPV6 5 #define AX_RXHDR_L3_TYPE_IP 1 #define AX_RXHDR_L3_TYPE_IPV6 2 #define AX_RXHDR_L4_TYPE_MASK 0x1c #define AX_RXHDR_L4_TYPE_UDP 4 #define AX_RXHDR_L4_TYPE_TCP 16 #define AX_RXHDR_L3CSUM_ERR 2 #define AX_RXHDR_L4CSUM_ERR 1 #define AX_RXHDR_CRC_ERR 0x20000000 #define AX_RXHDR_MII_ERR 0x40000000 #define AX_RXHDR_DROP_ERR 0x80000000 int ax_check_ether_addr(struct ax_device *axdev); int ax_get_mac_pass(struct ax_device *axdev, u8 *mac); void ax_set_tx_qlen(struct ax_device *dev); inline void *__rx_buf_align(void *data); inline void *__tx_buf_align(void *data, u8 tx_align_len); inline struct net_device_stats *ax_get_stats(struct net_device *dev); void ax_write_bulk_callback(struct urb *urb); void ax_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info); int ax_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd); int ax_set_link_ksettings(struct net_device *netdev, const struct ethtool_link_ksettings *cmd); u32 ax_get_msglevel(struct net_device *netdev); void ax_set_msglevel(struct net_device *netdev, u32 value); void ax_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); int ax_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); int ax_get_sset_count(struct net_device *dev, int sset); void ax_get_ethtool_stats (struct net_device *dev, struct ethtool_stats *stats, u64 *data); void ax_get_strings(struct net_device *netdev, u32 stringset, u8 *data); void ax_get_pauseparam (struct net_device *netdev, struct ethtool_pauseparam *pause); int ax_set_pauseparam (struct net_device *netdev, struct ethtool_pauseparam *pause); int ax_get_regs_len(struct net_device *netdev); void ax_get_regs (struct net_device *netdev, struct ethtool_regs *regs, void *buf); int ax_read_cmd (struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data, int eflag); int ax_write_cmd (struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data); int ax_read_cmd_nopm (struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data, int eflag); int ax_write_cmd_nopm (struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data); int ax_write_cmd_async (struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data); int ax_mmd_read(struct net_device *netdev, int dev_addr, int reg); void ax_mmd_write(struct net_device *netdev, int dev_addr, int reg, int val); int ax_mdio_read(struct net_device *netdev, int phy_id, int reg); void ax_mdio_write(struct net_device *netdev, int phy_id, int reg, int val); int ax_usb_command(struct ax_device *axdev, struct _ax_ioctl_command *info); void ax_print_version(struct ax_device *axdev, const char *str); #endif /* __ASIX_MAIN_H */