^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) sis190.c: Silicon Integrated Systems SiS190 ethernet driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Copyright (c) 2003 K.M. Liu <kmliu@sis.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Copyright (c) 2003, 2004 Jeff Garzik <jgarzik@pobox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) Copyright (c) 2003, 2004, 2005 Francois Romieu <romieu@fr.zoreil.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) Based on r8169.c, tg3.c, 8139cp.c, skge.c, epic100.c and SiS 190/191
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) genuine driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) This software may be used and distributed according to the terms of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) the GNU General Public License (GPL), incorporated herein by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) Drivers based on or derived from this code fall under the GPL and must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) retain the authorship, copyright and license notice. This file is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) a complete program and may only be used when the entire operating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) system is licensed under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) See the file COPYING in this distribution for more information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^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/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PHY_MAX_ADDR 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PHY_ID_ANY 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MII_REG_ANY 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DRV_VERSION "1.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DRV_NAME "sis190"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define sis190_rx_skb netif_rx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define sis190_rx_quota(count, quota) count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define NUM_TX_DESC 64 /* [8..1024] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define NUM_RX_DESC 64 /* [8..8192] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define RX_BUF_SIZE 1536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define RX_BUF_MASK 0xfff8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SIS190_REGS_SIZE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SIS190_TX_TIMEOUT (6*HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SIS190_PHY_TIMEOUT (10*HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SIS190_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) NETIF_MSG_LINK | NETIF_MSG_IFUP | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) NETIF_MSG_IFDOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Enhanced PHY access register bit definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define EhnMIIread 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define EhnMIIwrite 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define EhnMIIdataShift 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define EhnMIIpmdShift 6 /* 7016 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define EhnMIIregShift 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define EhnMIIreq 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define EhnMIInotDone 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* Write/read MMIO register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SIS_W8(reg, val) writeb ((val), ioaddr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SIS_W16(reg, val) writew ((val), ioaddr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SIS_W32(reg, val) writel ((val), ioaddr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SIS_R8(reg) readb (ioaddr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SIS_R16(reg) readw (ioaddr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SIS_R32(reg) readl (ioaddr + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SIS_PCI_COMMIT() SIS_R32(IntrControl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) enum sis190_registers {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) TxControl = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) TxDescStartAddr = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) rsv0 = 0x08, // reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) TxSts = 0x0c, // unused (Control/Status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) RxControl = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) RxDescStartAddr = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rsv1 = 0x18, // reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) RxSts = 0x1c, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) IntrStatus = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) IntrMask = 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) IntrControl = 0x28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) IntrTimer = 0x2c, // unused (Interrupt Timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) PMControl = 0x30, // unused (Power Mgmt Control/Status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) rsv2 = 0x34, // reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ROMControl = 0x38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ROMInterface = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) StationControl = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) GMIIControl = 0x44,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) GIoCR = 0x48, // unused (GMAC IO Compensation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) GIoCtrl = 0x4c, // unused (GMAC IO Control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) TxMacControl = 0x50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) TxLimit = 0x54, // unused (Tx MAC Timer/TryLimit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) RGDelay = 0x58, // unused (RGMII Tx Internal Delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) rsv3 = 0x5c, // reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) RxMacControl = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) RxMacAddr = 0x62,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) RxHashTable = 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) // Undocumented = 0x6c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) RxWolCtrl = 0x70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) RxWolData = 0x74, // unused (Rx WOL Data Access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) RxMPSControl = 0x78, // unused (Rx MPS Control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) rsv4 = 0x7c, // reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) enum sis190_register_content {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* IntrStatus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) SoftInt = 0x40000000, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) Timeup = 0x20000000, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) PauseFrame = 0x00080000, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) MagicPacket = 0x00040000, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) WakeupFrame = 0x00020000, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) LinkChange = 0x00010000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) RxQEmpty = 0x00000080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) RxQInt = 0x00000040,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) TxQ1Empty = 0x00000020, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) TxQ1Int = 0x00000010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) TxQ0Empty = 0x00000008, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) TxQ0Int = 0x00000004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) RxHalt = 0x00000002,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) TxHalt = 0x00000001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* {Rx/Tx}CmdBits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) CmdReset = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) CmdRxEnb = 0x08, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) CmdTxEnb = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) RxBufEmpty = 0x01, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Cfg9346Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) Cfg9346_Lock = 0x00, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) Cfg9346_Unlock = 0xc0, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* RxMacControl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) AcceptErr = 0x20, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) AcceptRunt = 0x10, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) AcceptBroadcast = 0x0800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) AcceptMulticast = 0x0400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) AcceptMyPhys = 0x0200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) AcceptAllPhys = 0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* RxConfigBits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) RxCfgFIFOShift = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) RxCfgDMAShift = 8, // 0x1a in RxControl ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* TxConfigBits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) TxInterFrameGapShift = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) LinkStatus = 0x02, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) FullDup = 0x01, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* TBICSRBit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) TBILinkOK = 0x02000000, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct TxDesc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) __le32 PSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) __le32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) __le32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) __le32 size;
^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) struct RxDesc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) __le32 PSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) __le32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) __le32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __le32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) enum _DescStatusBit {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* _Desc.status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) OWNbit = 0x80000000, // RXOWN/TXOWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) INTbit = 0x40000000, // RXINT/TXINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) CRCbit = 0x00020000, // CRCOFF/CRCEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) PADbit = 0x00010000, // PREADD/PADEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* _Desc.size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) RingEnd = 0x80000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* TxDesc.status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) LSEN = 0x08000000, // TSO ? -- FR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) IPCS = 0x04000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) TCPCS = 0x02000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) UDPCS = 0x01000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) BSTEN = 0x00800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) EXTEN = 0x00400000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) DEFEN = 0x00200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) BKFEN = 0x00100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) CRSEN = 0x00080000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) COLEN = 0x00040000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) THOL3 = 0x30000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) THOL2 = 0x20000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) THOL1 = 0x10000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) THOL0 = 0x00000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) WND = 0x00080000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) TABRT = 0x00040000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) FIFO = 0x00020000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) LINK = 0x00010000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ColCountMask = 0x0000ffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* RxDesc.status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) IPON = 0x20000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) TCPON = 0x10000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) UDPON = 0x08000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) Wakup = 0x00400000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) Magic = 0x00200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) Pause = 0x00100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) DEFbit = 0x00200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) BCAST = 0x000c0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) MCAST = 0x00080000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) UCAST = 0x00040000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* RxDesc.PSize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) TAGON = 0x80000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) RxDescCountMask = 0x7f000000, // multi-desc pkt when > 1 ? -- FR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ABORT = 0x00800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) SHORT = 0x00400000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) LIMIT = 0x00200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) MIIER = 0x00100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) OVRUN = 0x00080000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) NIBON = 0x00040000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) COLON = 0x00020000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) CRCOK = 0x00010000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) RxSizeMask = 0x0000ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * The asic could apparently do vlan, TSO, jumbo (sis191 only) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * provide two (unused with Linux) Tx queues. No publicly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * available documentation alas.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^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) enum sis190_eeprom_access_register_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) EECS = 0x00000001, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) EECLK = 0x00000002, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) EEDO = 0x00000008, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) EEDI = 0x00000004, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) EEREQ = 0x00000080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) EEROP = 0x00000200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) EEWOP = 0x00000100 // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* EEPROM Addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) enum sis190_eeprom_address {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) EEPROMSignature = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) EEPROMCLK = 0x01, // unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) EEPROMInfo = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) EEPROMMACAddr = 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) enum sis190_feature {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) F_HAS_RGMII = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) F_PHY_88E1111 = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) F_PHY_BCM5461 = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct sis190_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) void __iomem *mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct pci_dev *pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) u32 rx_buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) u32 cur_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u32 cur_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) u32 dirty_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) u32 dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) dma_addr_t rx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dma_addr_t tx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct RxDesc *RxDescRing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct TxDesc *TxDescRing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct sk_buff *Rx_skbuff[NUM_RX_DESC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct sk_buff *Tx_skbuff[NUM_TX_DESC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct work_struct phy_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u32 msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct mii_if_info mii_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct list_head first_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) u32 features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) u32 negotiated_lpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) LNK_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) LNK_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) LNK_AUTONEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } link_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct sis190_phy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u16 id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) enum sis190_phy_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) UNKNOWN = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) HOME = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) LAN = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) MIX = 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static struct mii_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u16 id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) u32 feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) } mii_chip_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) { "Atheros PHY", { 0x004d, 0xd010 }, LAN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) { NULL, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } sis_chip_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) { "SiS 190 PCI Fast Ethernet adapter" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) { "SiS 191 PCI Gigabit Ethernet adapter" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static const struct pci_device_id sis190_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) { 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) MODULE_DEVICE_TABLE(pci, sis190_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int rx_copybreak = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u32 msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) } debug = { -1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) MODULE_DESCRIPTION("SiS sis190/191 Gigabit Ethernet driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) module_param(rx_copybreak, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) module_param_named(debug, debug.msg_enable, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) MODULE_AUTHOR("K.M. Liu <kmliu@sis.com>, Ueimor <romieu@fr.zoreil.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) MODULE_VERSION(DRV_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static const u32 sis190_intr_mask =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt | LinkChange;
^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) * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * The chips use a 64 element hash table based on the Ethernet CRC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static const int multicast_filter_limit = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static void __mdio_cmd(void __iomem *ioaddr, u32 ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) SIS_W32(GMIIControl, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) for (i = 0; i < 100; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!(SIS_R32(GMIIControl) & EhnMIInotDone))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (i > 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) pr_err("PHY command failed !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static void mdio_write(void __iomem *ioaddr, int phy_id, int reg, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIwrite |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) (((u32) val) << EhnMIIdataShift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static int mdio_read(void __iomem *ioaddr, int phy_id, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIread |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void __mdio_write(struct net_device *dev, int phy_id, int reg, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) mdio_write(tp->mmio_addr, phy_id, reg, val);
^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 int __mdio_read(struct net_device *dev, int phy_id, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return mdio_read(tp->mmio_addr, phy_id, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static u16 mdio_read_latched(void __iomem *ioaddr, int phy_id, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mdio_read(ioaddr, phy_id, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return mdio_read(ioaddr, phy_id, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static u16 sis190_read_eeprom(void __iomem *ioaddr, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) u16 data = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (!(SIS_R32(ROMControl) & 0x0002))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) SIS_W32(ROMInterface, EEREQ | EEROP | (reg << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) for (i = 0; i < 200; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!(SIS_R32(ROMInterface) & EEREQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) data = (SIS_R32(ROMInterface) & 0xffff0000) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return 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 void sis190_irq_mask_and_ack(void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) SIS_W32(IntrMask, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) SIS_W32(IntrStatus, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) SIS_PCI_COMMIT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static void sis190_asic_down(void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* Stop the chip's Tx and Rx DMA processes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) SIS_W32(TxControl, 0x1a00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) SIS_W32(RxControl, 0x1a00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) sis190_irq_mask_and_ack(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static void sis190_mark_as_last_descriptor(struct RxDesc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) desc->size |= cpu_to_le32(RingEnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static inline void sis190_give_to_asic(struct RxDesc *desc, u32 rx_buf_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) u32 eor = le32_to_cpu(desc->size) & RingEnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) desc->PSize = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) desc->size = cpu_to_le32((rx_buf_sz & RX_BUF_MASK) | eor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) desc->status = cpu_to_le32(OWNbit | INTbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static inline void sis190_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) u32 rx_buf_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) desc->addr = cpu_to_le32(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) sis190_give_to_asic(desc, rx_buf_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static inline void sis190_make_unusable_by_asic(struct RxDesc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) desc->PSize = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) desc->addr = cpu_to_le32(0xdeadbeef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) desc->size &= cpu_to_le32(RingEnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) desc->status = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static struct sk_buff *sis190_alloc_rx_skb(struct sis190_private *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct RxDesc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u32 rx_buf_sz = tp->rx_buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) dma_addr_t mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) skb = netdev_alloc_skb(tp->dev, rx_buf_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (unlikely(!skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto skb_alloc_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) mapping = dma_map_single(&tp->pci_dev->dev, skb->data, tp->rx_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (dma_mapping_error(&tp->pci_dev->dev, mapping))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) sis190_map_to_asic(desc, mapping, rx_buf_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) skb_alloc_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) sis190_make_unusable_by_asic(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) u32 start, u32 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) u32 cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) for (cur = start; cur < end; cur++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) unsigned int i = cur % NUM_RX_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (tp->Rx_skbuff[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) tp->Rx_skbuff[i] = sis190_alloc_rx_skb(tp, tp->RxDescRing + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (!tp->Rx_skbuff[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return cur - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static bool sis190_try_rx_copy(struct sis190_private *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct sk_buff **sk_buff, int pkt_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dma_addr_t addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) bool done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (pkt_size >= rx_copybreak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, tp->rx_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) *sk_buff = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) #define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if ((status & CRCOK) && !(status & ErrMask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (!(status & CRCOK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) stats->rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) else if (status & OVRUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) stats->rx_over_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) else if (status & (SHORT | LIMIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) stats->rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) else if (status & (MIIER | NIBON | COLON))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) stats->rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) stats->rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static int sis190_rx_interrupt(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct sis190_private *tp, void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct net_device_stats *stats = &dev->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) u32 rx_left, cur_rx = tp->cur_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) u32 delta, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) rx_left = sis190_rx_quota(rx_left, (u32) dev->quota);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) for (; rx_left > 0; rx_left--, cur_rx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) unsigned int entry = cur_rx % NUM_RX_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct RxDesc *desc = tp->RxDescRing + entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (le32_to_cpu(desc->status) & OWNbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) status = le32_to_cpu(desc->PSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) //netif_info(tp, intr, dev, "Rx PSize = %08x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (sis190_rx_pkt_err(status, stats) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) sis190_give_to_asic(desc, tp->rx_buf_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct sk_buff *skb = tp->Rx_skbuff[entry];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dma_addr_t addr = le32_to_cpu(desc->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) int pkt_size = (status & RxSizeMask) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct pci_dev *pdev = tp->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (unlikely(pkt_size > tp->rx_buf_sz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) netif_info(tp, intr, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) "(frag) status = %08x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) stats->rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) stats->rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) sis190_give_to_asic(desc, tp->rx_buf_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) continue;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (sis190_try_rx_copy(tp, &skb, pkt_size, addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dma_sync_single_for_device(&pdev->dev, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) tp->rx_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) sis190_give_to_asic(desc, tp->rx_buf_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) dma_unmap_single(&pdev->dev, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) tp->rx_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) tp->Rx_skbuff[entry] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) sis190_make_unusable_by_asic(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) skb_put(skb, pkt_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) skb->protocol = eth_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) sis190_rx_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) stats->rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) stats->rx_bytes += pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if ((status & BCAST) == MCAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) stats->multicast++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) count = cur_rx - tp->cur_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) tp->cur_rx = cur_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) delta = sis190_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (!delta && count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) netif_info(tp, intr, dev, "no Rx buffer allocated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) tp->dirty_rx += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if ((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) netif_emerg(tp, intr, dev, "Rx buffers exhausted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static void sis190_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct TxDesc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dma_unmap_single(&pdev->dev, le32_to_cpu(desc->addr), len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) memset(desc, 0x00, sizeof(*desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static inline int sis190_tx_pkt_err(u32 status, struct net_device_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) #define TxErrMask (WND | TABRT | FIFO | LINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!unlikely(status & TxErrMask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (status & WND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) stats->tx_window_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (status & TABRT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) stats->tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (status & FIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) stats->tx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (status & LINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) stats->tx_carrier_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) stats->tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static void sis190_tx_interrupt(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct sis190_private *tp, void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct net_device_stats *stats = &dev->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) u32 pending, dirty_tx = tp->dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * It would not be needed if queueing was allowed to be enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * again too early (hint: think preempt and unclocked smp systems).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) unsigned int queue_stopped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) pending = tp->cur_tx - dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) queue_stopped = (pending == NUM_TX_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) for (; pending; pending--, dirty_tx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned int entry = dirty_tx % NUM_TX_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct TxDesc *txd = tp->TxDescRing + entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u32 status = le32_to_cpu(txd->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (status & OWNbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) skb = tp->Tx_skbuff[entry];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (likely(sis190_tx_pkt_err(status, stats) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) stats->tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) stats->tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) stats->collisions += ((status & ColCountMask) - 1);
^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) sis190_unmap_tx_skb(tp->pci_dev, skb, txd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) tp->Tx_skbuff[entry] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) dev_consume_skb_irq(skb);
^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) if (tp->dirty_tx != dirty_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) tp->dirty_tx = dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (queue_stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * The interrupt handler does all of the Rx thread work and cleans up after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * the Tx thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static irqreturn_t sis190_irq(int irq, void *__dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct net_device *dev = __dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) unsigned int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) status = SIS_R32(IntrStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if ((status == 0xffffffff) || !status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (unlikely(!netif_running(dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) sis190_asic_down(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) SIS_W32(IntrStatus, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) // netif_info(tp, intr, dev, "status = %08x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (status & LinkChange) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) netif_info(tp, intr, dev, "link change\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) del_timer(&tp->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) schedule_work(&tp->phy_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (status & RxQInt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) sis190_rx_interrupt(dev, tp, ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (status & TxQ0Int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) sis190_tx_interrupt(dev, tp, ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static void sis190_netpoll(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) const int irq = tp->pci_dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) disable_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) sis190_irq(irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) enable_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static void sis190_free_rx_skb(struct sis190_private *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct sk_buff **sk_buff, struct RxDesc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct pci_dev *pdev = tp->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dma_unmap_single(&pdev->dev, le32_to_cpu(desc->addr), tp->rx_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev_kfree_skb(*sk_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) *sk_buff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) sis190_make_unusable_by_asic(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) static void sis190_rx_clear(struct sis190_private *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) for (i = 0; i < NUM_RX_DESC; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (!tp->Rx_skbuff[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) sis190_free_rx_skb(tp, tp->Rx_skbuff + i, tp->RxDescRing + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) static void sis190_init_ring_indexes(struct sis190_private *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static int sis190_init_ring(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) sis190_init_ring_indexes(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (sis190_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto err_rx_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) sis190_mark_as_last_descriptor(tp->RxDescRing + NUM_RX_DESC - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) err_rx_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) sis190_rx_clear(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static void sis190_set_rx_mode(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) u32 mc_filter[2]; /* Multicast hash filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) u16 rx_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (dev->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) rx_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) AcceptAllPhys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) mc_filter[1] = mc_filter[0] = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) } else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) (dev->flags & IFF_ALLMULTI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* Too many to filter perfectly -- accept all multicasts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) mc_filter[1] = mc_filter[0] = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) rx_mode = AcceptBroadcast | AcceptMyPhys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) mc_filter[1] = mc_filter[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) netdev_for_each_mc_addr(ha, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int bit_nr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ether_crc(ETH_ALEN, ha->addr) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) rx_mode |= AcceptMulticast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) spin_lock_irqsave(&tp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) SIS_W16(RxMacControl, rx_mode | 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) SIS_W32(RxHashTable, mc_filter[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) SIS_W32(RxHashTable + 4, mc_filter[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) spin_unlock_irqrestore(&tp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static void sis190_soft_reset(void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) SIS_W32(IntrControl, 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) SIS_PCI_COMMIT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) SIS_W32(IntrControl, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) sis190_asic_down(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static void sis190_hw_start(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) sis190_soft_reset(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) SIS_W32(TxDescStartAddr, tp->tx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) SIS_W32(RxDescStartAddr, tp->rx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) SIS_W32(IntrStatus, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) SIS_W32(IntrMask, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) SIS_W32(GMIIControl, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) SIS_W32(TxMacControl, 0x60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) SIS_W16(RxMacControl, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) SIS_W32(RxHashTable, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) SIS_W32(0x6c, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) SIS_W32(RxWolCtrl, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) SIS_W32(RxWolData, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) SIS_PCI_COMMIT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) sis190_set_rx_mode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* Enable all known interrupts by setting the interrupt mask. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) SIS_W32(IntrMask, sis190_intr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) SIS_W32(TxControl, 0x1a00 | CmdTxEnb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) SIS_W32(RxControl, 0x1a1d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static void sis190_phy_task(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct sis190_private *tp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) container_of(work, struct sis190_private, phy_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct net_device *dev = tp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) int phy_id = tp->mii_if.phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) val = mdio_read(ioaddr, phy_id, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (val & BMCR_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) // FIXME: needlessly high ? -- FR 02/07/2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) mod_timer(&tp->timer, jiffies + HZ/10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) val = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (!(val & BMSR_ANEGCOMPLETE) && tp->link_status != LNK_AUTONEG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) netif_warn(tp, link, dev, "auto-negotiating...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) tp->link_status = LNK_AUTONEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) } else if ((val & BMSR_LSTATUS) && tp->link_status != LNK_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Rejoice ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) u32 ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) const char *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) } reg31[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) { LPA_1000FULL, 0x07000c00 | 0x00001000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) "1000 Mbps Full Duplex" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) { LPA_1000HALF, 0x07000c00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) "1000 Mbps Half Duplex" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) { LPA_100FULL, 0x04000800 | 0x00001000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) "100 Mbps Full Duplex" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) { LPA_100HALF, 0x04000800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) "100 Mbps Half Duplex" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) { LPA_10FULL, 0x04000400 | 0x00001000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) "10 Mbps Full Duplex" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) { LPA_10HALF, 0x04000400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) "10 Mbps Half Duplex" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) { 0, 0x04000400, "unknown" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }, *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) u16 adv, autoexp, gigadv, gigrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) val = mdio_read(ioaddr, phy_id, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) netif_info(tp, link, dev, "mii ext = %04x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) val = mdio_read(ioaddr, phy_id, MII_LPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) netif_info(tp, link, dev, "mii lpa=%04x adv=%04x exp=%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) val, adv, autoexp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* check for gigabit speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) val = (gigadv & (gigrec >> 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (val & ADVERTISE_1000FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) p = reg31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) else if (val & ADVERTISE_1000HALF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) p = reg31 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) val &= adv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) for (p = reg31; p->val; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if ((val & p->val) == p->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if ((tp->features & F_HAS_RGMII) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) (tp->features & F_PHY_BCM5461)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) // Set Tx Delay in RGMII mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) mdio_write(ioaddr, phy_id, 0x18, 0xf1c7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) mdio_write(ioaddr, phy_id, 0x1c, 0x8c00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) p->ctl |= 0x03000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) SIS_W32(StationControl, p->ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (tp->features & F_HAS_RGMII) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) SIS_W32(RGDelay, 0x0441);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) SIS_W32(RGDelay, 0x0440);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) tp->negotiated_lpa = p->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) netif_info(tp, link, dev, "link on %s mode\n", p->msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) netif_carrier_on(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) tp->link_status = LNK_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) } else if (!(val & BMSR_LSTATUS) && tp->link_status != LNK_AUTONEG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) tp->link_status = LNK_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) rtnl_unlock();
^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 void sis190_phy_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) struct sis190_private *tp = from_timer(tp, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) struct net_device *dev = tp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (likely(netif_running(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) schedule_work(&tp->phy_task);
^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 inline void sis190_delete_timer(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) del_timer_sync(&tp->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static inline void sis190_request_timer(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct timer_list *timer = &tp->timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) timer_setup(timer, sis190_phy_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) timer->expires = jiffies + SIS190_PHY_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) add_timer(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static void sis190_set_rxbufsize(struct sis190_private *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) unsigned int mtu = dev->mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* RxDesc->size has a licence to kill the lower bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (tp->rx_buf_sz & 0x07) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) tp->rx_buf_sz += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) tp->rx_buf_sz &= RX_BUF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static int sis190_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct pci_dev *pdev = tp->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) sis190_set_rxbufsize(tp, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * Rx and Tx descriptors need 256 bytes alignment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * pci_alloc_consistent() guarantees a stronger alignment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) tp->TxDescRing = dma_alloc_coherent(&pdev->dev, TX_RING_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) &tp->tx_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (!tp->TxDescRing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) tp->RxDescRing = dma_alloc_coherent(&pdev->dev, RX_RING_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) &tp->rx_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (!tp->RxDescRing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) goto err_free_tx_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) rc = sis190_init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) goto err_free_rx_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) sis190_request_timer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) rc = request_irq(pdev->irq, sis190_irq, IRQF_SHARED, dev->name, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) goto err_release_timer_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) sis190_hw_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) err_release_timer_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) sis190_delete_timer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) sis190_rx_clear(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) err_free_rx_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dma_free_coherent(&pdev->dev, RX_RING_BYTES, tp->RxDescRing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) tp->rx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) err_free_tx_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) dma_free_coherent(&pdev->dev, TX_RING_BYTES, tp->TxDescRing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) tp->tx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) static void sis190_tx_clear(struct sis190_private *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) for (i = 0; i < NUM_TX_DESC; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct sk_buff *skb = tp->Tx_skbuff[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) sis190_unmap_tx_skb(tp->pci_dev, skb, tp->TxDescRing + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) tp->Tx_skbuff[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) tp->dev->stats.tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) tp->cur_tx = tp->dirty_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static void sis190_down(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) unsigned int poll_locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) sis190_delete_timer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) spin_lock_irq(&tp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) sis190_asic_down(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) spin_unlock_irq(&tp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) synchronize_irq(tp->pci_dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (!poll_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) poll_locked++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) } while (SIS_R32(IntrMask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) sis190_tx_clear(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) sis190_rx_clear(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static int sis190_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct pci_dev *pdev = tp->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) sis190_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) free_irq(pdev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) dma_free_coherent(&pdev->dev, TX_RING_BYTES, tp->TxDescRing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) tp->tx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) dma_free_coherent(&pdev->dev, RX_RING_BYTES, tp->RxDescRing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) tp->rx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) tp->TxDescRing = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) tp->RxDescRing = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) static netdev_tx_t sis190_start_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) u32 len, entry, dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct TxDesc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) dma_addr_t mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (unlikely(skb->len < ETH_ZLEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (skb_padto(skb, ETH_ZLEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) dev->stats.tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) len = ETH_ZLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) entry = tp->cur_tx % NUM_TX_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) desc = tp->TxDescRing + entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (unlikely(le32_to_cpu(desc->status) & OWNbit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) netif_err(tp, tx_err, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) "BUG! Tx Ring full when queue awake!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (dma_mapping_error(&tp->pci_dev->dev, mapping)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) netif_err(tp, tx_err, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) "PCI mapping failed, dropping packet");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) tp->Tx_skbuff[entry] = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) desc->PSize = cpu_to_le32(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) desc->addr = cpu_to_le32(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) desc->size = cpu_to_le32(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (entry == (NUM_TX_DESC - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) desc->size |= cpu_to_le32(RingEnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (tp->negotiated_lpa & (LPA_1000HALF | LPA_100HALF | LPA_10HALF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) /* Half Duplex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) desc->status |= cpu_to_le32(COLEN | CRSEN | BKFEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (tp->negotiated_lpa & (LPA_1000HALF | LPA_1000FULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) desc->status |= cpu_to_le32(EXTEN | BSTEN); /* gigabit HD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) tp->cur_tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) dirty_tx = tp->dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (dirty_tx != tp->dirty_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return NETDEV_TX_OK;
^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 void sis190_free_phy(struct list_head *first_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) struct sis190_phy *cur, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) list_for_each_entry_safe(cur, next, first_phy, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) kfree(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) * sis190_default_phy - Select default PHY for sis190 mac.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) * @dev: the net device to probe for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * Select first detected PHY with link as default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * If no one is link on, select PHY whose types is HOME as default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * If HOME doesn't exist, select LAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static u16 sis190_default_phy(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct sis190_phy *phy, *phy_home, *phy_default, *phy_lan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct mii_if_info *mii_if = &tp->mii_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) phy_home = phy_default = phy_lan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) list_for_each_entry(phy, &tp->first_phy, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) status = mdio_read_latched(ioaddr, phy->phy_id, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) // Link ON & Not select default PHY & not ghost PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if ((status & BMSR_LSTATUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) !phy_default &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) (phy->type != UNKNOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) phy_default = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) status = mdio_read(ioaddr, phy->phy_id, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) mdio_write(ioaddr, phy->phy_id, MII_BMCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) status | BMCR_ANENABLE | BMCR_ISOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (phy->type == HOME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) phy_home = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) else if (phy->type == LAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) phy_lan = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (!phy_default) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (phy_home)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) phy_default = phy_home;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) else if (phy_lan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) phy_default = phy_lan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) phy_default = list_first_entry(&tp->first_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) struct sis190_phy, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (mii_if->phy_id != phy_default->phy_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) mii_if->phy_id = phy_default->phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) pr_info("%s: Using transceiver at address %d as default\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) pci_name(tp->pci_dev), mii_if->phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) status = mdio_read(ioaddr, mii_if->phy_id, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) status &= (~BMCR_ISOLATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) mdio_write(ioaddr, mii_if->phy_id, MII_BMCR, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) status = mdio_read_latched(ioaddr, mii_if->phy_id, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct sis190_phy *phy, unsigned int phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) u16 mii_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct mii_chip_info *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) INIT_LIST_HEAD(&phy->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) phy->status = mii_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) phy->phy_id = phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) phy->id[0] = mdio_read(ioaddr, phy_id, MII_PHYSID1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) phy->id[1] = mdio_read(ioaddr, phy_id, MII_PHYSID2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) for (p = mii_chip_table; p->type; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if ((p->id[0] == phy->id[0]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) (p->id[1] == (phy->id[1] & 0xfff0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (p->id[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) phy->type = (p->type == MIX) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) LAN : HOME) : p->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) tp->features |= p->feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) pr_info("%s: %s transceiver at address %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) pci_name(tp->pci_dev), p->name, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) phy->type = UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) pr_info("%s: unknown PHY 0x%x:0x%x transceiver at address %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) pci_name(tp->pci_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) phy->id[0], (phy->id[1] & 0xfff0), phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (tp->features & F_PHY_88E1111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) int phy_id = tp->mii_if.phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) u16 reg[2][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) { 0x808b, 0x0ce1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) { 0x808f, 0x0c60 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) mdio_write(ioaddr, phy_id, 0x1b, p[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) mdio_write(ioaddr, phy_id, 0x14, p[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * sis190_mii_probe - Probe MII PHY for sis190
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * @dev: the net device to probe for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * Search for total of 32 possible mii phy addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * Identify and set current phy if found one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * return error if it failed to found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) static int sis190_mii_probe(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct mii_if_info *mii_if = &tp->mii_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) int phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) INIT_LIST_HEAD(&tp->first_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) struct sis190_phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) status = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) // Try next mii if the current one is not accessible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (status == 0xffff || status == 0x0000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) phy = kmalloc(sizeof(*phy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (!phy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) sis190_free_phy(&tp->first_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) sis190_init_phy(dev, tp, phy, phy_id, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) list_add(&tp->first_phy, &phy->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (list_empty(&tp->first_phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) pr_info("%s: No MII transceivers found!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) pci_name(tp->pci_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /* Select default PHY for mac */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) sis190_default_phy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) sis190_mii_probe_88e1111_fixup(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) mii_if->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) mii_if->mdio_read = __mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) mii_if->mdio_write = __mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) mii_if->phy_id_mask = PHY_ID_ANY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) mii_if->reg_num_mask = MII_REG_ANY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) static void sis190_mii_remove(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) sis190_free_phy(&tp->first_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) static void sis190_release_board(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) struct net_device *dev = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) iounmap(tp->mmio_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) static struct net_device *sis190_init_board(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) struct sis190_private *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) void __iomem *ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) dev = alloc_etherdev(sizeof(*tp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) goto err_out_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) SET_NETDEV_DEV(dev, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) tp->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) rc = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) pr_err("%s: enable failure\n", pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) goto err_free_dev_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) pr_err("%s: region #0 is no MMIO resource\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) goto err_pci_disable_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (pci_resource_len(pdev, 0) < SIS190_REGS_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) pr_err("%s: invalid PCI region size(s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) goto err_pci_disable_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) rc = pci_request_regions(pdev, DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) pr_err("%s: could not request regions\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) goto err_pci_disable_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) pr_err("%s: DMA configuration failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) goto err_free_res_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) ioaddr = ioremap(pci_resource_start(pdev, 0), SIS190_REGS_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (!ioaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) pr_err("%s: cannot remap MMIO, aborting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) goto err_free_res_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) tp->pci_dev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) tp->mmio_addr = ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) tp->link_status = LNK_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) sis190_irq_mask_and_ack(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) sis190_soft_reset(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) err_free_res_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) err_pci_disable_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) err_free_dev_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) err_out_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) dev = ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) static void sis190_tx_timeout(struct net_device *dev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) u8 tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) /* Disable Tx, if not already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) tmp8 = SIS_R8(TxControl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) if (tmp8 & CmdTxEnb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) SIS_W8(TxControl, tmp8 & ~CmdTxEnb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) netif_info(tp, tx_err, dev, "Transmit timeout, status %08x %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) SIS_R32(TxControl), SIS_R32(TxSts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) /* Disable interrupts by clearing the interrupt mask. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) SIS_W32(IntrMask, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) /* Stop a shared interrupt from scavenging while we are. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) spin_lock_irq(&tp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) sis190_tx_clear(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) spin_unlock_irq(&tp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /* ...and finally, reset everything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) sis190_hw_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) static void sis190_set_rgmii(struct sis190_private *tp, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static int sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) u16 sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) pr_info("%s: Read MAC address from EEPROM\n", pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) /* Check to see if there is a sane EEPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if ((sig == 0xffff) || (sig == 0x0000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) pr_info("%s: Error EEPROM read %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) pci_name(pdev), sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) /* Get MAC address from EEPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) for (i = 0; i < ETH_ALEN / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) u16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) * sis190_get_mac_addr_from_apc - Get MAC address for SiS96x model
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) * @pdev: PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) * @dev: network device to get address for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) * SiS96x model, use APC CMOS RAM to store MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) * APC CMOS RAM is accessed through ISA bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) * MAC address is read into @net_dev->dev_addr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) static int sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) static const u16 ids[] = { 0x0965, 0x0966, 0x0968 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) struct pci_dev *isa_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) u8 reg, tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) pr_info("%s: Read MAC address from APC\n", pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) for (i = 0; i < ARRAY_SIZE(ids); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, ids[i], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (isa_bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (!isa_bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (netif_msg_probe(tp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) pr_info("%s: Can not find ISA bridge\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) /* Enable port 78h & 79h to access APC Registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) pci_read_config_byte(isa_bridge, 0x48, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) reg = (tmp8 & ~0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) pci_write_config_byte(isa_bridge, 0x48, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) pci_read_config_byte(isa_bridge, 0x48, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) for (i = 0; i < ETH_ALEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) outb(0x9 + i, 0x78);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) dev->dev_addr[i] = inb(0x79);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) outb(0x12, 0x78);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) reg = inb(0x79);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) sis190_set_rgmii(tp, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) /* Restore the value to ISA Bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) pci_write_config_byte(isa_bridge, 0x48, tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) pci_dev_put(isa_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) * sis190_init_rxfilter - Initialize the Rx filter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) * @dev: network device to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) * Set receive filter address to our MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) * and enable packet filtering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) static inline void sis190_init_rxfilter(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) u16 ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) ctl = SIS_R16(RxMacControl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * Disable packet filtering before setting filter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * Note: SiS's driver writes 32 bits but RxMacControl is 16 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) * only and followed by RxMacAddr (6 bytes). Strange. -- FR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) SIS_W16(RxMacControl, ctl & ~0x0f00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) for (i = 0; i < ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) SIS_W8(RxMacAddr + i, dev->dev_addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) SIS_W16(RxMacControl, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) SIS_PCI_COMMIT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) rc = sis190_get_mac_addr_from_eeprom(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) pci_read_config_byte(pdev, 0x73, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (reg & 0x00000001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) rc = sis190_get_mac_addr_from_apc(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) static void sis190_set_speed_auto(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) void __iomem *ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) int phy_id = tp->mii_if.phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) netif_info(tp, link, dev, "Enabling Auto-negotiation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) val = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) // Enable 10/100 Full/Half Mode, leave MII_ADVERTISE bit4:0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) // unchanged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) mdio_write(ioaddr, phy_id, MII_ADVERTISE, (val & ADVERTISE_SLCT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) ADVERTISE_100FULL | ADVERTISE_10FULL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) ADVERTISE_100HALF | ADVERTISE_10HALF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) // Enable 1000 Full Mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) mdio_write(ioaddr, phy_id, MII_CTRL1000, ADVERTISE_1000FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) // Enable auto-negotiation and restart auto-negotiation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) mdio_write(ioaddr, phy_id, MII_BMCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) static int sis190_get_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) mii_ethtool_get_link_ksettings(&tp->mii_if, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) static int sis190_set_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) const struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) return mii_ethtool_set_link_ksettings(&tp->mii_if, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) static void sis190_get_drvinfo(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) strlcpy(info->version, DRV_VERSION, sizeof(info->version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) strlcpy(info->bus_info, pci_name(tp->pci_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) sizeof(info->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static int sis190_get_regs_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return SIS190_REGS_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) static void sis190_get_regs(struct net_device *dev, struct ethtool_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) spin_lock_irqsave(&tp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) memcpy_fromio(p, tp->mmio_addr, regs->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) spin_unlock_irqrestore(&tp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) static int sis190_nway_reset(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) return mii_nway_restart(&tp->mii_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) static u32 sis190_get_msglevel(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) return tp->msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static void sis190_set_msglevel(struct net_device *dev, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) tp->msg_enable = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) static const struct ethtool_ops sis190_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) .get_drvinfo = sis190_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) .get_regs_len = sis190_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) .get_regs = sis190_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) .get_link = ethtool_op_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) .get_msglevel = sis190_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) .set_msglevel = sis190_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) .nway_reset = sis190_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) .get_link_ksettings = sis190_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) .set_link_ksettings = sis190_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) return !netif_running(dev) ? -EINVAL :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) static int sis190_mac_addr(struct net_device *dev, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) rc = eth_mac_addr(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) sis190_init_rxfilter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) static const struct net_device_ops sis190_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) .ndo_open = sis190_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) .ndo_stop = sis190_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) .ndo_do_ioctl = sis190_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) .ndo_start_xmit = sis190_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) .ndo_tx_timeout = sis190_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) .ndo_set_rx_mode = sis190_set_rx_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) .ndo_set_mac_address = sis190_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) .ndo_poll_controller = sis190_netpoll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) static int sis190_init_one(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) static int printed_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) struct sis190_private *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) void __iomem *ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) if (!printed_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (netif_msg_drv(&debug))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) pr_info(SIS190_DRIVER_NAME " loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) printed_version = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) dev = sis190_init_board(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if (IS_ERR(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) rc = PTR_ERR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) pci_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) ioaddr = tp->mmio_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) rc = sis190_get_mac_addr(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) goto err_release_board;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) sis190_init_rxfilter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) INIT_WORK(&tp->phy_task, sis190_phy_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) dev->netdev_ops = &sis190_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) dev->ethtool_ops = &sis190_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) dev->watchdog_timeo = SIS190_TX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) spin_lock_init(&tp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) rc = sis190_mii_probe(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) goto err_release_board;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) rc = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) goto err_remove_mii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if (netif_msg_probe(tp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) netdev_info(dev, "%s: %s at %p (IRQ: %d), %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) pci_name(pdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) sis_chip_info[ent->driver_data].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) ioaddr, pdev->irq, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) netdev_info(dev, "%s mode.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) sis190_set_speed_auto(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) err_remove_mii:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) sis190_mii_remove(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) err_release_board:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) sis190_release_board(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) static void sis190_remove_one(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) struct net_device *dev = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) struct sis190_private *tp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) sis190_mii_remove(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) cancel_work_sync(&tp->phy_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) sis190_release_board(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) static struct pci_driver sis190_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) .id_table = sis190_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) .probe = sis190_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) .remove = sis190_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) module_pci_driver(sis190_pci_driver);