Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'ax88796c-spi-ethernet-adapter'

Łukasz Stelmach says:

====================
AX88796C SPI Ethernet Adapter

This is a driver for AX88796C Ethernet Adapter connected in SPI mode as
found on ARTIK5 evaluation board. The driver has been ported from a
v3.10.9 vendor kernel for ARTIK5 board.
====================

Link: https://lore.kernel.org/r/20211020182422.362647-1-l.stelmach@samsung.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+2304
+73
Documentation/devicetree/bindings/net/asix,ax88796c.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/net/asix,ax88796c.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ASIX AX88796C SPI Ethernet Adapter 8 + 9 + maintainers: 10 + - Łukasz Stelmach <l.stelmach@samsung.com> 11 + 12 + description: | 13 + ASIX AX88796C is an Ethernet controller with a built in PHY. This 14 + describes SPI mode of the chip. 15 + 16 + The node for this driver must be a child node of an SPI controller, 17 + hence all mandatory properties described in 18 + ../spi/spi-controller.yaml must be specified. 19 + 20 + allOf: 21 + - $ref: ethernet-controller.yaml# 22 + 23 + properties: 24 + compatible: 25 + const: asix,ax88796c 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + spi-max-frequency: 31 + maximum: 40000000 32 + 33 + interrupts: 34 + maxItems: 1 35 + 36 + reset-gpios: 37 + description: 38 + A GPIO line handling reset of the chip. As the line is active low, 39 + it should be marked GPIO_ACTIVE_LOW. 40 + maxItems: 1 41 + 42 + local-mac-address: true 43 + 44 + mac-address: true 45 + 46 + required: 47 + - compatible 48 + - reg 49 + - spi-max-frequency 50 + - interrupts 51 + - reset-gpios 52 + 53 + additionalProperties: false 54 + 55 + examples: 56 + # Artik5 eval board 57 + - | 58 + #include <dt-bindings/interrupt-controller/irq.h> 59 + #include <dt-bindings/gpio/gpio.h> 60 + spi0 { 61 + #address-cells = <1>; 62 + #size-cells = <0>; 63 + 64 + ethernet@0 { 65 + compatible = "asix,ax88796c"; 66 + reg = <0x0>; 67 + local-mac-address = [00 00 00 00 00 00]; /* Filled in by a bootloader */ 68 + interrupt-parent = <&gpx2>; 69 + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; 70 + spi-max-frequency = <40000000>; 71 + reset-gpios = <&gpe0 2 GPIO_ACTIVE_LOW>; 72 + }; 73 + };
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 131 131 description: Asahi Kasei Corp. 132 132 "^asc,.*": 133 133 description: All Sensors Corporation 134 + "^asix,.*": 135 + description: ASIX Electronics Corporation 134 136 "^aspeed,.*": 135 137 description: ASPEED Technology Inc. 136 138 "^asus,.*":
+6
MAINTAINERS
··· 2899 2899 F: Documentation/hwmon/asc7621.rst 2900 2900 F: drivers/hwmon/asc7621.c 2901 2901 2902 + ASIX AX88796C SPI ETHERNET ADAPTER 2903 + M: Łukasz Stelmach <l.stelmach@samsung.com> 2904 + S: Maintained 2905 + F: Documentation/devicetree/bindings/net/asix,ax88796c.yaml 2906 + F: drivers/net/ethernet/asix/ax88796c_* 2907 + 2902 2908 ASPEED PINCTRL DRIVERS 2903 2909 M: Andrew Jeffery <andrew@aj.id.au> 2904 2910 L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
+1
drivers/net/ethernet/Kconfig
··· 33 33 source "drivers/net/ethernet/apple/Kconfig" 34 34 source "drivers/net/ethernet/aquantia/Kconfig" 35 35 source "drivers/net/ethernet/arc/Kconfig" 36 + source "drivers/net/ethernet/asix/Kconfig" 36 37 source "drivers/net/ethernet/atheros/Kconfig" 37 38 source "drivers/net/ethernet/broadcom/Kconfig" 38 39 source "drivers/net/ethernet/brocade/Kconfig"
+1
drivers/net/ethernet/Makefile
··· 19 19 obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ 20 20 obj-$(CONFIG_NET_VENDOR_AQUANTIA) += aquantia/ 21 21 obj-$(CONFIG_NET_VENDOR_ARC) += arc/ 22 + obj-$(CONFIG_NET_VENDOR_ASIX) += asix/ 22 23 obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ 23 24 obj-$(CONFIG_NET_VENDOR_CADENCE) += cadence/ 24 25 obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
+35
drivers/net/ethernet/asix/Kconfig
··· 1 + # 2 + # Asix network device configuration 3 + # 4 + 5 + config NET_VENDOR_ASIX 6 + bool "Asix devices" 7 + default y 8 + help 9 + If you have a network (Ethernet, non-USB, not NE2000 compatible) 10 + interface based on a chip from ASIX, say Y. 11 + 12 + if NET_VENDOR_ASIX 13 + 14 + config SPI_AX88796C 15 + tristate "Asix AX88796C-SPI support" 16 + select PHYLIB 17 + depends on SPI 18 + depends on GPIOLIB 19 + help 20 + Say Y here if you intend to use ASIX AX88796C attached in SPI mode. 21 + 22 + config SPI_AX88796C_COMPRESSION 23 + bool "SPI transfer compression" 24 + default n 25 + depends on SPI_AX88796C 26 + help 27 + Say Y here to enable SPI transfer compression. It saves up 28 + to 24 dummy cycles during each transfer which may noticeably 29 + speed up short transfers. This sets the default value that is 30 + inherited by network interfaces during probe. It can be 31 + changed at run time via spi-compression ethtool tunable. 32 + 33 + If unsure say N. 34 + 35 + endif # NET_VENDOR_ASIX
+6
drivers/net/ethernet/asix/Makefile
··· 1 + # 2 + # Makefile for the Asix network device drivers. 3 + # 4 + 5 + obj-$(CONFIG_SPI_AX88796C) += ax88796c.o 6 + ax88796c-y := ax88796c_main.o ax88796c_ioctl.o ax88796c_spi.o
+239
drivers/net/ethernet/asix/ax88796c_ioctl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2010 ASIX Electronics Corporation 4 + * Copyright (c) 2020 Samsung Electronics Co., Ltd. 5 + * 6 + * ASIX AX88796C SPI Fast Ethernet Linux driver 7 + */ 8 + 9 + #define pr_fmt(fmt) "ax88796c: " fmt 10 + 11 + #include <linux/bitmap.h> 12 + #include <linux/iopoll.h> 13 + #include <linux/phy.h> 14 + #include <linux/netdevice.h> 15 + 16 + #include "ax88796c_main.h" 17 + #include "ax88796c_ioctl.h" 18 + 19 + static const char ax88796c_priv_flag_names[][ETH_GSTRING_LEN] = { 20 + "SPICompression", 21 + }; 22 + 23 + static void 24 + ax88796c_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) 25 + { 26 + /* Inherit standard device info */ 27 + strncpy(info->driver, DRV_NAME, sizeof(info->driver)); 28 + } 29 + 30 + static u32 ax88796c_get_msglevel(struct net_device *ndev) 31 + { 32 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 33 + 34 + return ax_local->msg_enable; 35 + } 36 + 37 + static void ax88796c_set_msglevel(struct net_device *ndev, u32 level) 38 + { 39 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 40 + 41 + ax_local->msg_enable = level; 42 + } 43 + 44 + static void 45 + ax88796c_get_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause) 46 + { 47 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 48 + 49 + pause->tx_pause = !!(ax_local->flowctrl & AX_FC_TX); 50 + pause->rx_pause = !!(ax_local->flowctrl & AX_FC_RX); 51 + pause->autoneg = (ax_local->flowctrl & AX_FC_ANEG) ? 52 + AUTONEG_ENABLE : 53 + AUTONEG_DISABLE; 54 + } 55 + 56 + static int 57 + ax88796c_set_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause) 58 + { 59 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 60 + int fc; 61 + 62 + /* The following logic comes from phylink_ethtool_set_pauseparam() */ 63 + fc = pause->tx_pause ? AX_FC_TX : 0; 64 + fc |= pause->rx_pause ? AX_FC_RX : 0; 65 + fc |= pause->autoneg ? AX_FC_ANEG : 0; 66 + 67 + ax_local->flowctrl = fc; 68 + 69 + if (pause->autoneg) { 70 + phy_set_asym_pause(ax_local->phydev, pause->tx_pause, 71 + pause->rx_pause); 72 + } else { 73 + int maccr = 0; 74 + 75 + phy_set_asym_pause(ax_local->phydev, 0, 0); 76 + maccr |= (ax_local->flowctrl & AX_FC_RX) ? MACCR_RXFC_ENABLE : 0; 77 + maccr |= (ax_local->flowctrl & AX_FC_TX) ? MACCR_TXFC_ENABLE : 0; 78 + 79 + mutex_lock(&ax_local->spi_lock); 80 + 81 + maccr |= AX_READ(&ax_local->ax_spi, P0_MACCR) & 82 + ~(MACCR_TXFC_ENABLE | MACCR_RXFC_ENABLE); 83 + AX_WRITE(&ax_local->ax_spi, maccr, P0_MACCR); 84 + 85 + mutex_unlock(&ax_local->spi_lock); 86 + } 87 + 88 + return 0; 89 + } 90 + 91 + static int ax88796c_get_regs_len(struct net_device *ndev) 92 + { 93 + return AX88796C_REGDUMP_LEN + AX88796C_PHY_REGDUMP_LEN; 94 + } 95 + 96 + static void 97 + ax88796c_get_regs(struct net_device *ndev, struct ethtool_regs *regs, void *_p) 98 + { 99 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 100 + int offset, i; 101 + u16 *p = _p; 102 + 103 + memset(p, 0, ax88796c_get_regs_len(ndev)); 104 + 105 + mutex_lock(&ax_local->spi_lock); 106 + 107 + for (offset = 0; offset < AX88796C_REGDUMP_LEN; offset += 2) { 108 + if (!test_bit(offset / 2, ax88796c_no_regs_mask)) 109 + *p = AX_READ(&ax_local->ax_spi, offset); 110 + p++; 111 + } 112 + 113 + mutex_unlock(&ax_local->spi_lock); 114 + 115 + for (i = 0; i < AX88796C_PHY_REGDUMP_LEN / 2; i++) { 116 + *p = phy_read(ax_local->phydev, i); 117 + p++; 118 + } 119 + } 120 + 121 + static void 122 + ax88796c_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 123 + { 124 + switch (stringset) { 125 + case ETH_SS_PRIV_FLAGS: 126 + memcpy(data, ax88796c_priv_flag_names, 127 + sizeof(ax88796c_priv_flag_names)); 128 + break; 129 + } 130 + } 131 + 132 + static int 133 + ax88796c_get_sset_count(struct net_device *ndev, int stringset) 134 + { 135 + int ret = 0; 136 + 137 + switch (stringset) { 138 + case ETH_SS_PRIV_FLAGS: 139 + ret = ARRAY_SIZE(ax88796c_priv_flag_names); 140 + break; 141 + default: 142 + ret = -EOPNOTSUPP; 143 + } 144 + 145 + return ret; 146 + } 147 + 148 + static int ax88796c_set_priv_flags(struct net_device *ndev, u32 flags) 149 + { 150 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 151 + 152 + if (flags & ~AX_PRIV_FLAGS_MASK) 153 + return -EOPNOTSUPP; 154 + 155 + if ((ax_local->priv_flags ^ flags) & AX_CAP_COMP) 156 + if (netif_running(ndev)) 157 + return -EBUSY; 158 + 159 + ax_local->priv_flags = flags; 160 + 161 + return 0; 162 + } 163 + 164 + static u32 ax88796c_get_priv_flags(struct net_device *ndev) 165 + { 166 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 167 + 168 + return ax_local->priv_flags; 169 + } 170 + 171 + int ax88796c_mdio_read(struct mii_bus *mdiobus, int phy_id, int loc) 172 + { 173 + struct ax88796c_device *ax_local = mdiobus->priv; 174 + int ret; 175 + 176 + mutex_lock(&ax_local->spi_lock); 177 + AX_WRITE(&ax_local->ax_spi, MDIOCR_RADDR(loc) 178 + | MDIOCR_FADDR(phy_id) | MDIOCR_READ, P2_MDIOCR); 179 + 180 + ret = read_poll_timeout(AX_READ, ret, 181 + (ret != 0), 182 + 0, jiffies_to_usecs(HZ / 100), false, 183 + &ax_local->ax_spi, P2_MDIOCR); 184 + if (!ret) 185 + ret = AX_READ(&ax_local->ax_spi, P2_MDIODR); 186 + 187 + mutex_unlock(&ax_local->spi_lock); 188 + 189 + return ret; 190 + } 191 + 192 + int 193 + ax88796c_mdio_write(struct mii_bus *mdiobus, int phy_id, int loc, u16 val) 194 + { 195 + struct ax88796c_device *ax_local = mdiobus->priv; 196 + int ret; 197 + 198 + mutex_lock(&ax_local->spi_lock); 199 + AX_WRITE(&ax_local->ax_spi, val, P2_MDIODR); 200 + 201 + AX_WRITE(&ax_local->ax_spi, 202 + MDIOCR_RADDR(loc) | MDIOCR_FADDR(phy_id) 203 + | MDIOCR_WRITE, P2_MDIOCR); 204 + 205 + ret = read_poll_timeout(AX_READ, ret, 206 + ((ret & MDIOCR_VALID) != 0), 0, 207 + jiffies_to_usecs(HZ / 100), false, 208 + &ax_local->ax_spi, P2_MDIOCR); 209 + mutex_unlock(&ax_local->spi_lock); 210 + 211 + return ret; 212 + } 213 + 214 + const struct ethtool_ops ax88796c_ethtool_ops = { 215 + .get_drvinfo = ax88796c_get_drvinfo, 216 + .get_link = ethtool_op_get_link, 217 + .get_msglevel = ax88796c_get_msglevel, 218 + .set_msglevel = ax88796c_set_msglevel, 219 + .get_link_ksettings = phy_ethtool_get_link_ksettings, 220 + .set_link_ksettings = phy_ethtool_set_link_ksettings, 221 + .nway_reset = phy_ethtool_nway_reset, 222 + .get_pauseparam = ax88796c_get_pauseparam, 223 + .set_pauseparam = ax88796c_set_pauseparam, 224 + .get_regs_len = ax88796c_get_regs_len, 225 + .get_regs = ax88796c_get_regs, 226 + .get_strings = ax88796c_get_strings, 227 + .get_sset_count = ax88796c_get_sset_count, 228 + .get_priv_flags = ax88796c_get_priv_flags, 229 + .set_priv_flags = ax88796c_set_priv_flags, 230 + }; 231 + 232 + int ax88796c_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) 233 + { 234 + int ret; 235 + 236 + ret = phy_mii_ioctl(ndev->phydev, ifr, cmd); 237 + 238 + return ret; 239 + }
+26
drivers/net/ethernet/asix/ax88796c_ioctl.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2010 ASIX Electronics Corporation 4 + * Copyright (c) 2020 Samsung Electronics Co., Ltd. 5 + * 6 + * ASIX AX88796C SPI Fast Ethernet Linux driver 7 + */ 8 + 9 + #ifndef _AX88796C_IOCTL_H 10 + #define _AX88796C_IOCTL_H 11 + 12 + #include <linux/ethtool.h> 13 + #include <linux/netdevice.h> 14 + 15 + #include "ax88796c_main.h" 16 + 17 + extern const struct ethtool_ops ax88796c_ethtool_ops; 18 + 19 + bool ax88796c_check_power(const struct ax88796c_device *ax_local); 20 + bool ax88796c_check_power_and_wake(struct ax88796c_device *ax_local); 21 + void ax88796c_set_power_saving(struct ax88796c_device *ax_local, u8 ps_level); 22 + int ax88796c_mdio_read(struct mii_bus *mdiobus, int phy_id, int loc); 23 + int ax88796c_mdio_write(struct mii_bus *mdiobus, int phy_id, int loc, u16 val); 24 + int ax88796c_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 25 + 26 + #endif
+1163
drivers/net/ethernet/asix/ax88796c_main.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2010 ASIX Electronics Corporation 4 + * Copyright (c) 2020 Samsung Electronics Co., Ltd. 5 + * 6 + * ASIX AX88796C SPI Fast Ethernet Linux driver 7 + */ 8 + 9 + #define pr_fmt(fmt) "ax88796c: " fmt 10 + 11 + #include "ax88796c_main.h" 12 + #include "ax88796c_ioctl.h" 13 + 14 + #include <linux/bitmap.h> 15 + #include <linux/etherdevice.h> 16 + #include <linux/iopoll.h> 17 + #include <linux/lockdep.h> 18 + #include <linux/mdio.h> 19 + #include <linux/minmax.h> 20 + #include <linux/module.h> 21 + #include <linux/netdevice.h> 22 + #include <linux/of.h> 23 + #include <linux/phy.h> 24 + #include <linux/skbuff.h> 25 + #include <linux/spi/spi.h> 26 + 27 + static int comp = IS_ENABLED(CONFIG_SPI_AX88796C_COMPRESSION); 28 + static int msg_enable = NETIF_MSG_PROBE | 29 + NETIF_MSG_LINK | 30 + NETIF_MSG_RX_ERR | 31 + NETIF_MSG_TX_ERR; 32 + 33 + static const char *no_regs_list = "80018001,e1918001,8001a001,fc0d0000"; 34 + unsigned long ax88796c_no_regs_mask[AX88796C_REGDUMP_LEN / (sizeof(unsigned long) * 8)]; 35 + 36 + module_param(msg_enable, int, 0444); 37 + MODULE_PARM_DESC(msg_enable, "Message mask (see linux/netdevice.h for bitmap)"); 38 + 39 + static int ax88796c_soft_reset(struct ax88796c_device *ax_local) 40 + { 41 + u16 temp; 42 + int ret; 43 + 44 + lockdep_assert_held(&ax_local->spi_lock); 45 + 46 + AX_WRITE(&ax_local->ax_spi, PSR_RESET, P0_PSR); 47 + AX_WRITE(&ax_local->ax_spi, PSR_RESET_CLR, P0_PSR); 48 + 49 + ret = read_poll_timeout(AX_READ, ret, 50 + (ret & PSR_DEV_READY), 51 + 0, jiffies_to_usecs(160 * HZ / 1000), false, 52 + &ax_local->ax_spi, P0_PSR); 53 + if (ret) 54 + return ret; 55 + 56 + temp = AX_READ(&ax_local->ax_spi, P4_SPICR); 57 + if (ax_local->priv_flags & AX_CAP_COMP) { 58 + AX_WRITE(&ax_local->ax_spi, 59 + (temp | SPICR_RCEN | SPICR_QCEN), P4_SPICR); 60 + ax_local->ax_spi.comp = 1; 61 + } else { 62 + AX_WRITE(&ax_local->ax_spi, 63 + (temp & ~(SPICR_RCEN | SPICR_QCEN)), P4_SPICR); 64 + ax_local->ax_spi.comp = 0; 65 + } 66 + 67 + return 0; 68 + } 69 + 70 + static int ax88796c_reload_eeprom(struct ax88796c_device *ax_local) 71 + { 72 + int ret; 73 + 74 + lockdep_assert_held(&ax_local->spi_lock); 75 + 76 + AX_WRITE(&ax_local->ax_spi, EECR_RELOAD, P3_EECR); 77 + 78 + ret = read_poll_timeout(AX_READ, ret, 79 + (ret & PSR_DEV_READY), 80 + 0, jiffies_to_usecs(2 * HZ / 1000), false, 81 + &ax_local->ax_spi, P0_PSR); 82 + if (ret) { 83 + dev_err(&ax_local->spi->dev, 84 + "timeout waiting for reload eeprom\n"); 85 + return ret; 86 + } 87 + 88 + return 0; 89 + } 90 + 91 + static void ax88796c_set_hw_multicast(struct net_device *ndev) 92 + { 93 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 94 + int mc_count = netdev_mc_count(ndev); 95 + u16 rx_ctl = RXCR_AB; 96 + 97 + lockdep_assert_held(&ax_local->spi_lock); 98 + 99 + memset(ax_local->multi_filter, 0, AX_MCAST_FILTER_SIZE); 100 + 101 + if (ndev->flags & IFF_PROMISC) { 102 + rx_ctl |= RXCR_PRO; 103 + 104 + } else if (ndev->flags & IFF_ALLMULTI || mc_count > AX_MAX_MCAST) { 105 + rx_ctl |= RXCR_AMALL; 106 + 107 + } else if (mc_count == 0) { 108 + /* just broadcast and directed */ 109 + } else { 110 + u32 crc_bits; 111 + int i; 112 + struct netdev_hw_addr *ha; 113 + 114 + netdev_for_each_mc_addr(ha, ndev) { 115 + crc_bits = ether_crc(ETH_ALEN, ha->addr); 116 + ax_local->multi_filter[crc_bits >> 29] |= 117 + (1 << ((crc_bits >> 26) & 7)); 118 + } 119 + 120 + for (i = 0; i < 4; i++) { 121 + AX_WRITE(&ax_local->ax_spi, 122 + ((ax_local->multi_filter[i * 2 + 1] << 8) | 123 + ax_local->multi_filter[i * 2]), P3_MFAR(i)); 124 + } 125 + } 126 + 127 + AX_WRITE(&ax_local->ax_spi, rx_ctl, P2_RXCR); 128 + } 129 + 130 + static void ax88796c_set_mac_addr(struct net_device *ndev) 131 + { 132 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 133 + 134 + lockdep_assert_held(&ax_local->spi_lock); 135 + 136 + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[4] << 8) | 137 + (u16)ndev->dev_addr[5]), P3_MACASR0); 138 + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[2] << 8) | 139 + (u16)ndev->dev_addr[3]), P3_MACASR1); 140 + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[0] << 8) | 141 + (u16)ndev->dev_addr[1]), P3_MACASR2); 142 + } 143 + 144 + static void ax88796c_load_mac_addr(struct net_device *ndev) 145 + { 146 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 147 + u16 temp; 148 + 149 + lockdep_assert_held(&ax_local->spi_lock); 150 + 151 + /* Try the device tree first */ 152 + if (!eth_platform_get_mac_address(&ax_local->spi->dev, ndev->dev_addr) && 153 + is_valid_ether_addr(ndev->dev_addr)) { 154 + if (netif_msg_probe(ax_local)) 155 + dev_info(&ax_local->spi->dev, 156 + "MAC address read from device tree\n"); 157 + return; 158 + } 159 + 160 + /* Read the MAC address from AX88796C */ 161 + temp = AX_READ(&ax_local->ax_spi, P3_MACASR0); 162 + ndev->dev_addr[5] = (u8)temp; 163 + ndev->dev_addr[4] = (u8)(temp >> 8); 164 + 165 + temp = AX_READ(&ax_local->ax_spi, P3_MACASR1); 166 + ndev->dev_addr[3] = (u8)temp; 167 + ndev->dev_addr[2] = (u8)(temp >> 8); 168 + 169 + temp = AX_READ(&ax_local->ax_spi, P3_MACASR2); 170 + ndev->dev_addr[1] = (u8)temp; 171 + ndev->dev_addr[0] = (u8)(temp >> 8); 172 + 173 + if (is_valid_ether_addr(ndev->dev_addr)) { 174 + if (netif_msg_probe(ax_local)) 175 + dev_info(&ax_local->spi->dev, 176 + "MAC address read from ASIX chip\n"); 177 + return; 178 + } 179 + 180 + /* Use random address if none found */ 181 + if (netif_msg_probe(ax_local)) 182 + dev_info(&ax_local->spi->dev, "Use random MAC address\n"); 183 + eth_hw_addr_random(ndev); 184 + } 185 + 186 + static void ax88796c_proc_tx_hdr(struct tx_pkt_info *info, u8 ip_summed) 187 + { 188 + u16 pkt_len_bar = (~info->pkt_len & TX_HDR_SOP_PKTLENBAR); 189 + 190 + /* Prepare SOP header */ 191 + info->sop.flags_len = info->pkt_len | 192 + ((ip_summed == CHECKSUM_NONE) || 193 + (ip_summed == CHECKSUM_UNNECESSARY) ? TX_HDR_SOP_DICF : 0); 194 + 195 + info->sop.seq_lenbar = ((info->seq_num << 11) & TX_HDR_SOP_SEQNUM) 196 + | pkt_len_bar; 197 + cpu_to_be16s(&info->sop.flags_len); 198 + cpu_to_be16s(&info->sop.seq_lenbar); 199 + 200 + /* Prepare Segment header */ 201 + info->seg.flags_seqnum_seglen = TX_HDR_SEG_FS | TX_HDR_SEG_LS 202 + | info->pkt_len; 203 + 204 + info->seg.eo_so_seglenbar = pkt_len_bar; 205 + 206 + cpu_to_be16s(&info->seg.flags_seqnum_seglen); 207 + cpu_to_be16s(&info->seg.eo_so_seglenbar); 208 + 209 + /* Prepare EOP header */ 210 + info->eop.seq_len = ((info->seq_num << 11) & 211 + TX_HDR_EOP_SEQNUM) | info->pkt_len; 212 + info->eop.seqbar_lenbar = ((~info->seq_num << 11) & 213 + TX_HDR_EOP_SEQNUMBAR) | pkt_len_bar; 214 + 215 + cpu_to_be16s(&info->eop.seq_len); 216 + cpu_to_be16s(&info->eop.seqbar_lenbar); 217 + } 218 + 219 + static int 220 + ax88796c_check_free_pages(struct ax88796c_device *ax_local, u8 need_pages) 221 + { 222 + u8 free_pages; 223 + u16 tmp; 224 + 225 + lockdep_assert_held(&ax_local->spi_lock); 226 + 227 + free_pages = AX_READ(&ax_local->ax_spi, P0_TFBFCR) & TX_FREEBUF_MASK; 228 + if (free_pages < need_pages) { 229 + /* schedule free page interrupt */ 230 + tmp = AX_READ(&ax_local->ax_spi, P0_TFBFCR) 231 + & TFBFCR_SCHE_FREE_PAGE; 232 + AX_WRITE(&ax_local->ax_spi, tmp | TFBFCR_TX_PAGE_SET | 233 + TFBFCR_SET_FREE_PAGE(need_pages), 234 + P0_TFBFCR); 235 + return -ENOMEM; 236 + } 237 + 238 + return 0; 239 + } 240 + 241 + static struct sk_buff * 242 + ax88796c_tx_fixup(struct net_device *ndev, struct sk_buff_head *q) 243 + { 244 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 245 + u8 spi_len = ax_local->ax_spi.comp ? 1 : 4; 246 + struct sk_buff *skb; 247 + struct tx_pkt_info info; 248 + struct skb_data *entry; 249 + u16 pkt_len; 250 + u8 padlen, seq_num; 251 + u8 need_pages; 252 + int headroom; 253 + int tailroom; 254 + 255 + if (skb_queue_empty(q)) 256 + return NULL; 257 + 258 + skb = skb_peek(q); 259 + pkt_len = skb->len; 260 + need_pages = (pkt_len + TX_OVERHEAD + 127) >> 7; 261 + if (ax88796c_check_free_pages(ax_local, need_pages) != 0) 262 + return NULL; 263 + 264 + headroom = skb_headroom(skb); 265 + tailroom = skb_tailroom(skb); 266 + padlen = round_up(pkt_len, 4) - pkt_len; 267 + seq_num = ++ax_local->seq_num & 0x1F; 268 + 269 + info.pkt_len = pkt_len; 270 + 271 + if (skb_cloned(skb) || 272 + (headroom < (TX_OVERHEAD + spi_len)) || 273 + (tailroom < (padlen + TX_EOP_SIZE))) { 274 + size_t h = max((TX_OVERHEAD + spi_len) - headroom, 0); 275 + size_t t = max((padlen + TX_EOP_SIZE) - tailroom, 0); 276 + 277 + if (pskb_expand_head(skb, h, t, GFP_KERNEL)) 278 + return NULL; 279 + } 280 + 281 + info.seq_num = seq_num; 282 + ax88796c_proc_tx_hdr(&info, skb->ip_summed); 283 + 284 + /* SOP and SEG header */ 285 + memcpy(skb_push(skb, TX_OVERHEAD), &info.sop, TX_OVERHEAD); 286 + 287 + /* Write SPI TXQ header */ 288 + memcpy(skb_push(skb, spi_len), ax88796c_tx_cmd_buf, spi_len); 289 + 290 + /* Make 32-bit alignment */ 291 + skb_put(skb, padlen); 292 + 293 + /* EOP header */ 294 + memcpy(skb_put(skb, TX_EOP_SIZE), &info.eop, TX_EOP_SIZE); 295 + 296 + skb_unlink(skb, q); 297 + 298 + entry = (struct skb_data *)skb->cb; 299 + memset(entry, 0, sizeof(*entry)); 300 + entry->len = pkt_len; 301 + 302 + if (netif_msg_pktdata(ax_local)) { 303 + char pfx[IFNAMSIZ + 7]; 304 + 305 + snprintf(pfx, sizeof(pfx), "%s: ", ndev->name); 306 + 307 + netdev_info(ndev, "TX packet len %d, total len %d, seq %d\n", 308 + pkt_len, skb->len, seq_num); 309 + 310 + netdev_info(ndev, " SPI Header:\n"); 311 + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, 312 + skb->data, 4, 0); 313 + 314 + netdev_info(ndev, " TX SOP:\n"); 315 + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, 316 + skb->data + 4, TX_OVERHEAD, 0); 317 + 318 + netdev_info(ndev, " TX packet:\n"); 319 + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, 320 + skb->data + 4 + TX_OVERHEAD, 321 + skb->len - TX_EOP_SIZE - 4 - TX_OVERHEAD, 0); 322 + 323 + netdev_info(ndev, " TX EOP:\n"); 324 + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, 325 + skb->data + skb->len - 4, 4, 0); 326 + } 327 + 328 + return skb; 329 + } 330 + 331 + static int ax88796c_hard_xmit(struct ax88796c_device *ax_local) 332 + { 333 + struct ax88796c_pcpu_stats *stats; 334 + struct sk_buff *tx_skb; 335 + struct skb_data *entry; 336 + unsigned long flags; 337 + 338 + lockdep_assert_held(&ax_local->spi_lock); 339 + 340 + stats = this_cpu_ptr(ax_local->stats); 341 + tx_skb = ax88796c_tx_fixup(ax_local->ndev, &ax_local->tx_wait_q); 342 + 343 + if (!tx_skb) { 344 + this_cpu_inc(ax_local->stats->tx_dropped); 345 + return 0; 346 + } 347 + entry = (struct skb_data *)tx_skb->cb; 348 + 349 + AX_WRITE(&ax_local->ax_spi, 350 + (TSNR_TXB_START | TSNR_PKT_CNT(1)), P0_TSNR); 351 + 352 + axspi_write_txq(&ax_local->ax_spi, tx_skb->data, tx_skb->len); 353 + 354 + if (((AX_READ(&ax_local->ax_spi, P0_TSNR) & TXNR_TXB_IDLE) == 0) || 355 + ((ISR_TXERR & AX_READ(&ax_local->ax_spi, P0_ISR)) != 0)) { 356 + /* Ack tx error int */ 357 + AX_WRITE(&ax_local->ax_spi, ISR_TXERR, P0_ISR); 358 + 359 + this_cpu_inc(ax_local->stats->tx_dropped); 360 + 361 + if (net_ratelimit()) 362 + netif_err(ax_local, tx_err, ax_local->ndev, 363 + "TX FIFO error, re-initialize the TX bridge\n"); 364 + 365 + /* Reinitial tx bridge */ 366 + AX_WRITE(&ax_local->ax_spi, TXNR_TXB_REINIT | 367 + AX_READ(&ax_local->ax_spi, P0_TSNR), P0_TSNR); 368 + ax_local->seq_num = 0; 369 + } else { 370 + flags = u64_stats_update_begin_irqsave(&stats->syncp); 371 + u64_stats_inc(&stats->tx_packets); 372 + u64_stats_add(&stats->tx_bytes, entry->len); 373 + u64_stats_update_end_irqrestore(&stats->syncp, flags); 374 + } 375 + 376 + entry->state = tx_done; 377 + dev_kfree_skb(tx_skb); 378 + 379 + return 1; 380 + } 381 + 382 + static int 383 + ax88796c_start_xmit(struct sk_buff *skb, struct net_device *ndev) 384 + { 385 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 386 + 387 + skb_queue_tail(&ax_local->tx_wait_q, skb); 388 + if (skb_queue_len(&ax_local->tx_wait_q) > TX_QUEUE_HIGH_WATER) 389 + netif_stop_queue(ndev); 390 + 391 + set_bit(EVENT_TX, &ax_local->flags); 392 + schedule_work(&ax_local->ax_work); 393 + 394 + return NETDEV_TX_OK; 395 + } 396 + 397 + static void 398 + ax88796c_skb_return(struct ax88796c_device *ax_local, 399 + struct sk_buff *skb, struct rx_header *rxhdr) 400 + { 401 + struct net_device *ndev = ax_local->ndev; 402 + struct ax88796c_pcpu_stats *stats; 403 + unsigned long flags; 404 + int status; 405 + 406 + stats = this_cpu_ptr(ax_local->stats); 407 + 408 + do { 409 + if (!(ndev->features & NETIF_F_RXCSUM)) 410 + break; 411 + 412 + /* checksum error bit is set */ 413 + if ((rxhdr->flags & RX_HDR3_L3_ERR) || 414 + (rxhdr->flags & RX_HDR3_L4_ERR)) 415 + break; 416 + 417 + /* Other types may be indicated by more than one bit. */ 418 + if ((rxhdr->flags & RX_HDR3_L4_TYPE_TCP) || 419 + (rxhdr->flags & RX_HDR3_L4_TYPE_UDP)) 420 + skb->ip_summed = CHECKSUM_UNNECESSARY; 421 + } while (0); 422 + 423 + flags = u64_stats_update_begin_irqsave(&stats->syncp); 424 + u64_stats_inc(&stats->rx_packets); 425 + u64_stats_add(&stats->rx_bytes, skb->len); 426 + u64_stats_update_end_irqrestore(&stats->syncp, flags); 427 + 428 + skb->dev = ndev; 429 + skb->protocol = eth_type_trans(skb, ax_local->ndev); 430 + 431 + netif_info(ax_local, rx_status, ndev, "< rx, len %zu, type 0x%x\n", 432 + skb->len + sizeof(struct ethhdr), skb->protocol); 433 + 434 + status = netif_rx_ni(skb); 435 + if (status != NET_RX_SUCCESS && net_ratelimit()) 436 + netif_info(ax_local, rx_err, ndev, 437 + "netif_rx status %d\n", status); 438 + } 439 + 440 + static void 441 + ax88796c_rx_fixup(struct ax88796c_device *ax_local, struct sk_buff *rx_skb) 442 + { 443 + struct rx_header *rxhdr = (struct rx_header *)rx_skb->data; 444 + struct net_device *ndev = ax_local->ndev; 445 + u16 len; 446 + 447 + be16_to_cpus(&rxhdr->flags_len); 448 + be16_to_cpus(&rxhdr->seq_lenbar); 449 + be16_to_cpus(&rxhdr->flags); 450 + 451 + if ((rxhdr->flags_len & RX_HDR1_PKT_LEN) != 452 + (~rxhdr->seq_lenbar & 0x7FF)) { 453 + netif_err(ax_local, rx_err, ndev, "Header error\n"); 454 + 455 + this_cpu_inc(ax_local->stats->rx_frame_errors); 456 + kfree_skb(rx_skb); 457 + return; 458 + } 459 + 460 + if ((rxhdr->flags_len & RX_HDR1_MII_ERR) || 461 + (rxhdr->flags_len & RX_HDR1_CRC_ERR)) { 462 + netif_err(ax_local, rx_err, ndev, "CRC or MII error\n"); 463 + 464 + this_cpu_inc(ax_local->stats->rx_crc_errors); 465 + kfree_skb(rx_skb); 466 + return; 467 + } 468 + 469 + len = rxhdr->flags_len & RX_HDR1_PKT_LEN; 470 + if (netif_msg_pktdata(ax_local)) { 471 + char pfx[IFNAMSIZ + 7]; 472 + 473 + snprintf(pfx, sizeof(pfx), "%s: ", ndev->name); 474 + netdev_info(ndev, "RX data, total len %d, packet len %d\n", 475 + rx_skb->len, len); 476 + 477 + netdev_info(ndev, " Dump RX packet header:"); 478 + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, 479 + rx_skb->data, sizeof(*rxhdr), 0); 480 + 481 + netdev_info(ndev, " Dump RX packet:"); 482 + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, 483 + rx_skb->data + sizeof(*rxhdr), len, 0); 484 + } 485 + 486 + skb_pull(rx_skb, sizeof(*rxhdr)); 487 + pskb_trim(rx_skb, len); 488 + 489 + ax88796c_skb_return(ax_local, rx_skb, rxhdr); 490 + } 491 + 492 + static int ax88796c_receive(struct net_device *ndev) 493 + { 494 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 495 + struct skb_data *entry; 496 + u16 w_count, pkt_len; 497 + struct sk_buff *skb; 498 + u8 pkt_cnt; 499 + 500 + lockdep_assert_held(&ax_local->spi_lock); 501 + 502 + /* check rx packet and total word count */ 503 + AX_WRITE(&ax_local->ax_spi, AX_READ(&ax_local->ax_spi, P0_RTWCR) 504 + | RTWCR_RX_LATCH, P0_RTWCR); 505 + 506 + pkt_cnt = AX_READ(&ax_local->ax_spi, P0_RXBCR2) & RXBCR2_PKT_MASK; 507 + if (!pkt_cnt) 508 + return 0; 509 + 510 + pkt_len = AX_READ(&ax_local->ax_spi, P0_RCPHR) & 0x7FF; 511 + 512 + w_count = round_up(pkt_len + 6, 4) >> 1; 513 + 514 + skb = netdev_alloc_skb(ndev, w_count * 2); 515 + if (!skb) { 516 + AX_WRITE(&ax_local->ax_spi, RXBCR1_RXB_DISCARD, P0_RXBCR1); 517 + this_cpu_inc(ax_local->stats->rx_dropped); 518 + return 0; 519 + } 520 + entry = (struct skb_data *)skb->cb; 521 + 522 + AX_WRITE(&ax_local->ax_spi, RXBCR1_RXB_START | w_count, P0_RXBCR1); 523 + 524 + axspi_read_rxq(&ax_local->ax_spi, 525 + skb_put(skb, w_count * 2), skb->len); 526 + 527 + /* Check if rx bridge is idle */ 528 + if ((AX_READ(&ax_local->ax_spi, P0_RXBCR2) & RXBCR2_RXB_IDLE) == 0) { 529 + if (net_ratelimit()) 530 + netif_err(ax_local, rx_err, ndev, 531 + "Rx Bridge is not idle\n"); 532 + AX_WRITE(&ax_local->ax_spi, RXBCR2_RXB_REINIT, P0_RXBCR2); 533 + 534 + entry->state = rx_err; 535 + } else { 536 + entry->state = rx_done; 537 + } 538 + 539 + AX_WRITE(&ax_local->ax_spi, ISR_RXPKT, P0_ISR); 540 + 541 + ax88796c_rx_fixup(ax_local, skb); 542 + 543 + return 1; 544 + } 545 + 546 + static int ax88796c_process_isr(struct ax88796c_device *ax_local) 547 + { 548 + struct net_device *ndev = ax_local->ndev; 549 + int todo = 0; 550 + u16 isr; 551 + 552 + lockdep_assert_held(&ax_local->spi_lock); 553 + 554 + isr = AX_READ(&ax_local->ax_spi, P0_ISR); 555 + AX_WRITE(&ax_local->ax_spi, isr, P0_ISR); 556 + 557 + netif_dbg(ax_local, intr, ndev, " ISR 0x%04x\n", isr); 558 + 559 + if (isr & ISR_TXERR) { 560 + netif_dbg(ax_local, intr, ndev, " TXERR interrupt\n"); 561 + AX_WRITE(&ax_local->ax_spi, TXNR_TXB_REINIT, P0_TSNR); 562 + ax_local->seq_num = 0x1f; 563 + } 564 + 565 + if (isr & ISR_TXPAGES) { 566 + netif_dbg(ax_local, intr, ndev, " TXPAGES interrupt\n"); 567 + set_bit(EVENT_TX, &ax_local->flags); 568 + } 569 + 570 + if (isr & ISR_LINK) { 571 + netif_dbg(ax_local, intr, ndev, " Link change interrupt\n"); 572 + phy_mac_interrupt(ax_local->ndev->phydev); 573 + } 574 + 575 + if (isr & ISR_RXPKT) { 576 + netif_dbg(ax_local, intr, ndev, " RX interrupt\n"); 577 + todo = ax88796c_receive(ax_local->ndev); 578 + } 579 + 580 + return todo; 581 + } 582 + 583 + static irqreturn_t ax88796c_interrupt(int irq, void *dev_instance) 584 + { 585 + struct ax88796c_device *ax_local; 586 + struct net_device *ndev; 587 + 588 + ndev = dev_instance; 589 + if (!ndev) { 590 + pr_err("irq %d for unknown device.\n", irq); 591 + return IRQ_RETVAL(0); 592 + } 593 + ax_local = to_ax88796c_device(ndev); 594 + 595 + disable_irq_nosync(irq); 596 + 597 + netif_dbg(ax_local, intr, ndev, "Interrupt occurred\n"); 598 + 599 + set_bit(EVENT_INTR, &ax_local->flags); 600 + schedule_work(&ax_local->ax_work); 601 + 602 + return IRQ_HANDLED; 603 + } 604 + 605 + static void ax88796c_work(struct work_struct *work) 606 + { 607 + struct ax88796c_device *ax_local = 608 + container_of(work, struct ax88796c_device, ax_work); 609 + 610 + mutex_lock(&ax_local->spi_lock); 611 + 612 + if (test_bit(EVENT_SET_MULTI, &ax_local->flags)) { 613 + ax88796c_set_hw_multicast(ax_local->ndev); 614 + clear_bit(EVENT_SET_MULTI, &ax_local->flags); 615 + } 616 + 617 + if (test_bit(EVENT_INTR, &ax_local->flags)) { 618 + AX_WRITE(&ax_local->ax_spi, IMR_MASKALL, P0_IMR); 619 + 620 + while (ax88796c_process_isr(ax_local)) 621 + /* nothing */; 622 + 623 + clear_bit(EVENT_INTR, &ax_local->flags); 624 + 625 + AX_WRITE(&ax_local->ax_spi, IMR_DEFAULT, P0_IMR); 626 + 627 + enable_irq(ax_local->ndev->irq); 628 + } 629 + 630 + if (test_bit(EVENT_TX, &ax_local->flags)) { 631 + while (skb_queue_len(&ax_local->tx_wait_q)) { 632 + if (!ax88796c_hard_xmit(ax_local)) 633 + break; 634 + } 635 + 636 + clear_bit(EVENT_TX, &ax_local->flags); 637 + 638 + if (netif_queue_stopped(ax_local->ndev) && 639 + (skb_queue_len(&ax_local->tx_wait_q) < TX_QUEUE_LOW_WATER)) 640 + netif_wake_queue(ax_local->ndev); 641 + } 642 + 643 + mutex_unlock(&ax_local->spi_lock); 644 + } 645 + 646 + static void ax88796c_get_stats64(struct net_device *ndev, 647 + struct rtnl_link_stats64 *stats) 648 + { 649 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 650 + u32 rx_frame_errors = 0, rx_crc_errors = 0; 651 + u32 rx_dropped = 0, tx_dropped = 0; 652 + unsigned int start; 653 + int cpu; 654 + 655 + for_each_possible_cpu(cpu) { 656 + struct ax88796c_pcpu_stats *s; 657 + u64 rx_packets, rx_bytes; 658 + u64 tx_packets, tx_bytes; 659 + 660 + s = per_cpu_ptr(ax_local->stats, cpu); 661 + 662 + do { 663 + start = u64_stats_fetch_begin_irq(&s->syncp); 664 + rx_packets = u64_stats_read(&s->rx_packets); 665 + rx_bytes = u64_stats_read(&s->rx_bytes); 666 + tx_packets = u64_stats_read(&s->tx_packets); 667 + tx_bytes = u64_stats_read(&s->tx_bytes); 668 + } while (u64_stats_fetch_retry_irq(&s->syncp, start)); 669 + 670 + stats->rx_packets += rx_packets; 671 + stats->rx_bytes += rx_bytes; 672 + stats->tx_packets += tx_packets; 673 + stats->tx_bytes += tx_bytes; 674 + 675 + rx_dropped += stats->rx_dropped; 676 + tx_dropped += stats->tx_dropped; 677 + rx_frame_errors += stats->rx_frame_errors; 678 + rx_crc_errors += stats->rx_crc_errors; 679 + } 680 + 681 + stats->rx_dropped = rx_dropped; 682 + stats->tx_dropped = tx_dropped; 683 + stats->rx_frame_errors = rx_frame_errors; 684 + stats->rx_crc_errors = rx_crc_errors; 685 + } 686 + 687 + static void ax88796c_set_mac(struct ax88796c_device *ax_local) 688 + { 689 + u16 maccr; 690 + 691 + maccr = (ax_local->link) ? MACCR_RXEN : 0; 692 + 693 + switch (ax_local->speed) { 694 + case SPEED_100: 695 + maccr |= MACCR_SPEED_100; 696 + case SPEED_10: 697 + case SPEED_UNKNOWN: 698 + break; 699 + default: 700 + return; 701 + } 702 + 703 + switch (ax_local->duplex) { 704 + case DUPLEX_FULL: 705 + maccr |= MACCR_SPEED_100; 706 + case DUPLEX_HALF: 707 + case DUPLEX_UNKNOWN: 708 + break; 709 + default: 710 + return; 711 + } 712 + 713 + if (ax_local->flowctrl & AX_FC_ANEG && 714 + ax_local->phydev->autoneg) { 715 + maccr |= ax_local->pause ? MACCR_RXFC_ENABLE : 0; 716 + maccr |= !ax_local->pause != !ax_local->asym_pause ? 717 + MACCR_TXFC_ENABLE : 0; 718 + } else { 719 + maccr |= (ax_local->flowctrl & AX_FC_RX) ? MACCR_RXFC_ENABLE : 0; 720 + maccr |= (ax_local->flowctrl & AX_FC_TX) ? MACCR_TXFC_ENABLE : 0; 721 + } 722 + 723 + mutex_lock(&ax_local->spi_lock); 724 + 725 + maccr |= AX_READ(&ax_local->ax_spi, P0_MACCR) & 726 + ~(MACCR_DUPLEX_FULL | MACCR_SPEED_100 | 727 + MACCR_TXFC_ENABLE | MACCR_RXFC_ENABLE); 728 + AX_WRITE(&ax_local->ax_spi, maccr, P0_MACCR); 729 + 730 + mutex_unlock(&ax_local->spi_lock); 731 + } 732 + 733 + static void ax88796c_handle_link_change(struct net_device *ndev) 734 + { 735 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 736 + struct phy_device *phydev = ndev->phydev; 737 + bool update = false; 738 + 739 + if (phydev->link && (ax_local->speed != phydev->speed || 740 + ax_local->duplex != phydev->duplex || 741 + ax_local->pause != phydev->pause || 742 + ax_local->asym_pause != phydev->asym_pause)) { 743 + ax_local->speed = phydev->speed; 744 + ax_local->duplex = phydev->duplex; 745 + ax_local->pause = phydev->pause; 746 + ax_local->asym_pause = phydev->asym_pause; 747 + update = true; 748 + } 749 + 750 + if (phydev->link != ax_local->link) { 751 + if (!phydev->link) { 752 + ax_local->speed = SPEED_UNKNOWN; 753 + ax_local->duplex = DUPLEX_UNKNOWN; 754 + } 755 + 756 + ax_local->link = phydev->link; 757 + update = true; 758 + } 759 + 760 + if (update) 761 + ax88796c_set_mac(ax_local); 762 + 763 + if (net_ratelimit()) 764 + phy_print_status(ndev->phydev); 765 + } 766 + 767 + static void ax88796c_set_csums(struct ax88796c_device *ax_local) 768 + { 769 + struct net_device *ndev = ax_local->ndev; 770 + 771 + lockdep_assert_held(&ax_local->spi_lock); 772 + 773 + if (ndev->features & NETIF_F_RXCSUM) { 774 + AX_WRITE(&ax_local->ax_spi, COERCR0_DEFAULT, P4_COERCR0); 775 + AX_WRITE(&ax_local->ax_spi, COERCR1_DEFAULT, P4_COERCR1); 776 + } else { 777 + AX_WRITE(&ax_local->ax_spi, 0, P4_COERCR0); 778 + AX_WRITE(&ax_local->ax_spi, 0, P4_COERCR1); 779 + } 780 + 781 + if (ndev->features & NETIF_F_HW_CSUM) { 782 + AX_WRITE(&ax_local->ax_spi, COETCR0_DEFAULT, P4_COETCR0); 783 + AX_WRITE(&ax_local->ax_spi, COETCR1_TXPPPE, P4_COETCR1); 784 + } else { 785 + AX_WRITE(&ax_local->ax_spi, 0, P4_COETCR0); 786 + AX_WRITE(&ax_local->ax_spi, 0, P4_COETCR1); 787 + } 788 + } 789 + 790 + static int 791 + ax88796c_open(struct net_device *ndev) 792 + { 793 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 794 + unsigned long irq_flag = 0; 795 + int fc = AX_FC_NONE; 796 + int ret; 797 + u16 t; 798 + 799 + ret = request_irq(ndev->irq, ax88796c_interrupt, 800 + irq_flag, ndev->name, ndev); 801 + if (ret) { 802 + netdev_err(ndev, "unable to get IRQ %d (errno=%d).\n", 803 + ndev->irq, ret); 804 + return ret; 805 + } 806 + 807 + mutex_lock(&ax_local->spi_lock); 808 + 809 + ret = ax88796c_soft_reset(ax_local); 810 + if (ret < 0) { 811 + free_irq(ndev->irq, ndev); 812 + mutex_unlock(&ax_local->spi_lock); 813 + return ret; 814 + } 815 + ax_local->seq_num = 0x1f; 816 + 817 + ax88796c_set_mac_addr(ndev); 818 + ax88796c_set_csums(ax_local); 819 + 820 + /* Disable stuffing packet */ 821 + t = AX_READ(&ax_local->ax_spi, P1_RXBSPCR); 822 + t &= ~RXBSPCR_STUF_ENABLE; 823 + AX_WRITE(&ax_local->ax_spi, t, P1_RXBSPCR); 824 + 825 + /* Enable RX packet process */ 826 + AX_WRITE(&ax_local->ax_spi, RPPER_RXEN, P1_RPPER); 827 + 828 + t = AX_READ(&ax_local->ax_spi, P0_FER); 829 + t |= FER_RXEN | FER_TXEN | FER_BSWAP | FER_IRQ_PULL; 830 + AX_WRITE(&ax_local->ax_spi, t, P0_FER); 831 + 832 + /* Setup LED mode */ 833 + AX_WRITE(&ax_local->ax_spi, 834 + (LCR_LED0_EN | LCR_LED0_DUPLEX | LCR_LED1_EN | 835 + LCR_LED1_100MODE), P2_LCR0); 836 + AX_WRITE(&ax_local->ax_spi, 837 + (AX_READ(&ax_local->ax_spi, P2_LCR1) & LCR_LED2_MASK) | 838 + LCR_LED2_EN | LCR_LED2_LINK, P2_LCR1); 839 + 840 + /* Disable PHY auto-polling */ 841 + AX_WRITE(&ax_local->ax_spi, PCR_PHYID(AX88796C_PHY_ID), P2_PCR); 842 + 843 + /* Enable MAC interrupts */ 844 + AX_WRITE(&ax_local->ax_spi, IMR_DEFAULT, P0_IMR); 845 + 846 + mutex_unlock(&ax_local->spi_lock); 847 + 848 + /* Setup flow-control configuration */ 849 + phy_support_asym_pause(ax_local->phydev); 850 + 851 + if (ax_local->phydev->advertising && 852 + (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, 853 + ax_local->phydev->advertising) || 854 + linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 855 + ax_local->phydev->advertising))) 856 + fc |= AX_FC_ANEG; 857 + 858 + fc |= linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, 859 + ax_local->phydev->advertising) ? AX_FC_RX : 0; 860 + fc |= (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, 861 + ax_local->phydev->advertising) != 862 + linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, 863 + ax_local->phydev->advertising)) ? AX_FC_TX : 0; 864 + ax_local->flowctrl = fc; 865 + 866 + phy_start(ax_local->ndev->phydev); 867 + 868 + netif_start_queue(ndev); 869 + 870 + spi_message_init(&ax_local->ax_spi.rx_msg); 871 + 872 + return 0; 873 + } 874 + 875 + static int 876 + ax88796c_close(struct net_device *ndev) 877 + { 878 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 879 + 880 + phy_stop(ndev->phydev); 881 + 882 + /* We lock the mutex early not only to protect the device 883 + * against concurrent access, but also avoid waking up the 884 + * queue in ax88796c_work(). phy_stop() needs to be called 885 + * before because it locks the mutex to access SPI. 886 + */ 887 + mutex_lock(&ax_local->spi_lock); 888 + 889 + netif_stop_queue(ndev); 890 + 891 + /* No more work can be scheduled now. Make any pending work, 892 + * including one already waiting for the mutex to be unlocked, 893 + * NOP. 894 + */ 895 + netif_dbg(ax_local, ifdown, ndev, "clearing bits\n"); 896 + clear_bit(EVENT_SET_MULTI, &ax_local->flags); 897 + clear_bit(EVENT_INTR, &ax_local->flags); 898 + clear_bit(EVENT_TX, &ax_local->flags); 899 + 900 + /* Disable MAC interrupts */ 901 + AX_WRITE(&ax_local->ax_spi, IMR_MASKALL, P0_IMR); 902 + __skb_queue_purge(&ax_local->tx_wait_q); 903 + ax88796c_soft_reset(ax_local); 904 + 905 + mutex_unlock(&ax_local->spi_lock); 906 + 907 + cancel_work_sync(&ax_local->ax_work); 908 + 909 + free_irq(ndev->irq, ndev); 910 + 911 + return 0; 912 + } 913 + 914 + static int 915 + ax88796c_set_features(struct net_device *ndev, netdev_features_t features) 916 + { 917 + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); 918 + netdev_features_t changed = features ^ ndev->features; 919 + 920 + if (!(changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM))) 921 + return 0; 922 + 923 + ndev->features = features; 924 + 925 + if (changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM)) 926 + ax88796c_set_csums(ax_local); 927 + 928 + return 0; 929 + } 930 + 931 + static const struct net_device_ops ax88796c_netdev_ops = { 932 + .ndo_open = ax88796c_open, 933 + .ndo_stop = ax88796c_close, 934 + .ndo_start_xmit = ax88796c_start_xmit, 935 + .ndo_get_stats64 = ax88796c_get_stats64, 936 + .ndo_do_ioctl = ax88796c_ioctl, 937 + .ndo_set_mac_address = eth_mac_addr, 938 + .ndo_set_features = ax88796c_set_features, 939 + }; 940 + 941 + static int ax88796c_hard_reset(struct ax88796c_device *ax_local) 942 + { 943 + struct device *dev = (struct device *)&ax_local->spi->dev; 944 + struct gpio_desc *reset_gpio; 945 + 946 + /* reset info */ 947 + reset_gpio = gpiod_get(dev, "reset", 0); 948 + if (IS_ERR(reset_gpio)) { 949 + dev_err(dev, "Could not get 'reset' GPIO: %ld", PTR_ERR(reset_gpio)); 950 + return PTR_ERR(reset_gpio); 951 + } 952 + 953 + /* set reset */ 954 + gpiod_direction_output(reset_gpio, 1); 955 + msleep(100); 956 + gpiod_direction_output(reset_gpio, 0); 957 + gpiod_put(reset_gpio); 958 + msleep(20); 959 + 960 + return 0; 961 + } 962 + 963 + static int ax88796c_probe(struct spi_device *spi) 964 + { 965 + char phy_id[MII_BUS_ID_SIZE + 3]; 966 + struct ax88796c_device *ax_local; 967 + struct net_device *ndev; 968 + u16 temp; 969 + int ret; 970 + 971 + ndev = devm_alloc_etherdev(&spi->dev, sizeof(*ax_local)); 972 + if (!ndev) 973 + return -ENOMEM; 974 + 975 + SET_NETDEV_DEV(ndev, &spi->dev); 976 + 977 + ax_local = to_ax88796c_device(ndev); 978 + 979 + dev_set_drvdata(&spi->dev, ax_local); 980 + ax_local->spi = spi; 981 + ax_local->ax_spi.spi = spi; 982 + 983 + ax_local->stats = 984 + devm_netdev_alloc_pcpu_stats(&spi->dev, 985 + struct ax88796c_pcpu_stats); 986 + if (!ax_local->stats) 987 + return -ENOMEM; 988 + 989 + ax_local->ndev = ndev; 990 + ax_local->priv_flags |= comp ? AX_CAP_COMP : 0; 991 + ax_local->msg_enable = msg_enable; 992 + mutex_init(&ax_local->spi_lock); 993 + 994 + ax_local->mdiobus = devm_mdiobus_alloc(&spi->dev); 995 + if (!ax_local->mdiobus) 996 + return -ENOMEM; 997 + 998 + ax_local->mdiobus->priv = ax_local; 999 + ax_local->mdiobus->read = ax88796c_mdio_read; 1000 + ax_local->mdiobus->write = ax88796c_mdio_write; 1001 + ax_local->mdiobus->name = "ax88976c-mdiobus"; 1002 + ax_local->mdiobus->phy_mask = (u32)~BIT(AX88796C_PHY_ID); 1003 + ax_local->mdiobus->parent = &spi->dev; 1004 + 1005 + snprintf(ax_local->mdiobus->id, MII_BUS_ID_SIZE, 1006 + "ax88796c-%s.%u", dev_name(&spi->dev), spi->chip_select); 1007 + 1008 + ret = devm_mdiobus_register(&spi->dev, ax_local->mdiobus); 1009 + if (ret < 0) { 1010 + dev_err(&spi->dev, "Could not register MDIO bus\n"); 1011 + return ret; 1012 + } 1013 + 1014 + if (netif_msg_probe(ax_local)) { 1015 + dev_info(&spi->dev, "AX88796C-SPI Configuration:\n"); 1016 + dev_info(&spi->dev, " Compression : %s\n", 1017 + ax_local->priv_flags & AX_CAP_COMP ? "ON" : "OFF"); 1018 + } 1019 + 1020 + ndev->irq = spi->irq; 1021 + ndev->netdev_ops = &ax88796c_netdev_ops; 1022 + ndev->ethtool_ops = &ax88796c_ethtool_ops; 1023 + ndev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; 1024 + ndev->features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; 1025 + ndev->needed_headroom = TX_OVERHEAD; 1026 + ndev->needed_tailroom = TX_EOP_SIZE; 1027 + 1028 + mutex_lock(&ax_local->spi_lock); 1029 + 1030 + /* ax88796c gpio reset */ 1031 + ax88796c_hard_reset(ax_local); 1032 + 1033 + /* Reset AX88796C */ 1034 + ret = ax88796c_soft_reset(ax_local); 1035 + if (ret < 0) { 1036 + ret = -ENODEV; 1037 + mutex_unlock(&ax_local->spi_lock); 1038 + goto err; 1039 + } 1040 + /* Check board revision */ 1041 + temp = AX_READ(&ax_local->ax_spi, P2_CRIR); 1042 + if ((temp & 0xF) != 0x0) { 1043 + dev_err(&spi->dev, "spi read failed: %d\n", temp); 1044 + ret = -ENODEV; 1045 + mutex_unlock(&ax_local->spi_lock); 1046 + goto err; 1047 + } 1048 + 1049 + /*Reload EEPROM*/ 1050 + ax88796c_reload_eeprom(ax_local); 1051 + 1052 + ax88796c_load_mac_addr(ndev); 1053 + 1054 + if (netif_msg_probe(ax_local)) 1055 + dev_info(&spi->dev, 1056 + "irq %d, MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", 1057 + ndev->irq, 1058 + ndev->dev_addr[0], ndev->dev_addr[1], 1059 + ndev->dev_addr[2], ndev->dev_addr[3], 1060 + ndev->dev_addr[4], ndev->dev_addr[5]); 1061 + 1062 + /* Disable power saving */ 1063 + AX_WRITE(&ax_local->ax_spi, (AX_READ(&ax_local->ax_spi, P0_PSCR) 1064 + & PSCR_PS_MASK) | PSCR_PS_D0, P0_PSCR); 1065 + 1066 + mutex_unlock(&ax_local->spi_lock); 1067 + 1068 + INIT_WORK(&ax_local->ax_work, ax88796c_work); 1069 + 1070 + skb_queue_head_init(&ax_local->tx_wait_q); 1071 + 1072 + snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, 1073 + ax_local->mdiobus->id, AX88796C_PHY_ID); 1074 + ax_local->phydev = phy_connect(ax_local->ndev, phy_id, 1075 + ax88796c_handle_link_change, 1076 + PHY_INTERFACE_MODE_MII); 1077 + if (IS_ERR(ax_local->phydev)) { 1078 + ret = PTR_ERR(ax_local->phydev); 1079 + goto err; 1080 + } 1081 + ax_local->phydev->irq = PHY_POLL; 1082 + 1083 + ret = devm_register_netdev(&spi->dev, ndev); 1084 + if (ret) { 1085 + dev_err(&spi->dev, "failed to register a network device\n"); 1086 + goto err_phy_dis; 1087 + } 1088 + 1089 + netif_info(ax_local, probe, ndev, "%s %s registered\n", 1090 + dev_driver_string(&spi->dev), 1091 + dev_name(&spi->dev)); 1092 + phy_attached_info(ax_local->phydev); 1093 + 1094 + return 0; 1095 + 1096 + err_phy_dis: 1097 + phy_disconnect(ax_local->phydev); 1098 + err: 1099 + return ret; 1100 + } 1101 + 1102 + static int ax88796c_remove(struct spi_device *spi) 1103 + { 1104 + struct ax88796c_device *ax_local = dev_get_drvdata(&spi->dev); 1105 + struct net_device *ndev = ax_local->ndev; 1106 + 1107 + phy_disconnect(ndev->phydev); 1108 + 1109 + netif_info(ax_local, probe, ndev, "removing network device %s %s\n", 1110 + dev_driver_string(&spi->dev), 1111 + dev_name(&spi->dev)); 1112 + 1113 + return 0; 1114 + } 1115 + 1116 + static const struct of_device_id ax88796c_dt_ids[] = { 1117 + { .compatible = "asix,ax88796c" }, 1118 + {}, 1119 + }; 1120 + MODULE_DEVICE_TABLE(of, ax88796c_dt_ids); 1121 + 1122 + static const struct spi_device_id asix_id[] = { 1123 + { "ax88796c", 0 }, 1124 + { } 1125 + }; 1126 + MODULE_DEVICE_TABLE(spi, asix_id); 1127 + 1128 + static struct spi_driver ax88796c_spi_driver = { 1129 + .driver = { 1130 + .name = DRV_NAME, 1131 + .of_match_table = of_match_ptr(ax88796c_dt_ids), 1132 + }, 1133 + .probe = ax88796c_probe, 1134 + .remove = ax88796c_remove, 1135 + .id_table = asix_id, 1136 + }; 1137 + 1138 + static __init int ax88796c_spi_init(void) 1139 + { 1140 + int ret; 1141 + 1142 + bitmap_zero(ax88796c_no_regs_mask, AX88796C_REGDUMP_LEN); 1143 + ret = bitmap_parse(no_regs_list, 35, 1144 + ax88796c_no_regs_mask, AX88796C_REGDUMP_LEN); 1145 + if (ret) { 1146 + bitmap_fill(ax88796c_no_regs_mask, AX88796C_REGDUMP_LEN); 1147 + pr_err("Invalid bitmap description, masking all registers\n"); 1148 + } 1149 + 1150 + return spi_register_driver(&ax88796c_spi_driver); 1151 + } 1152 + 1153 + static __exit void ax88796c_spi_exit(void) 1154 + { 1155 + spi_unregister_driver(&ax88796c_spi_driver); 1156 + } 1157 + 1158 + module_init(ax88796c_spi_init); 1159 + module_exit(ax88796c_spi_exit); 1160 + 1161 + MODULE_AUTHOR("Łukasz Stelmach <l.stelmach@samsung.com>"); 1162 + MODULE_DESCRIPTION("ASIX AX88796C SPI Ethernet driver"); 1163 + MODULE_LICENSE("GPL");
+568
drivers/net/ethernet/asix/ax88796c_main.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2010 ASIX Electronics Corporation 4 + * Copyright (c) 2020 Samsung Electronics 5 + * 6 + * ASIX AX88796C SPI Fast Ethernet Linux driver 7 + */ 8 + 9 + #ifndef _AX88796C_MAIN_H 10 + #define _AX88796C_MAIN_H 11 + 12 + #include <linux/netdevice.h> 13 + #include <linux/mii.h> 14 + 15 + #include "ax88796c_spi.h" 16 + 17 + /* These identify the driver base version and may not be removed. */ 18 + #define DRV_NAME "ax88796c" 19 + #define ADP_NAME "ASIX AX88796C SPI Ethernet Adapter" 20 + 21 + #define TX_QUEUE_HIGH_WATER 45 /* Tx queue high water mark */ 22 + #define TX_QUEUE_LOW_WATER 20 /* Tx queue low water mark */ 23 + 24 + #define AX88796C_REGDUMP_LEN 256 25 + #define AX88796C_PHY_REGDUMP_LEN 14 26 + #define AX88796C_PHY_ID 0x10 27 + 28 + #define TX_OVERHEAD 8 29 + #define TX_EOP_SIZE 4 30 + 31 + #define AX_MCAST_FILTER_SIZE 8 32 + #define AX_MAX_MCAST 64 33 + #define AX_MAX_CLK 80000000 34 + #define TX_HDR_SOP_DICF 0x8000 35 + #define TX_HDR_SOP_CPHI 0x4000 36 + #define TX_HDR_SOP_INT 0x2000 37 + #define TX_HDR_SOP_MDEQ 0x1000 38 + #define TX_HDR_SOP_PKTLEN 0x07FF 39 + #define TX_HDR_SOP_SEQNUM 0xF800 40 + #define TX_HDR_SOP_PKTLENBAR 0x07FF 41 + 42 + #define TX_HDR_SEG_FS 0x8000 43 + #define TX_HDR_SEG_LS 0x4000 44 + #define TX_HDR_SEG_SEGNUM 0x3800 45 + #define TX_HDR_SEG_SEGLEN 0x0700 46 + #define TX_HDR_SEG_EOFST 0xC000 47 + #define TX_HDR_SEG_SOFST 0x3800 48 + #define TX_HDR_SEG_SEGLENBAR 0x07FF 49 + 50 + #define TX_HDR_EOP_SEQNUM 0xF800 51 + #define TX_HDR_EOP_PKTLEN 0x07FF 52 + #define TX_HDR_EOP_SEQNUMBAR 0xF800 53 + #define TX_HDR_EOP_PKTLENBAR 0x07FF 54 + 55 + /* Rx header fields mask */ 56 + #define RX_HDR1_MCBC 0x8000 57 + #define RX_HDR1_STUFF_PKT 0x4000 58 + #define RX_HDR1_MII_ERR 0x2000 59 + #define RX_HDR1_CRC_ERR 0x1000 60 + #define RX_HDR1_PKT_LEN 0x07FF 61 + 62 + #define RX_HDR2_SEQ_NUM 0xF800 63 + #define RX_HDR2_PKT_LEN_BAR 0x7FFF 64 + 65 + #define RX_HDR3_PE 0x8000 66 + #define RX_HDR3_L3_TYPE_IPV4V6 0x6000 67 + #define RX_HDR3_L3_TYPE_IP 0x4000 68 + #define RX_HDR3_L3_TYPE_IPV6 0x2000 69 + #define RX_HDR3_L4_TYPE_ICMPV6 0x1400 70 + #define RX_HDR3_L4_TYPE_TCP 0x1000 71 + #define RX_HDR3_L4_TYPE_IGMP 0x0c00 72 + #define RX_HDR3_L4_TYPE_ICMP 0x0800 73 + #define RX_HDR3_L4_TYPE_UDP 0x0400 74 + #define RX_HDR3_L3_ERR 0x0200 75 + #define RX_HDR3_L4_ERR 0x0100 76 + #define RX_HDR3_PRIORITY(x) ((x) << 4) 77 + #define RX_HDR3_STRIP 0x0008 78 + #define RX_HDR3_VLAN_ID 0x0007 79 + 80 + struct ax88796c_pcpu_stats { 81 + u64_stats_t rx_packets; 82 + u64_stats_t rx_bytes; 83 + u64_stats_t tx_packets; 84 + u64_stats_t tx_bytes; 85 + struct u64_stats_sync syncp; 86 + u32 rx_dropped; 87 + u32 tx_dropped; 88 + u32 rx_frame_errors; 89 + u32 rx_crc_errors; 90 + }; 91 + 92 + struct ax88796c_device { 93 + struct spi_device *spi; 94 + struct net_device *ndev; 95 + struct ax88796c_pcpu_stats __percpu *stats; 96 + 97 + struct work_struct ax_work; 98 + 99 + struct mutex spi_lock; /* device access */ 100 + 101 + struct sk_buff_head tx_wait_q; 102 + 103 + struct axspi_data ax_spi; 104 + 105 + struct mii_bus *mdiobus; 106 + struct phy_device *phydev; 107 + 108 + int msg_enable; 109 + 110 + u16 seq_num; 111 + 112 + u8 multi_filter[AX_MCAST_FILTER_SIZE]; 113 + 114 + int link; 115 + int speed; 116 + int duplex; 117 + int pause; 118 + int asym_pause; 119 + int flowctrl; 120 + #define AX_FC_NONE 0 121 + #define AX_FC_RX BIT(0) 122 + #define AX_FC_TX BIT(1) 123 + #define AX_FC_ANEG BIT(2) 124 + 125 + u32 priv_flags; 126 + #define AX_CAP_COMP BIT(0) 127 + #define AX_PRIV_FLAGS_MASK (AX_CAP_COMP) 128 + 129 + unsigned long flags; 130 + #define EVENT_INTR BIT(0) 131 + #define EVENT_TX BIT(1) 132 + #define EVENT_SET_MULTI BIT(2) 133 + 134 + }; 135 + 136 + #define to_ax88796c_device(ndev) ((struct ax88796c_device *)netdev_priv(ndev)) 137 + 138 + enum skb_state { 139 + illegal = 0, 140 + tx_done, 141 + rx_done, 142 + rx_err, 143 + }; 144 + 145 + struct skb_data { 146 + enum skb_state state; 147 + size_t len; 148 + }; 149 + 150 + /* A88796C register definition */ 151 + /* Definition of PAGE0 */ 152 + #define P0_PSR (0x00) 153 + #define PSR_DEV_READY BIT(7) 154 + #define PSR_RESET (0 << 15) 155 + #define PSR_RESET_CLR BIT(15) 156 + #define P0_BOR (0x02) 157 + #define P0_FER (0x04) 158 + #define FER_IPALM BIT(0) 159 + #define FER_DCRC BIT(1) 160 + #define FER_RH3M BIT(2) 161 + #define FER_HEADERSWAP BIT(7) 162 + #define FER_WSWAP BIT(8) 163 + #define FER_BSWAP BIT(9) 164 + #define FER_INTHI BIT(10) 165 + #define FER_INTLO (0 << 10) 166 + #define FER_IRQ_PULL BIT(11) 167 + #define FER_RXEN BIT(14) 168 + #define FER_TXEN BIT(15) 169 + #define P0_ISR (0x06) 170 + #define ISR_RXPKT BIT(0) 171 + #define ISR_MDQ BIT(4) 172 + #define ISR_TXT BIT(5) 173 + #define ISR_TXPAGES BIT(6) 174 + #define ISR_TXERR BIT(8) 175 + #define ISR_LINK BIT(9) 176 + #define P0_IMR (0x08) 177 + #define IMR_RXPKT BIT(0) 178 + #define IMR_MDQ BIT(4) 179 + #define IMR_TXT BIT(5) 180 + #define IMR_TXPAGES BIT(6) 181 + #define IMR_TXERR BIT(8) 182 + #define IMR_LINK BIT(9) 183 + #define IMR_MASKALL (0xFFFF) 184 + #define IMR_DEFAULT (IMR_TXERR) 185 + #define P0_WFCR (0x0A) 186 + #define WFCR_PMEIND BIT(0) /* PME indication */ 187 + #define WFCR_PMETYPE BIT(1) /* PME I/O type */ 188 + #define WFCR_PMEPOL BIT(2) /* PME polarity */ 189 + #define WFCR_PMERST BIT(3) /* Reset PME */ 190 + #define WFCR_SLEEP BIT(4) /* Enable sleep mode */ 191 + #define WFCR_WAKEUP BIT(5) /* Enable wakeup mode */ 192 + #define WFCR_WAITEVENT BIT(6) /* Reserved */ 193 + #define WFCR_CLRWAKE BIT(7) /* Clear wakeup */ 194 + #define WFCR_LINKCH BIT(8) /* Enable link change */ 195 + #define WFCR_MAGICP BIT(9) /* Enable magic packet */ 196 + #define WFCR_WAKEF BIT(10) /* Enable wakeup frame */ 197 + #define WFCR_PMEEN BIT(11) /* Enable PME pin */ 198 + #define WFCR_LINKCHS BIT(12) /* Link change status */ 199 + #define WFCR_MAGICPS BIT(13) /* Magic packet status */ 200 + #define WFCR_WAKEFS BIT(14) /* Wakeup frame status */ 201 + #define WFCR_PMES BIT(15) /* PME pin status */ 202 + #define P0_PSCR (0x0C) 203 + #define PSCR_PS_MASK (0xFFF0) 204 + #define PSCR_PS_D0 (0) 205 + #define PSCR_PS_D1 BIT(0) 206 + #define PSCR_PS_D2 BIT(1) 207 + #define PSCR_FPS BIT(3) /* Enable fiber mode PS */ 208 + #define PSCR_SWPS BIT(4) /* Enable software */ 209 + /* PS control */ 210 + #define PSCR_WOLPS BIT(5) /* Enable WOL PS */ 211 + #define PSCR_SWWOL BIT(6) /* Enable software select */ 212 + /* WOL PS */ 213 + #define PSCR_PHYOSC BIT(7) /* Internal PHY OSC control */ 214 + #define PSCR_FOFEF BIT(8) /* Force PHY generate FEF */ 215 + #define PSCR_FOF BIT(9) /* Force PHY in fiber mode */ 216 + #define PSCR_PHYPD BIT(10) /* PHY power down. */ 217 + /* Active high */ 218 + #define PSCR_PHYRST BIT(11) /* PHY reset signal. */ 219 + /* Active low */ 220 + #define PSCR_PHYCSIL BIT(12) /* PHY cable energy detect */ 221 + #define PSCR_PHYCOFF BIT(13) /* PHY cable off */ 222 + #define PSCR_PHYLINK BIT(14) /* PHY link status */ 223 + #define PSCR_EEPOK BIT(15) /* EEPROM load complete */ 224 + #define P0_MACCR (0x0E) 225 + #define MACCR_RXEN BIT(0) /* Enable RX */ 226 + #define MACCR_DUPLEX_FULL BIT(1) /* 1: Full, 0: Half */ 227 + #define MACCR_SPEED_100 BIT(2) /* 1: 100Mbps, 0: 10Mbps */ 228 + #define MACCR_RXFC_ENABLE BIT(3) 229 + #define MACCR_RXFC_MASK 0xFFF7 230 + #define MACCR_TXFC_ENABLE BIT(4) 231 + #define MACCR_TXFC_MASK 0xFFEF 232 + #define MACCR_PSI BIT(6) /* Software Cable-Off */ 233 + /* Power Saving Interrupt */ 234 + #define MACCR_PF BIT(7) 235 + #define MACCR_PMM_BITS 8 236 + #define MACCR_PMM_MASK (0x1F00) 237 + #define MACCR_PMM_RESET BIT(8) 238 + #define MACCR_PMM_WAIT (2 << 8) 239 + #define MACCR_PMM_READY (3 << 8) 240 + #define MACCR_PMM_D1 (4 << 8) 241 + #define MACCR_PMM_D2 (5 << 8) 242 + #define MACCR_PMM_WAKE (7 << 8) 243 + #define MACCR_PMM_D1_WAKE (8 << 8) 244 + #define MACCR_PMM_D2_WAKE (9 << 8) 245 + #define MACCR_PMM_SLEEP (10 << 8) 246 + #define MACCR_PMM_PHY_RESET (11 << 8) 247 + #define MACCR_PMM_SOFT_D1 (16 << 8) 248 + #define MACCR_PMM_SOFT_D2 (17 << 8) 249 + #define P0_TFBFCR (0x10) 250 + #define TFBFCR_SCHE_FREE_PAGE 0xE07F 251 + #define TFBFCR_FREE_PAGE_BITS 0x07 252 + #define TFBFCR_FREE_PAGE_LATCH BIT(6) 253 + #define TFBFCR_SET_FREE_PAGE(x) (((x) & 0x3F) << TFBFCR_FREE_PAGE_BITS) 254 + #define TFBFCR_TX_PAGE_SET BIT(13) 255 + #define TFBFCR_MANU_ENTX BIT(15) 256 + #define TX_FREEBUF_MASK 0x003F 257 + #define TX_DPTSTART 0x4000 258 + 259 + #define P0_TSNR (0x12) 260 + #define TXNR_TXB_ERR BIT(5) 261 + #define TXNR_TXB_IDLE BIT(6) 262 + #define TSNR_PKT_CNT(x) (((x) & 0x3F) << 8) 263 + #define TXNR_TXB_REINIT BIT(14) 264 + #define TSNR_TXB_START BIT(15) 265 + #define P0_RTDPR (0x14) 266 + #define P0_RXBCR1 (0x16) 267 + #define RXBCR1_RXB_DISCARD BIT(14) 268 + #define RXBCR1_RXB_START BIT(15) 269 + #define P0_RXBCR2 (0x18) 270 + #define RXBCR2_PKT_MASK (0xFF) 271 + #define RXBCR2_RXPC_MASK (0x7F) 272 + #define RXBCR2_RXB_READY BIT(13) 273 + #define RXBCR2_RXB_IDLE BIT(14) 274 + #define RXBCR2_RXB_REINIT BIT(15) 275 + #define P0_RTWCR (0x1A) 276 + #define RTWCR_RXWC_MASK (0x3FFF) 277 + #define RTWCR_RX_LATCH BIT(15) 278 + #define P0_RCPHR (0x1C) 279 + 280 + /* Definition of PAGE1 */ 281 + #define P1_RPPER (0x22) 282 + #define RPPER_RXEN BIT(0) 283 + #define P1_MRCR (0x28) 284 + #define P1_MDR (0x2A) 285 + #define P1_RMPR (0x2C) 286 + #define P1_TMPR (0x2E) 287 + #define P1_RXBSPCR (0x30) 288 + #define RXBSPCR_STUF_WORD_CNT(x) (((x) & 0x7000) >> 12) 289 + #define RXBSPCR_STUF_ENABLE BIT(15) 290 + #define P1_MCR (0x32) 291 + #define MCR_SBP BIT(8) 292 + #define MCR_SM BIT(9) 293 + #define MCR_CRCENLAN BIT(11) 294 + #define MCR_STP BIT(12) 295 + /* Definition of PAGE2 */ 296 + #define P2_CIR (0x42) 297 + #define P2_PCR (0x44) 298 + #define PCR_POLL_EN BIT(0) 299 + #define PCR_POLL_FLOWCTRL BIT(1) 300 + #define PCR_POLL_BMCR BIT(2) 301 + #define PCR_PHYID(x) ((x) << 8) 302 + #define P2_PHYSR (0x46) 303 + #define P2_MDIODR (0x48) 304 + #define P2_MDIOCR (0x4A) 305 + #define MDIOCR_RADDR(x) ((x) & 0x1F) 306 + #define MDIOCR_FADDR(x) (((x) & 0x1F) << 8) 307 + #define MDIOCR_VALID BIT(13) 308 + #define MDIOCR_READ BIT(14) 309 + #define MDIOCR_WRITE BIT(15) 310 + #define P2_LCR0 (0x4C) 311 + #define LCR_LED0_EN BIT(0) 312 + #define LCR_LED0_100MODE BIT(1) 313 + #define LCR_LED0_DUPLEX BIT(2) 314 + #define LCR_LED0_LINK BIT(3) 315 + #define LCR_LED0_ACT BIT(4) 316 + #define LCR_LED0_COL BIT(5) 317 + #define LCR_LED0_10MODE BIT(6) 318 + #define LCR_LED0_DUPCOL BIT(7) 319 + #define LCR_LED1_EN BIT(8) 320 + #define LCR_LED1_100MODE BIT(9) 321 + #define LCR_LED1_DUPLEX BIT(10) 322 + #define LCR_LED1_LINK BIT(11) 323 + #define LCR_LED1_ACT BIT(12) 324 + #define LCR_LED1_COL BIT(13) 325 + #define LCR_LED1_10MODE BIT(14) 326 + #define LCR_LED1_DUPCOL BIT(15) 327 + #define P2_LCR1 (0x4E) 328 + #define LCR_LED2_MASK (0xFF00) 329 + #define LCR_LED2_EN BIT(0) 330 + #define LCR_LED2_100MODE BIT(1) 331 + #define LCR_LED2_DUPLEX BIT(2) 332 + #define LCR_LED2_LINK BIT(3) 333 + #define LCR_LED2_ACT BIT(4) 334 + #define LCR_LED2_COL BIT(5) 335 + #define LCR_LED2_10MODE BIT(6) 336 + #define LCR_LED2_DUPCOL BIT(7) 337 + #define P2_IPGCR (0x50) 338 + #define P2_CRIR (0x52) 339 + #define P2_FLHWCR (0x54) 340 + #define P2_RXCR (0x56) 341 + #define RXCR_PRO BIT(0) 342 + #define RXCR_AMALL BIT(1) 343 + #define RXCR_SEP BIT(2) 344 + #define RXCR_AB BIT(3) 345 + #define RXCR_AM BIT(4) 346 + #define RXCR_AP BIT(5) 347 + #define RXCR_ARP BIT(6) 348 + #define P2_JLCR (0x58) 349 + #define P2_MPLR (0x5C) 350 + 351 + /* Definition of PAGE3 */ 352 + #define P3_MACASR0 (0x62) 353 + #define P3_MACASR(x) (P3_MACASR0 + 2 * (x)) 354 + #define MACASR_LOWBYTE_MASK 0x00FF 355 + #define MACASR_HIGH_BITS 0x08 356 + #define P3_MACASR1 (0x64) 357 + #define P3_MACASR2 (0x66) 358 + #define P3_MFAR01 (0x68) 359 + #define P3_MFAR_BASE (0x68) 360 + #define P3_MFAR(x) (P3_MFAR_BASE + 2 * (x)) 361 + 362 + #define P3_MFAR23 (0x6A) 363 + #define P3_MFAR45 (0x6C) 364 + #define P3_MFAR67 (0x6E) 365 + #define P3_VID0FR (0x70) 366 + #define P3_VID1FR (0x72) 367 + #define P3_EECSR (0x74) 368 + #define P3_EEDR (0x76) 369 + #define P3_EECR (0x78) 370 + #define EECR_ADDR_MASK (0x00FF) 371 + #define EECR_READ_ACT BIT(8) 372 + #define EECR_WRITE_ACT BIT(9) 373 + #define EECR_WRITE_DISABLE BIT(10) 374 + #define EECR_WRITE_ENABLE BIT(11) 375 + #define EECR_EE_READY BIT(13) 376 + #define EECR_RELOAD BIT(14) 377 + #define EECR_RESET BIT(15) 378 + #define P3_TPCR (0x7A) 379 + #define TPCR_PATT_MASK (0xFF) 380 + #define TPCR_RAND_PKT_EN BIT(14) 381 + #define TPCR_FIXED_PKT_EN BIT(15) 382 + #define P3_TPLR (0x7C) 383 + /* Definition of PAGE4 */ 384 + #define P4_SPICR (0x8A) 385 + #define SPICR_RCEN BIT(0) 386 + #define SPICR_QCEN BIT(1) 387 + #define SPICR_RBRE BIT(3) 388 + #define SPICR_PMM BIT(4) 389 + #define SPICR_LOOPBACK BIT(8) 390 + #define SPICR_CORE_RES_CLR BIT(10) 391 + #define SPICR_SPI_RES_CLR BIT(11) 392 + #define P4_SPIISMR (0x8C) 393 + 394 + #define P4_COERCR0 (0x92) 395 + #define COERCR0_RXIPCE BIT(0) 396 + #define COERCR0_RXIPVE BIT(1) 397 + #define COERCR0_RXV6PE BIT(2) 398 + #define COERCR0_RXTCPE BIT(3) 399 + #define COERCR0_RXUDPE BIT(4) 400 + #define COERCR0_RXICMP BIT(5) 401 + #define COERCR0_RXIGMP BIT(6) 402 + #define COERCR0_RXICV6 BIT(7) 403 + 404 + #define COERCR0_RXTCPV6 BIT(8) 405 + #define COERCR0_RXUDPV6 BIT(9) 406 + #define COERCR0_RXICMV6 BIT(10) 407 + #define COERCR0_RXIGMV6 BIT(11) 408 + #define COERCR0_RXICV6V6 BIT(12) 409 + 410 + #define COERCR0_DEFAULT (COERCR0_RXIPCE | COERCR0_RXV6PE | \ 411 + COERCR0_RXTCPE | COERCR0_RXUDPE | \ 412 + COERCR0_RXTCPV6 | COERCR0_RXUDPV6) 413 + #define P4_COERCR1 (0x94) 414 + #define COERCR1_IPCEDP BIT(0) 415 + #define COERCR1_IPVEDP BIT(1) 416 + #define COERCR1_V6VEDP BIT(2) 417 + #define COERCR1_TCPEDP BIT(3) 418 + #define COERCR1_UDPEDP BIT(4) 419 + #define COERCR1_ICMPDP BIT(5) 420 + #define COERCR1_IGMPDP BIT(6) 421 + #define COERCR1_ICV6DP BIT(7) 422 + #define COERCR1_RX64TE BIT(8) 423 + #define COERCR1_RXPPPE BIT(9) 424 + #define COERCR1_TCP6DP BIT(10) 425 + #define COERCR1_UDP6DP BIT(11) 426 + #define COERCR1_IC6DP BIT(12) 427 + #define COERCR1_IG6DP BIT(13) 428 + #define COERCR1_ICV66DP BIT(14) 429 + #define COERCR1_RPCE BIT(15) 430 + 431 + #define COERCR1_DEFAULT (COERCR1_RXPPPE) 432 + 433 + #define P4_COETCR0 (0x96) 434 + #define COETCR0_TXIP BIT(0) 435 + #define COETCR0_TXTCP BIT(1) 436 + #define COETCR0_TXUDP BIT(2) 437 + #define COETCR0_TXICMP BIT(3) 438 + #define COETCR0_TXIGMP BIT(4) 439 + #define COETCR0_TXICV6 BIT(5) 440 + #define COETCR0_TXTCPV6 BIT(8) 441 + #define COETCR0_TXUDPV6 BIT(9) 442 + #define COETCR0_TXICMV6 BIT(10) 443 + #define COETCR0_TXIGMV6 BIT(11) 444 + #define COETCR0_TXICV6V6 BIT(12) 445 + 446 + #define COETCR0_DEFAULT (COETCR0_TXIP | COETCR0_TXTCP | \ 447 + COETCR0_TXUDP | COETCR0_TXTCPV6 | \ 448 + COETCR0_TXUDPV6) 449 + #define P4_COETCR1 (0x98) 450 + #define COETCR1_TX64TE BIT(0) 451 + #define COETCR1_TXPPPE BIT(1) 452 + 453 + #define P4_COECEDR (0x9A) 454 + #define P4_L2CECR (0x9C) 455 + 456 + /* Definition of PAGE5 */ 457 + #define P5_WFTR (0xA2) 458 + #define WFTR_2MS (0x01) 459 + #define WFTR_4MS (0x02) 460 + #define WFTR_8MS (0x03) 461 + #define WFTR_16MS (0x04) 462 + #define WFTR_32MS (0x05) 463 + #define WFTR_64MS (0x06) 464 + #define WFTR_128MS (0x07) 465 + #define WFTR_256MS (0x08) 466 + #define WFTR_512MS (0x09) 467 + #define WFTR_1024MS (0x0A) 468 + #define WFTR_2048MS (0x0B) 469 + #define WFTR_4096MS (0x0C) 470 + #define WFTR_8192MS (0x0D) 471 + #define WFTR_16384MS (0x0E) 472 + #define WFTR_32768MS (0x0F) 473 + #define P5_WFCCR (0xA4) 474 + #define P5_WFCR03 (0xA6) 475 + #define WFCR03_F0_EN BIT(0) 476 + #define WFCR03_F1_EN BIT(4) 477 + #define WFCR03_F2_EN BIT(8) 478 + #define WFCR03_F3_EN BIT(12) 479 + #define P5_WFCR47 (0xA8) 480 + #define WFCR47_F4_EN BIT(0) 481 + #define WFCR47_F5_EN BIT(4) 482 + #define WFCR47_F6_EN BIT(8) 483 + #define WFCR47_F7_EN BIT(12) 484 + #define P5_WF0BMR0 (0xAA) 485 + #define P5_WF0BMR1 (0xAC) 486 + #define P5_WF0CR (0xAE) 487 + #define P5_WF0OBR (0xB0) 488 + #define P5_WF1BMR0 (0xB2) 489 + #define P5_WF1BMR1 (0xB4) 490 + #define P5_WF1CR (0xB6) 491 + #define P5_WF1OBR (0xB8) 492 + #define P5_WF2BMR0 (0xBA) 493 + #define P5_WF2BMR1 (0xBC) 494 + 495 + /* Definition of PAGE6 */ 496 + #define P6_WF2CR (0xC2) 497 + #define P6_WF2OBR (0xC4) 498 + #define P6_WF3BMR0 (0xC6) 499 + #define P6_WF3BMR1 (0xC8) 500 + #define P6_WF3CR (0xCA) 501 + #define P6_WF3OBR (0xCC) 502 + #define P6_WF4BMR0 (0xCE) 503 + #define P6_WF4BMR1 (0xD0) 504 + #define P6_WF4CR (0xD2) 505 + #define P6_WF4OBR (0xD4) 506 + #define P6_WF5BMR0 (0xD6) 507 + #define P6_WF5BMR1 (0xD8) 508 + #define P6_WF5CR (0xDA) 509 + #define P6_WF5OBR (0xDC) 510 + 511 + /* Definition of PAGE7 */ 512 + #define P7_WF6BMR0 (0xE2) 513 + #define P7_WF6BMR1 (0xE4) 514 + #define P7_WF6CR (0xE6) 515 + #define P7_WF6OBR (0xE8) 516 + #define P7_WF7BMR0 (0xEA) 517 + #define P7_WF7BMR1 (0xEC) 518 + #define P7_WF7CR (0xEE) 519 + #define P7_WF7OBR (0xF0) 520 + #define P7_WFR01 (0xF2) 521 + #define P7_WFR23 (0xF4) 522 + #define P7_WFR45 (0xF6) 523 + #define P7_WFR67 (0xF8) 524 + #define P7_WFPC0 (0xFA) 525 + #define P7_WFPC1 (0xFC) 526 + 527 + /* Tx headers structure */ 528 + struct tx_sop_header { 529 + /* bit 15-11: flags, bit 10-0: packet length */ 530 + u16 flags_len; 531 + /* bit 15-11: sequence number, bit 11-0: packet length bar */ 532 + u16 seq_lenbar; 533 + }; 534 + 535 + struct tx_segment_header { 536 + /* bit 15-14: flags, bit 13-11: segment number */ 537 + /* bit 10-0: segment length */ 538 + u16 flags_seqnum_seglen; 539 + /* bit 15-14: end offset, bit 13-11: start offset */ 540 + /* bit 10-0: segment length bar */ 541 + u16 eo_so_seglenbar; 542 + }; 543 + 544 + struct tx_eop_header { 545 + /* bit 15-11: sequence number, bit 10-0: packet length */ 546 + u16 seq_len; 547 + /* bit 15-11: sequence number bar, bit 10-0: packet length bar */ 548 + u16 seqbar_lenbar; 549 + }; 550 + 551 + struct tx_pkt_info { 552 + struct tx_sop_header sop; 553 + struct tx_segment_header seg; 554 + struct tx_eop_header eop; 555 + u16 pkt_len; 556 + u16 seq_num; 557 + }; 558 + 559 + /* Rx headers structure */ 560 + struct rx_header { 561 + u16 flags_len; 562 + u16 seq_lenbar; 563 + u16 flags; 564 + }; 565 + 566 + extern unsigned long ax88796c_no_regs_mask[]; 567 + 568 + #endif /* #ifndef _AX88796C_MAIN_H */
+115
drivers/net/ethernet/asix/ax88796c_spi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2010 ASIX Electronics Corporation 4 + * Copyright (c) 2020 Samsung Electronics Co., Ltd. 5 + * 6 + * ASIX AX88796C SPI Fast Ethernet Linux driver 7 + */ 8 + 9 + #define pr_fmt(fmt) "ax88796c: " fmt 10 + 11 + #include <linux/string.h> 12 + #include <linux/spi/spi.h> 13 + 14 + #include "ax88796c_spi.h" 15 + 16 + const u8 ax88796c_rx_cmd_buf[5] = {AX_SPICMD_READ_RXQ, 0xFF, 0xFF, 0xFF, 0xFF}; 17 + const u8 ax88796c_tx_cmd_buf[4] = {AX_SPICMD_WRITE_TXQ, 0xFF, 0xFF, 0xFF}; 18 + 19 + /* driver bus management functions */ 20 + int axspi_wakeup(struct axspi_data *ax_spi) 21 + { 22 + int ret; 23 + 24 + ax_spi->cmd_buf[0] = AX_SPICMD_EXIT_PWD; /* OP */ 25 + ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 1); 26 + if (ret) 27 + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 28 + return ret; 29 + } 30 + 31 + int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status) 32 + { 33 + int ret; 34 + 35 + /* OP */ 36 + ax_spi->cmd_buf[0] = AX_SPICMD_READ_STATUS; 37 + ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)&status, 3); 38 + if (ret) 39 + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 40 + else 41 + le16_to_cpus(&status->isr); 42 + 43 + return ret; 44 + } 45 + 46 + int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len) 47 + { 48 + struct spi_transfer *xfer = ax_spi->spi_rx_xfer; 49 + int ret; 50 + 51 + memcpy(ax_spi->cmd_buf, ax88796c_rx_cmd_buf, 5); 52 + 53 + xfer->tx_buf = ax_spi->cmd_buf; 54 + xfer->rx_buf = NULL; 55 + xfer->len = ax_spi->comp ? 2 : 5; 56 + xfer->bits_per_word = 8; 57 + spi_message_add_tail(xfer, &ax_spi->rx_msg); 58 + 59 + xfer++; 60 + xfer->rx_buf = data; 61 + xfer->tx_buf = NULL; 62 + xfer->len = len; 63 + xfer->bits_per_word = 8; 64 + spi_message_add_tail(xfer, &ax_spi->rx_msg); 65 + ret = spi_sync(ax_spi->spi, &ax_spi->rx_msg); 66 + if (ret) 67 + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 68 + 69 + return ret; 70 + } 71 + 72 + int axspi_write_txq(const struct axspi_data *ax_spi, void *data, int len) 73 + { 74 + return spi_write(ax_spi->spi, data, len); 75 + } 76 + 77 + u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg) 78 + { 79 + int ret; 80 + int len = ax_spi->comp ? 3 : 4; 81 + 82 + ax_spi->cmd_buf[0] = 0x03; /* OP code read register */ 83 + ax_spi->cmd_buf[1] = reg; /* register address */ 84 + ax_spi->cmd_buf[2] = 0xFF; /* dumy cycle */ 85 + ax_spi->cmd_buf[3] = 0xFF; /* dumy cycle */ 86 + ret = spi_write_then_read(ax_spi->spi, 87 + ax_spi->cmd_buf, len, 88 + ax_spi->rx_buf, 2); 89 + if (ret) { 90 + dev_err(&ax_spi->spi->dev, 91 + "%s() failed: ret = %d\n", __func__, ret); 92 + return 0xFFFF; 93 + } 94 + 95 + le16_to_cpus((u16 *)ax_spi->rx_buf); 96 + 97 + return *(u16 *)ax_spi->rx_buf; 98 + } 99 + 100 + int axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value) 101 + { 102 + int ret; 103 + 104 + memset(ax_spi->cmd_buf, 0, sizeof(ax_spi->cmd_buf)); 105 + ax_spi->cmd_buf[0] = AX_SPICMD_WRITE_REG; /* OP code read register */ 106 + ax_spi->cmd_buf[1] = reg; /* register address */ 107 + ax_spi->cmd_buf[2] = value; 108 + ax_spi->cmd_buf[3] = value >> 8; 109 + 110 + ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 4); 111 + if (ret) 112 + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 113 + return ret; 114 + } 115 +
+69
drivers/net/ethernet/asix/ax88796c_spi.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2010 ASIX Electronics Corporation 4 + * Copyright (c) 2020 Samsung Electronics Co., Ltd. 5 + * 6 + * ASIX AX88796C SPI Fast Ethernet Linux driver 7 + */ 8 + 9 + #ifndef _AX88796C_SPI_H 10 + #define _AX88796C_SPI_H 11 + 12 + #include <linux/spi/spi.h> 13 + #include <linux/types.h> 14 + 15 + /* Definition of SPI command */ 16 + #define AX_SPICMD_WRITE_TXQ 0x02 17 + #define AX_SPICMD_READ_REG 0x03 18 + #define AX_SPICMD_READ_STATUS 0x05 19 + #define AX_SPICMD_READ_RXQ 0x0B 20 + #define AX_SPICMD_BIDIR_WRQ 0xB2 21 + #define AX_SPICMD_WRITE_REG 0xD8 22 + #define AX_SPICMD_EXIT_PWD 0xAB 23 + 24 + extern const u8 ax88796c_rx_cmd_buf[]; 25 + extern const u8 ax88796c_tx_cmd_buf[]; 26 + 27 + struct axspi_data { 28 + struct spi_device *spi; 29 + struct spi_message rx_msg; 30 + struct spi_transfer spi_rx_xfer[2]; 31 + u8 cmd_buf[6]; 32 + u8 rx_buf[6]; 33 + u8 comp; 34 + }; 35 + 36 + struct spi_status { 37 + u16 isr; 38 + u8 status; 39 + # define AX_STATUS_READY 0x80 40 + }; 41 + 42 + int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len); 43 + int axspi_write_txq(const struct axspi_data *ax_spi, void *data, int len); 44 + u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg); 45 + int axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value); 46 + int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status); 47 + int axspi_wakeup(struct axspi_data *ax_spi); 48 + 49 + static inline u16 AX_READ(struct axspi_data *ax_spi, u8 offset) 50 + { 51 + return axspi_read_reg(ax_spi, offset); 52 + } 53 + 54 + static inline int AX_WRITE(struct axspi_data *ax_spi, u16 value, u8 offset) 55 + { 56 + return axspi_write_reg(ax_spi, offset, value); 57 + } 58 + 59 + static inline int AX_READ_STATUS(struct axspi_data *ax_spi, 60 + struct spi_status *status) 61 + { 62 + return axspi_read_status(ax_spi, status); 63 + } 64 + 65 + static inline int AX_WAKEUP(struct axspi_data *ax_spi) 66 + { 67 + return axspi_wakeup(ax_spi); 68 + } 69 + #endif