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