162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ASIX AX8817X based USB 2.0 Ethernet Devices 462306a36Sopenharmony_ci * Copyright (C) 2003-2006 David Hollis <dhollis@davehollis.com> 562306a36Sopenharmony_ci * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net> 662306a36Sopenharmony_ci * Copyright (C) 2006 James Painter <jamie.painter@iname.com> 762306a36Sopenharmony_ci * Copyright (c) 2002-2003 TiVo Inc. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef _ASIX_H 1162306a36Sopenharmony_ci#define _ASIX_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci// #define DEBUG // error path messages, extra info 1462306a36Sopenharmony_ci// #define VERBOSE // more; success messages 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/module.h> 1762306a36Sopenharmony_ci#include <linux/kmod.h> 1862306a36Sopenharmony_ci#include <linux/netdevice.h> 1962306a36Sopenharmony_ci#include <linux/etherdevice.h> 2062306a36Sopenharmony_ci#include <linux/ethtool.h> 2162306a36Sopenharmony_ci#include <linux/workqueue.h> 2262306a36Sopenharmony_ci#include <linux/mii.h> 2362306a36Sopenharmony_ci#include <linux/usb.h> 2462306a36Sopenharmony_ci#include <linux/crc32.h> 2562306a36Sopenharmony_ci#include <linux/usb/usbnet.h> 2662306a36Sopenharmony_ci#include <linux/slab.h> 2762306a36Sopenharmony_ci#include <linux/if_vlan.h> 2862306a36Sopenharmony_ci#include <linux/phy.h> 2962306a36Sopenharmony_ci#include <net/selftests.h> 3062306a36Sopenharmony_ci#include <linux/phylink.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define DRIVER_VERSION "22-Dec-2011" 3362306a36Sopenharmony_ci#define DRIVER_NAME "asix" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* ASIX AX8817X based USB 2.0 Ethernet Devices */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#define AX_CMD_SET_SW_MII 0x06 3862306a36Sopenharmony_ci#define AX_CMD_READ_MII_REG 0x07 3962306a36Sopenharmony_ci#define AX_CMD_WRITE_MII_REG 0x08 4062306a36Sopenharmony_ci#define AX_CMD_STATMNGSTS_REG 0x09 4162306a36Sopenharmony_ci#define AX_CMD_SET_HW_MII 0x0a 4262306a36Sopenharmony_ci#define AX_CMD_READ_EEPROM 0x0b 4362306a36Sopenharmony_ci#define AX_CMD_WRITE_EEPROM 0x0c 4462306a36Sopenharmony_ci#define AX_CMD_WRITE_ENABLE 0x0d 4562306a36Sopenharmony_ci#define AX_CMD_WRITE_DISABLE 0x0e 4662306a36Sopenharmony_ci#define AX_CMD_READ_RX_CTL 0x0f 4762306a36Sopenharmony_ci#define AX_CMD_WRITE_RX_CTL 0x10 4862306a36Sopenharmony_ci#define AX_CMD_READ_IPG012 0x11 4962306a36Sopenharmony_ci#define AX_CMD_WRITE_IPG0 0x12 5062306a36Sopenharmony_ci#define AX_CMD_WRITE_IPG1 0x13 5162306a36Sopenharmony_ci#define AX_CMD_READ_NODE_ID 0x13 5262306a36Sopenharmony_ci#define AX_CMD_WRITE_NODE_ID 0x14 5362306a36Sopenharmony_ci#define AX_CMD_WRITE_IPG2 0x14 5462306a36Sopenharmony_ci#define AX_CMD_WRITE_MULTI_FILTER 0x16 5562306a36Sopenharmony_ci#define AX88172_CMD_READ_NODE_ID 0x17 5662306a36Sopenharmony_ci#define AX_CMD_READ_PHY_ID 0x19 5762306a36Sopenharmony_ci#define AX_CMD_READ_MEDIUM_STATUS 0x1a 5862306a36Sopenharmony_ci#define AX_CMD_WRITE_MEDIUM_MODE 0x1b 5962306a36Sopenharmony_ci#define AX_CMD_READ_MONITOR_MODE 0x1c 6062306a36Sopenharmony_ci#define AX_CMD_WRITE_MONITOR_MODE 0x1d 6162306a36Sopenharmony_ci#define AX_CMD_READ_GPIOS 0x1e 6262306a36Sopenharmony_ci#define AX_CMD_WRITE_GPIOS 0x1f 6362306a36Sopenharmony_ci#define AX_CMD_SW_RESET 0x20 6462306a36Sopenharmony_ci#define AX_CMD_SW_PHY_STATUS 0x21 6562306a36Sopenharmony_ci#define AX_CMD_SW_PHY_SELECT 0x22 6662306a36Sopenharmony_ci#define AX_QCTCTRL 0x2A 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#define AX_CHIPCODE_MASK 0x70 6962306a36Sopenharmony_ci#define AX_AX88772_CHIPCODE 0x00 7062306a36Sopenharmony_ci#define AX_AX88772A_CHIPCODE 0x10 7162306a36Sopenharmony_ci#define AX_AX88772B_CHIPCODE 0x20 7262306a36Sopenharmony_ci#define AX_HOST_EN 0x01 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci#define AX_PHYSEL_PSEL 0x01 7562306a36Sopenharmony_ci#define AX_PHYSEL_SSMII 0 7662306a36Sopenharmony_ci#define AX_PHYSEL_SSEN 0x10 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#define AX_PHY_SELECT_MASK (BIT(3) | BIT(2)) 7962306a36Sopenharmony_ci#define AX_PHY_SELECT_INTERNAL 0 8062306a36Sopenharmony_ci#define AX_PHY_SELECT_EXTERNAL BIT(2) 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#define AX_MONITOR_MODE 0x01 8362306a36Sopenharmony_ci#define AX_MONITOR_LINK 0x02 8462306a36Sopenharmony_ci#define AX_MONITOR_MAGIC 0x04 8562306a36Sopenharmony_ci#define AX_MONITOR_HSFS 0x10 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* AX88172 Medium Status Register values */ 8862306a36Sopenharmony_ci#define AX88172_MEDIUM_FD 0x02 8962306a36Sopenharmony_ci#define AX88172_MEDIUM_TX 0x04 9062306a36Sopenharmony_ci#define AX88172_MEDIUM_FC 0x10 9162306a36Sopenharmony_ci#define AX88172_MEDIUM_DEFAULT \ 9262306a36Sopenharmony_ci ( AX88172_MEDIUM_FD | AX88172_MEDIUM_TX | AX88172_MEDIUM_FC ) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci#define AX_MCAST_FILTER_SIZE 8 9562306a36Sopenharmony_ci#define AX_MAX_MCAST 64 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define AX_SWRESET_CLEAR 0x00 9862306a36Sopenharmony_ci#define AX_SWRESET_RR 0x01 9962306a36Sopenharmony_ci#define AX_SWRESET_RT 0x02 10062306a36Sopenharmony_ci#define AX_SWRESET_PRTE 0x04 10162306a36Sopenharmony_ci#define AX_SWRESET_PRL 0x08 10262306a36Sopenharmony_ci#define AX_SWRESET_BZ 0x10 10362306a36Sopenharmony_ci#define AX_SWRESET_IPRL 0x20 10462306a36Sopenharmony_ci#define AX_SWRESET_IPPD 0x40 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci#define AX88772_IPG0_DEFAULT 0x15 10762306a36Sopenharmony_ci#define AX88772_IPG1_DEFAULT 0x0c 10862306a36Sopenharmony_ci#define AX88772_IPG2_DEFAULT 0x12 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* AX88772 & AX88178 Medium Mode Register */ 11162306a36Sopenharmony_ci#define AX_MEDIUM_PF 0x0080 11262306a36Sopenharmony_ci#define AX_MEDIUM_JFE 0x0040 11362306a36Sopenharmony_ci#define AX_MEDIUM_TFC 0x0020 11462306a36Sopenharmony_ci#define AX_MEDIUM_RFC 0x0010 11562306a36Sopenharmony_ci#define AX_MEDIUM_ENCK 0x0008 11662306a36Sopenharmony_ci#define AX_MEDIUM_AC 0x0004 11762306a36Sopenharmony_ci#define AX_MEDIUM_FD 0x0002 11862306a36Sopenharmony_ci#define AX_MEDIUM_GM 0x0001 11962306a36Sopenharmony_ci#define AX_MEDIUM_SM 0x1000 12062306a36Sopenharmony_ci#define AX_MEDIUM_SBP 0x0800 12162306a36Sopenharmony_ci#define AX_MEDIUM_PS 0x0200 12262306a36Sopenharmony_ci#define AX_MEDIUM_RE 0x0100 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#define AX88178_MEDIUM_DEFAULT \ 12562306a36Sopenharmony_ci (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \ 12662306a36Sopenharmony_ci AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \ 12762306a36Sopenharmony_ci AX_MEDIUM_RE) 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define AX88772_MEDIUM_DEFAULT \ 13062306a36Sopenharmony_ci (AX_MEDIUM_FD | AX_MEDIUM_PS | \ 13162306a36Sopenharmony_ci AX_MEDIUM_AC | AX_MEDIUM_RE) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci/* AX88772 & AX88178 RX_CTL values */ 13462306a36Sopenharmony_ci#define AX_RX_CTL_SO 0x0080 13562306a36Sopenharmony_ci#define AX_RX_CTL_AP 0x0020 13662306a36Sopenharmony_ci#define AX_RX_CTL_AM 0x0010 13762306a36Sopenharmony_ci#define AX_RX_CTL_AB 0x0008 13862306a36Sopenharmony_ci#define AX_RX_CTL_SEP 0x0004 13962306a36Sopenharmony_ci#define AX_RX_CTL_AMALL 0x0002 14062306a36Sopenharmony_ci#define AX_RX_CTL_PRO 0x0001 14162306a36Sopenharmony_ci#define AX_RX_CTL_MFB_2048 0x0000 14262306a36Sopenharmony_ci#define AX_RX_CTL_MFB_4096 0x0100 14362306a36Sopenharmony_ci#define AX_RX_CTL_MFB_8192 0x0200 14462306a36Sopenharmony_ci#define AX_RX_CTL_MFB_16384 0x0300 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#define AX_DEFAULT_RX_CTL (AX_RX_CTL_SO | AX_RX_CTL_AB) 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* GPIO 0 .. 2 toggles */ 14962306a36Sopenharmony_ci#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */ 15062306a36Sopenharmony_ci#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */ 15162306a36Sopenharmony_ci#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */ 15262306a36Sopenharmony_ci#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */ 15362306a36Sopenharmony_ci#define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */ 15462306a36Sopenharmony_ci#define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */ 15562306a36Sopenharmony_ci#define AX_GPIO_RESERVED 0x40 /* Reserved */ 15662306a36Sopenharmony_ci#define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */ 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci#define AX_EEPROM_MAGIC 0xdeadbeef 15962306a36Sopenharmony_ci#define AX_EEPROM_LEN 0x200 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci#define AX_EMBD_PHY_ADDR 0x10 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ 16462306a36Sopenharmony_cistruct asix_data { 16562306a36Sopenharmony_ci u8 multi_filter[AX_MCAST_FILTER_SIZE]; 16662306a36Sopenharmony_ci u8 mac_addr[ETH_ALEN]; 16762306a36Sopenharmony_ci u8 phymode; 16862306a36Sopenharmony_ci u8 ledmode; 16962306a36Sopenharmony_ci u8 res; 17062306a36Sopenharmony_ci}; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistruct asix_rx_fixup_info { 17362306a36Sopenharmony_ci struct sk_buff *ax_skb; 17462306a36Sopenharmony_ci u32 header; 17562306a36Sopenharmony_ci u16 remaining; 17662306a36Sopenharmony_ci bool split_head; 17762306a36Sopenharmony_ci}; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistruct asix_common_private { 18062306a36Sopenharmony_ci void (*resume)(struct usbnet *dev); 18162306a36Sopenharmony_ci void (*suspend)(struct usbnet *dev); 18262306a36Sopenharmony_ci int (*reset)(struct usbnet *dev, int in_pm); 18362306a36Sopenharmony_ci u16 presvd_phy_advertise; 18462306a36Sopenharmony_ci u16 presvd_phy_bmcr; 18562306a36Sopenharmony_ci struct asix_rx_fixup_info rx_fixup_info; 18662306a36Sopenharmony_ci struct mii_bus *mdio; 18762306a36Sopenharmony_ci struct phy_device *phydev; 18862306a36Sopenharmony_ci struct phy_device *phydev_int; 18962306a36Sopenharmony_ci struct phylink *phylink; 19062306a36Sopenharmony_ci struct phylink_config phylink_config; 19162306a36Sopenharmony_ci u16 phy_addr; 19262306a36Sopenharmony_ci bool embd_phy; 19362306a36Sopenharmony_ci u8 chipcode; 19462306a36Sopenharmony_ci}; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ciextern const struct driver_info ax88172a_info; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* ASIX specific flags */ 19962306a36Sopenharmony_ci#define FLAG_EEPROM_MAC (1UL << 0) /* init device MAC from eeprom */ 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ciint __must_check asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, 20262306a36Sopenharmony_ci u16 size, void *data, int in_pm); 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ciint asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, 20562306a36Sopenharmony_ci u16 size, void *data, int in_pm); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_civoid asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, 20862306a36Sopenharmony_ci u16 index, u16 size, void *data); 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciint asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb, 21162306a36Sopenharmony_ci struct asix_rx_fixup_info *rx); 21262306a36Sopenharmony_ciint asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb); 21362306a36Sopenharmony_civoid asix_rx_fixup_common_free(struct asix_common_private *dp); 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistruct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 21662306a36Sopenharmony_ci gfp_t flags); 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ciint asix_read_phy_addr(struct usbnet *dev, bool internal); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ciint asix_sw_reset(struct usbnet *dev, u8 flags, int in_pm); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ciu16 asix_read_rx_ctl(struct usbnet *dev, int in_pm); 22362306a36Sopenharmony_ciint asix_write_rx_ctl(struct usbnet *dev, u16 mode, int in_pm); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ciu16 asix_read_medium_status(struct usbnet *dev, int in_pm); 22662306a36Sopenharmony_ciint asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm); 22762306a36Sopenharmony_civoid asix_adjust_link(struct net_device *netdev); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ciint asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_civoid asix_set_multicast(struct net_device *net); 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ciint asix_mdio_read(struct net_device *netdev, int phy_id, int loc); 23462306a36Sopenharmony_civoid asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ciint asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum); 23762306a36Sopenharmony_ciint asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val); 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ciint asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc); 24062306a36Sopenharmony_civoid asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, 24162306a36Sopenharmony_ci int val); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_civoid asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); 24462306a36Sopenharmony_ciint asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ciint asix_get_eeprom_len(struct net_device *net); 24762306a36Sopenharmony_ciint asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, 24862306a36Sopenharmony_ci u8 *data); 24962306a36Sopenharmony_ciint asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, 25062306a36Sopenharmony_ci u8 *data); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_civoid asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ciint asix_set_mac_address(struct net_device *net, void *p); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci#endif /* _ASIX_H */ 257