^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Ethernet driver for the WIZnet W5100 chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006-2008 WIZnet Co.,Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2012 Mike Sinkovsky <msink@permonline.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_data/wiznet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "w5100.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DRV_NAME "w5100"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define DRV_VERSION "2012-04-04"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_DESCRIPTION("WIZnet W5100 Ethernet driver v"DRV_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MODULE_AUTHOR("Mike Sinkovsky <msink@permonline.ru>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) MODULE_ALIAS("platform:"DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * W5100/W5200/W5500 common registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define W5100_COMMON_REGS 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define W5100_MR 0x0000 /* Mode Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MR_RST 0x80 /* S/W reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MR_PB 0x10 /* Ping block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MR_AI 0x02 /* Address Auto-Increment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MR_IND 0x01 /* Indirect mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define W5100_SHAR 0x0009 /* Source MAC address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define W5100_IR 0x0015 /* Interrupt Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define W5100_COMMON_REGS_LEN 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define W5100_Sn_MR 0x0000 /* Sn Mode Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define W5100_Sn_CR 0x0001 /* Sn Command Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define W5100_Sn_IR 0x0002 /* Sn Interrupt Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define W5100_Sn_SR 0x0003 /* Sn Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define W5100_Sn_TX_FSR 0x0020 /* Sn Transmit free memory size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define W5100_Sn_TX_RD 0x0022 /* Sn Transmit memory read pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define W5100_Sn_TX_WR 0x0024 /* Sn Transmit memory write pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define W5100_Sn_RX_RSR 0x0026 /* Sn Receive free memory size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define W5100_Sn_RX_RD 0x0028 /* Sn Receive memory read pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define S0_REGS(priv) ((priv)->s0_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define W5100_S0_MR(priv) (S0_REGS(priv) + W5100_Sn_MR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define S0_MR_MACRAW 0x04 /* MAC RAW mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define S0_MR_MF 0x40 /* MAC Filter for W5100 and W5200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define W5500_S0_MR_MF 0x80 /* MAC Filter for W5500 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define W5100_S0_CR(priv) (S0_REGS(priv) + W5100_Sn_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define S0_CR_OPEN 0x01 /* OPEN command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define S0_CR_CLOSE 0x10 /* CLOSE command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define S0_CR_SEND 0x20 /* SEND command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define S0_CR_RECV 0x40 /* RECV command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define W5100_S0_IR(priv) (S0_REGS(priv) + W5100_Sn_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define S0_IR_SENDOK 0x10 /* complete sending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define S0_IR_RECV 0x04 /* receiving data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define W5100_S0_SR(priv) (S0_REGS(priv) + W5100_Sn_SR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define S0_SR_MACRAW 0x42 /* mac raw mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define W5100_S0_TX_FSR(priv) (S0_REGS(priv) + W5100_Sn_TX_FSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define W5100_S0_TX_RD(priv) (S0_REGS(priv) + W5100_Sn_TX_RD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define W5100_S0_TX_WR(priv) (S0_REGS(priv) + W5100_Sn_TX_WR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define W5100_S0_RX_RSR(priv) (S0_REGS(priv) + W5100_Sn_RX_RSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define W5100_S0_RX_RD(priv) (S0_REGS(priv) + W5100_Sn_RX_RD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define W5100_S0_REGS_LEN 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * W5100 and W5200 common registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define W5100_IMR 0x0016 /* Interrupt Mask Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IR_S0 0x01 /* S0 interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define W5100_RTR 0x0017 /* Retry Time-value Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define RTR_DEFAULT 2000 /* =0x07d0 (2000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * W5100 specific register and memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define W5100_RMSR 0x001a /* Receive Memory Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define W5100_TMSR 0x001b /* Transmit Memory Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define W5100_S0_REGS 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define W5100_TX_MEM_START 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define W5100_TX_MEM_SIZE 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define W5100_RX_MEM_START 0x6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define W5100_RX_MEM_SIZE 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * W5200 specific register and memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define W5200_S0_REGS 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define W5200_Sn_RXMEM_SIZE(n) (0x401e + (n) * 0x0100) /* Sn RX Memory Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define W5200_Sn_TXMEM_SIZE(n) (0x401f + (n) * 0x0100) /* Sn TX Memory Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define W5200_TX_MEM_START 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define W5200_TX_MEM_SIZE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define W5200_RX_MEM_START 0xc000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define W5200_RX_MEM_SIZE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * W5500 specific register and memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * W5500 register and memory are organized by multiple blocks. Each one is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * selected by 16bits offset address and 5bits block select bits. So we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * encode it into 32bits address. (lower 16bits is offset address and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * upper 16bits is block select bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define W5500_SIMR 0x0018 /* Socket Interrupt Mask Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define W5500_RTR 0x0019 /* Retry Time-value Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define W5500_S0_REGS 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define W5500_Sn_RXMEM_SIZE(n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) (0x1001e + (n) * 0x40000) /* Sn RX Memory Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define W5500_Sn_TXMEM_SIZE(n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) (0x1001f + (n) * 0x40000) /* Sn TX Memory Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define W5500_TX_MEM_START 0x20000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define W5500_TX_MEM_SIZE 0x04000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define W5500_RX_MEM_START 0x30000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define W5500_RX_MEM_SIZE 0x04000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Device driver private data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct w5100_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) const struct w5100_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Socket 0 register offset address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u32 s0_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Socket 0 TX buffer offset address and size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u32 s0_tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u16 s0_tx_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Socket 0 RX buffer offset address and size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u32 s0_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u16 s0_rx_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int link_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int link_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct napi_struct napi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct net_device *ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) bool promisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) u32 msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct workqueue_struct *xfer_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct work_struct rx_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct sk_buff *tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct work_struct tx_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct work_struct setrx_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct work_struct restart_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * Lowlevel I/O functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct w5100_mmio_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Serialize access in indirect address mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static inline struct w5100_mmio_priv *w5100_mmio_priv(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return w5100_ops_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static inline void __iomem *w5100_mmio(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return mmio_priv->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * In direct address mode host system can directly access W5100 registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * after mapping to Memory-Mapped I/O space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * 0x8000 bytes are required for memory space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static inline int w5100_read_direct(struct net_device *ndev, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return ioread8(w5100_mmio(ndev) + (addr << CONFIG_WIZNET_BUS_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static inline int __w5100_write_direct(struct net_device *ndev, u32 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) iowrite8(data, w5100_mmio(ndev) + (addr << CONFIG_WIZNET_BUS_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static inline int w5100_write_direct(struct net_device *ndev, u32 addr, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) __w5100_write_direct(ndev, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int w5100_read16_direct(struct net_device *ndev, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) data = w5100_read_direct(ndev, addr) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) data |= w5100_read_direct(ndev, addr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int w5100_write16_direct(struct net_device *ndev, u32 addr, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) __w5100_write_direct(ndev, addr, data >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) __w5100_write_direct(ndev, addr + 1, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int w5100_readbulk_direct(struct net_device *ndev, u32 addr, u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) for (i = 0; i < len; i++, addr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *buf++ = w5100_read_direct(ndev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int w5100_writebulk_direct(struct net_device *ndev, u32 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) const u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) for (i = 0; i < len; i++, addr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) __w5100_write_direct(ndev, addr, *buf++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int w5100_mmio_init(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct platform_device *pdev = to_platform_device(ndev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct resource *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_lock_init(&mmio_priv->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) mmio_priv->base = devm_ioremap_resource(&pdev->dev, mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (IS_ERR(mmio_priv->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return PTR_ERR(mmio_priv->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) netdev_info(ndev, "at 0x%llx irq %d\n", (u64)mem->start, priv->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static const struct w5100_ops w5100_mmio_direct_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .chip_id = W5100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .read = w5100_read_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .write = w5100_write_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .read16 = w5100_read16_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .write16 = w5100_write16_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .readbulk = w5100_readbulk_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .writebulk = w5100_writebulk_direct,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .init = w5100_mmio_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * In indirect address mode host system indirectly accesses registers by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * using Indirect Mode Address Register (IDM_AR) and Indirect Mode Data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * Register (IDM_DR), which are directly mapped to Memory-Mapped I/O space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * Mode Register (MR) is directly accessible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * Only 0x04 bytes are required for memory space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define W5100_IDM_AR 0x01 /* Indirect Mode Address Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define W5100_IDM_DR 0x03 /* Indirect Mode Data Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int w5100_read_indirect(struct net_device *ndev, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) spin_lock_irqsave(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) w5100_write16_direct(ndev, W5100_IDM_AR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) data = w5100_read_direct(ndev, W5100_IDM_DR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int w5100_write_indirect(struct net_device *ndev, u32 addr, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) spin_lock_irqsave(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) w5100_write16_direct(ndev, W5100_IDM_AR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) w5100_write_direct(ndev, W5100_IDM_DR, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int w5100_read16_indirect(struct net_device *ndev, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) spin_lock_irqsave(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) w5100_write16_direct(ndev, W5100_IDM_AR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) data = w5100_read_direct(ndev, W5100_IDM_DR) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) data |= w5100_read_direct(ndev, W5100_IDM_DR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int w5100_write16_indirect(struct net_device *ndev, u32 addr, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) spin_lock_irqsave(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) w5100_write16_direct(ndev, W5100_IDM_AR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) __w5100_write_direct(ndev, W5100_IDM_DR, data >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) w5100_write_direct(ndev, W5100_IDM_DR, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int w5100_readbulk_indirect(struct net_device *ndev, u32 addr, u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) spin_lock_irqsave(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) w5100_write16_direct(ndev, W5100_IDM_AR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) *buf++ = w5100_read_direct(ndev, W5100_IDM_DR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int w5100_writebulk_indirect(struct net_device *ndev, u32 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) const u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct w5100_mmio_priv *mmio_priv = w5100_mmio_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) spin_lock_irqsave(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) w5100_write16_direct(ndev, W5100_IDM_AR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) __w5100_write_direct(ndev, W5100_IDM_DR, *buf++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) spin_unlock_irqrestore(&mmio_priv->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int w5100_reset_indirect(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) w5100_write_direct(ndev, W5100_MR, MR_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) w5100_write_direct(ndev, W5100_MR, MR_PB | MR_AI | MR_IND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static const struct w5100_ops w5100_mmio_indirect_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .chip_id = W5100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .read = w5100_read_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .write = w5100_write_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .read16 = w5100_read16_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .write16 = w5100_write16_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .readbulk = w5100_readbulk_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .writebulk = w5100_writebulk_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .init = w5100_mmio_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .reset = w5100_reset_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #if defined(CONFIG_WIZNET_BUS_DIRECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int w5100_read(struct w5100_priv *priv, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return w5100_read_direct(priv->ndev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int w5100_write(struct w5100_priv *priv, u32 addr, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return w5100_write_direct(priv->ndev, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static int w5100_read16(struct w5100_priv *priv, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return w5100_read16_direct(priv->ndev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static int w5100_write16(struct w5100_priv *priv, u32 addr, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return w5100_write16_direct(priv->ndev, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static int w5100_readbulk(struct w5100_priv *priv, u32 addr, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return w5100_readbulk_direct(priv->ndev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int w5100_writebulk(struct w5100_priv *priv, u32 addr, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return w5100_writebulk_direct(priv->ndev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #elif defined(CONFIG_WIZNET_BUS_INDIRECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int w5100_read(struct w5100_priv *priv, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return w5100_read_indirect(priv->ndev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int w5100_write(struct w5100_priv *priv, u32 addr, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return w5100_write_indirect(priv->ndev, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int w5100_read16(struct w5100_priv *priv, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return w5100_read16_indirect(priv->ndev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static int w5100_write16(struct w5100_priv *priv, u32 addr, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return w5100_write16_indirect(priv->ndev, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static int w5100_readbulk(struct w5100_priv *priv, u32 addr, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return w5100_readbulk_indirect(priv->ndev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int w5100_writebulk(struct w5100_priv *priv, u32 addr, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return w5100_writebulk_indirect(priv->ndev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #else /* CONFIG_WIZNET_BUS_ANY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int w5100_read(struct w5100_priv *priv, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return priv->ops->read(priv->ndev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static int w5100_write(struct w5100_priv *priv, u32 addr, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return priv->ops->write(priv->ndev, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int w5100_read16(struct w5100_priv *priv, u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return priv->ops->read16(priv->ndev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int w5100_write16(struct w5100_priv *priv, u32 addr, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return priv->ops->write16(priv->ndev, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static int w5100_readbulk(struct w5100_priv *priv, u32 addr, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return priv->ops->readbulk(priv->ndev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static int w5100_writebulk(struct w5100_priv *priv, u32 addr, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return priv->ops->writebulk(priv->ndev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int w5100_readbuf(struct w5100_priv *priv, u16 offset, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int remain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) const u32 mem_start = priv->s0_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) const u16 mem_size = priv->s0_rx_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) offset %= mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) addr = mem_start + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (offset + len > mem_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) remain = (offset + len) % mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) len = mem_size - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret = w5100_readbulk(priv, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (ret || !remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return w5100_readbulk(priv, mem_start, buf + len, remain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int w5100_writebuf(struct w5100_priv *priv, u16 offset, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) int remain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) const u32 mem_start = priv->s0_tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) const u16 mem_size = priv->s0_tx_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) offset %= mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) addr = mem_start + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (offset + len > mem_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) remain = (offset + len) % mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) len = mem_size - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ret = w5100_writebulk(priv, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (ret || !remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return w5100_writebulk(priv, mem_start, buf + len, remain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static int w5100_reset(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (priv->ops->reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return priv->ops->reset(priv->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) w5100_write(priv, W5100_MR, MR_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) w5100_write(priv, W5100_MR, MR_PB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static int w5100_command(struct w5100_priv *priv, u16 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) w5100_write(priv, W5100_S0_CR(priv), cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) timeout = jiffies + msecs_to_jiffies(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) while (w5100_read(priv, W5100_S0_CR(priv)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (time_after(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static void w5100_write_macaddr(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct net_device *ndev = priv->ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) w5100_writebulk(priv, W5100_SHAR, ndev->dev_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static void w5100_socket_intr_mask(struct w5100_priv *priv, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) u32 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (priv->ops->chip_id == W5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) imr = W5500_SIMR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) imr = W5100_IMR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) w5100_write(priv, imr, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static void w5100_enable_intr(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) w5100_socket_intr_mask(priv, IR_S0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static void w5100_disable_intr(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) w5100_socket_intr_mask(priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static void w5100_memory_configure(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* Configure 16K of internal memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * as 8K RX buffer and 8K TX buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) w5100_write(priv, W5100_RMSR, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) w5100_write(priv, W5100_TMSR, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static void w5200_memory_configure(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Configure internal RX memory as 16K RX buffer and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * internal TX memory as 16K TX buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) w5100_write(priv, W5200_Sn_RXMEM_SIZE(0), 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) w5100_write(priv, W5200_Sn_TXMEM_SIZE(0), 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) for (i = 1; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) w5100_write(priv, W5200_Sn_RXMEM_SIZE(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) w5100_write(priv, W5200_Sn_TXMEM_SIZE(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static void w5500_memory_configure(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /* Configure internal RX memory as 16K RX buffer and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * internal TX memory as 16K TX buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) w5100_write(priv, W5500_Sn_RXMEM_SIZE(0), 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) w5100_write(priv, W5500_Sn_TXMEM_SIZE(0), 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) for (i = 1; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) w5100_write(priv, W5500_Sn_RXMEM_SIZE(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) w5100_write(priv, W5500_Sn_TXMEM_SIZE(i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static int w5100_hw_reset(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u32 rtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) w5100_reset(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) w5100_disable_intr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) w5100_write_macaddr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) switch (priv->ops->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case W5100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) w5100_memory_configure(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) rtr = W5100_RTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case W5200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) w5200_memory_configure(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) rtr = W5100_RTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case W5500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) w5500_memory_configure(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) rtr = W5500_RTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (w5100_read16(priv, rtr) != RTR_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static void w5100_hw_start(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) u8 mode = S0_MR_MACRAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!priv->promisc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (priv->ops->chip_id == W5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) mode |= W5500_S0_MR_MF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mode |= S0_MR_MF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) w5100_write(priv, W5100_S0_MR(priv), mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) w5100_command(priv, S0_CR_OPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) w5100_enable_intr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static void w5100_hw_close(struct w5100_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) w5100_disable_intr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) w5100_command(priv, S0_CR_CLOSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /***********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * Device driver functions / callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static void w5100_get_drvinfo(struct net_device *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) strlcpy(info->version, DRV_VERSION, sizeof(info->version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) strlcpy(info->bus_info, dev_name(ndev->dev.parent),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) sizeof(info->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static u32 w5100_get_link(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (gpio_is_valid(priv->link_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return !!gpio_get_value(priv->link_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static u32 w5100_get_msglevel(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return priv->msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static void w5100_set_msglevel(struct net_device *ndev, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) priv->msg_enable = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static int w5100_get_regs_len(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return W5100_COMMON_REGS_LEN + W5100_S0_REGS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static void w5100_get_regs(struct net_device *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct ethtool_regs *regs, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) regs->version = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) w5100_readbulk(priv, W5100_COMMON_REGS, buf, W5100_COMMON_REGS_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) buf += W5100_COMMON_REGS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) w5100_readbulk(priv, S0_REGS(priv), buf, W5100_S0_REGS_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static void w5100_restart(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) netif_stop_queue(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) w5100_hw_reset(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) w5100_hw_start(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ndev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) netif_trans_update(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) netif_wake_queue(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static void w5100_restart_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct w5100_priv *priv = container_of(work, struct w5100_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) w5100_restart(priv->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static void w5100_tx_timeout(struct net_device *ndev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (priv->ops->may_sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) schedule_work(&priv->restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) w5100_restart(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static void w5100_tx_skb(struct net_device *ndev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) offset = w5100_read16(priv, W5100_S0_TX_WR(priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) w5100_writebuf(priv, offset, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) w5100_write16(priv, W5100_S0_TX_WR(priv), offset + skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ndev->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ndev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) w5100_command(priv, S0_CR_SEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static void w5100_tx_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct w5100_priv *priv = container_of(work, struct w5100_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) tx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct sk_buff *skb = priv->tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) priv->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (WARN_ON(!skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) w5100_tx_skb(priv->ndev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static netdev_tx_t w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) netif_stop_queue(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (priv->ops->may_sleep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) WARN_ON(priv->tx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) priv->tx_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) queue_work(priv->xfer_wq, &priv->tx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) w5100_tx_skb(ndev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static struct sk_buff *w5100_rx_skb(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) u16 rx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) u8 header[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) u16 rx_buf_len = w5100_read16(priv, W5100_S0_RX_RSR(priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (rx_buf_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) offset = w5100_read16(priv, W5100_S0_RX_RD(priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) w5100_readbuf(priv, offset, header, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) rx_len = get_unaligned_be16(header) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) skb = netdev_alloc_skb_ip_align(ndev, rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (unlikely(!skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) w5100_write16(priv, W5100_S0_RX_RD(priv), offset + rx_buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) w5100_command(priv, S0_CR_RECV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ndev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) skb_put(skb, rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) w5100_readbuf(priv, offset + 2, skb->data, rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) w5100_write16(priv, W5100_S0_RX_RD(priv), offset + 2 + rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) w5100_command(priv, S0_CR_RECV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) skb->protocol = eth_type_trans(skb, ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ndev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) ndev->stats.rx_bytes += rx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static void w5100_rx_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct w5100_priv *priv = container_of(work, struct w5100_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) rx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) while ((skb = w5100_rx_skb(priv->ndev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) netif_rx_ni(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) w5100_enable_intr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int w5100_napi_poll(struct napi_struct *napi, int budget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct w5100_priv *priv = container_of(napi, struct w5100_priv, napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) int rx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) for (rx_count = 0; rx_count < budget; rx_count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct sk_buff *skb = w5100_rx_skb(priv->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) netif_receive_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (rx_count < budget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) napi_complete_done(napi, rx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) w5100_enable_intr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return rx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct net_device *ndev = ndev_instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) int ir = w5100_read(priv, W5100_S0_IR(priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (!ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) w5100_write(priv, W5100_S0_IR(priv), ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (ir & S0_IR_SENDOK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) netif_dbg(priv, tx_done, ndev, "tx done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) netif_wake_queue(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (ir & S0_IR_RECV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) w5100_disable_intr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (priv->ops->may_sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) queue_work(priv->xfer_wq, &priv->rx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) else if (napi_schedule_prep(&priv->napi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) __napi_schedule(&priv->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static irqreturn_t w5100_detect_link(int irq, void *ndev_instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct net_device *ndev = ndev_instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (netif_running(ndev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (gpio_get_value(priv->link_gpio) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) netif_info(priv, link, ndev, "link is up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) netif_carrier_on(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) netif_info(priv, link, ndev, "link is down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) netif_carrier_off(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static void w5100_setrx_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct w5100_priv *priv = container_of(work, struct w5100_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) setrx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) w5100_hw_start(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static void w5100_set_rx_mode(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) bool set_promisc = (ndev->flags & IFF_PROMISC) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (priv->promisc != set_promisc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) priv->promisc = set_promisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (priv->ops->may_sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) schedule_work(&priv->setrx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) w5100_hw_start(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int w5100_set_macaddr(struct net_device *ndev, void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct sockaddr *sock_addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!is_valid_ether_addr(sock_addr->sa_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) memcpy(ndev->dev_addr, sock_addr->sa_data, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) w5100_write_macaddr(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static int w5100_open(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) netif_info(priv, ifup, ndev, "enabling\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) w5100_hw_start(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) napi_enable(&priv->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) netif_start_queue(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (!gpio_is_valid(priv->link_gpio) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) gpio_get_value(priv->link_gpio) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) netif_carrier_on(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static int w5100_stop(struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) netif_info(priv, ifdown, ndev, "shutting down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) w5100_hw_close(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) netif_carrier_off(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) netif_stop_queue(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) napi_disable(&priv->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static const struct ethtool_ops w5100_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .get_drvinfo = w5100_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .get_msglevel = w5100_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .set_msglevel = w5100_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .get_link = w5100_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .get_regs_len = w5100_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .get_regs = w5100_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static const struct net_device_ops w5100_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .ndo_open = w5100_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .ndo_stop = w5100_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .ndo_start_xmit = w5100_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .ndo_tx_timeout = w5100_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .ndo_set_rx_mode = w5100_set_rx_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .ndo_set_mac_address = w5100_set_macaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static int w5100_mmio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct wiznet_platform_data *data = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) const void *mac_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct resource *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) const struct w5100_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (data && is_valid_ether_addr(data->mac_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) mac_addr = data->mac_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (!mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (resource_size(mem) < W5100_BUS_DIRECT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) ops = &w5100_mmio_indirect_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) ops = &w5100_mmio_direct_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return w5100_probe(&pdev->dev, ops, sizeof(struct w5100_mmio_priv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) mac_addr, irq, data ? data->link_gpio : -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static int w5100_mmio_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return w5100_remove(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) void *w5100_ops_priv(const struct net_device *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return netdev_priv(ndev) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) ALIGN(sizeof(struct w5100_priv), NETDEV_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) EXPORT_SYMBOL_GPL(w5100_ops_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int w5100_probe(struct device *dev, const struct w5100_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) int sizeof_ops_priv, const void *mac_addr, int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) int link_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct w5100_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct net_device *ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) size_t alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) alloc_size = sizeof(*priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (sizeof_ops_priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) alloc_size = ALIGN(alloc_size, NETDEV_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) alloc_size += sizeof_ops_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) alloc_size += NETDEV_ALIGN - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) ndev = alloc_etherdev(alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (!ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) SET_NETDEV_DEV(ndev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) dev_set_drvdata(dev, ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) switch (ops->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) case W5100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) priv->s0_regs = W5100_S0_REGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) priv->s0_tx_buf = W5100_TX_MEM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) priv->s0_tx_buf_size = W5100_TX_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) priv->s0_rx_buf = W5100_RX_MEM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) priv->s0_rx_buf_size = W5100_RX_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) case W5200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) priv->s0_regs = W5200_S0_REGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) priv->s0_tx_buf = W5200_TX_MEM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) priv->s0_tx_buf_size = W5200_TX_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) priv->s0_rx_buf = W5200_RX_MEM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) priv->s0_rx_buf_size = W5200_RX_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) case W5500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) priv->s0_regs = W5500_S0_REGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) priv->s0_tx_buf = W5500_TX_MEM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) priv->s0_tx_buf_size = W5500_TX_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) priv->s0_rx_buf = W5500_RX_MEM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) priv->s0_rx_buf_size = W5500_RX_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) goto err_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) priv->ndev = ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) priv->ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) priv->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) priv->link_gpio = link_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) ndev->netdev_ops = &w5100_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) ndev->ethtool_ops = &w5100_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) netif_napi_add(ndev, &priv->napi, w5100_napi_poll, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) /* This chip doesn't support VLAN packets with normal MTU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * so disable VLAN for this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ndev->features |= NETIF_F_VLAN_CHALLENGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) err = register_netdev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) goto err_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) priv->xfer_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) netdev_name(ndev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (!priv->xfer_wq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) goto err_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) INIT_WORK(&priv->rx_work, w5100_rx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) INIT_WORK(&priv->tx_work, w5100_tx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) INIT_WORK(&priv->setrx_work, w5100_setrx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) INIT_WORK(&priv->restart_work, w5100_restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (!IS_ERR_OR_NULL(mac_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) eth_hw_addr_random(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (priv->ops->init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) err = priv->ops->init(priv->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) goto err_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) err = w5100_hw_reset(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) goto err_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (ops->may_sleep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) err = request_threaded_irq(priv->irq, NULL, w5100_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) IRQF_TRIGGER_LOW | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) netdev_name(ndev), ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) err = request_irq(priv->irq, w5100_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) IRQF_TRIGGER_LOW, netdev_name(ndev), ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto err_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (gpio_is_valid(priv->link_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) char *link_name = devm_kzalloc(dev, 16, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (!link_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) goto err_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) snprintf(link_name, 16, "%s-link", netdev_name(ndev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) priv->link_irq = gpio_to_irq(priv->link_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (request_any_context_irq(priv->link_irq, w5100_detect_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) IRQF_TRIGGER_RISING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) IRQF_TRIGGER_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) link_name, priv->ndev) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) priv->link_gpio = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) err_gpio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) free_irq(priv->irq, ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) err_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) destroy_workqueue(priv->xfer_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) err_wq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) unregister_netdev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) err_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) free_netdev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) EXPORT_SYMBOL_GPL(w5100_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) int w5100_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct net_device *ndev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) w5100_hw_reset(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) free_irq(priv->irq, ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (gpio_is_valid(priv->link_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) free_irq(priv->link_irq, ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) flush_work(&priv->setrx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) flush_work(&priv->restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) destroy_workqueue(priv->xfer_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) unregister_netdev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) free_netdev(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) EXPORT_SYMBOL_GPL(w5100_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static int w5100_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) struct net_device *ndev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (netif_running(ndev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) netif_carrier_off(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) netif_device_detach(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) w5100_hw_close(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) static int w5100_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) struct net_device *ndev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) struct w5100_priv *priv = netdev_priv(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (netif_running(ndev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) w5100_hw_reset(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) w5100_hw_start(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) netif_device_attach(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if (!gpio_is_valid(priv->link_gpio) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) gpio_get_value(priv->link_gpio) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) netif_carrier_on(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) SIMPLE_DEV_PM_OPS(w5100_pm_ops, w5100_suspend, w5100_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) EXPORT_SYMBOL_GPL(w5100_pm_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static struct platform_driver w5100_mmio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .pm = &w5100_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .probe = w5100_mmio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) .remove = w5100_mmio_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) module_platform_driver(w5100_mmio_driver);