Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &reg);
^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, &reg);
^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);