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) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * New driver for Marvell Yukon 2 chipset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Based on earlier sk98lin, and skge driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * This driver intentionally does not support all the features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * of the original driver such as link fail-over and link management because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * those should be done at higher levels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/prefetch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/of_net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include "sky2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define DRV_NAME		"sky2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define DRV_VERSION		"1.30"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  * The Yukon II chipset takes 64 bit command blocks (called list elements)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  * that are organized into three (receive, transmit, status) different rings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  * similar to Tigon3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define RX_LE_SIZE	    	1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define RX_LE_BYTES		(RX_LE_SIZE*sizeof(struct sky2_rx_le))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define RX_MAX_PENDING		(RX_LE_SIZE/6 - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define RX_DEF_PENDING		RX_MAX_PENDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) /* This is the worst case number of transmit list elements for a single skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)    VLAN:GSO + CKSUM + Data + skb_frags * DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define MAX_SKB_TX_LE	(2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define TX_MIN_PENDING		(MAX_SKB_TX_LE+1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define TX_MAX_PENDING		1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define TX_DEF_PENDING		63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define TX_WATCHDOG		(5 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define NAPI_WEIGHT		64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define PHY_RETRIES		1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define SKY2_EEPROM_MAGIC	0x9955aabb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define RING_NEXT(x, s)	(((x)+1) & ((s)-1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) static const u32 default_msg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)     NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)     | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)     | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) static int debug = -1;		/* defaults above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) module_param(debug, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) static int copybreak __read_mostly = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) module_param(copybreak, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) MODULE_PARM_DESC(copybreak, "Receive copy threshold");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) static int disable_msi = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) module_param(disable_msi, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static int legacy_pme = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) module_param(legacy_pme, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) MODULE_PARM_DESC(legacy_pme, "Legacy power management");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) static const struct pci_device_id sky2_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E01) }, /* SK-9E21M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },	/* DGE-560T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, 	/* DGE-550SX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B02) },	/* DGE-560SX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B03) },	/* DGE-550T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, /* 88E8021 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, /* 88E8022 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, /* 88E8061 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) }, /* 88E8062 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) }, /* 88E8021 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) }, /* 88E8022 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) }, /* 88E8061 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) }, /* 88E8062 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) }, /* 88E8035 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4355) }, /* 88E8040T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, /* 88E8070 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4381) }, /* 88E8059 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4382) }, /* 88E8079 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	{ 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) MODULE_DEVICE_TABLE(pci, sky2_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) /* Avoid conditionals by using array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static void sky2_set_multicast(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) static irqreturn_t sky2_intr(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) /* Access to PHY via serial interconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	gma_write16(hw, port, GM_SMI_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	gma_write16(hw, port, GM_SMI_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 		    GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	for (i = 0; i < PHY_RETRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		if (ctrl == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			goto io_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		if (!(ctrl & GM_SMI_CT_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	dev_warn(&hw->pdev->dev, "%s: phy write timeout\n", hw->dev[port]->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) io_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		    | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	for (i = 0; i < PHY_RETRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		if (ctrl == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 			goto io_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		if (ctrl & GM_SMI_CT_RD_VAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			*val = gma_read16(hw, port, GM_SMI_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	dev_warn(&hw->pdev->dev, "%s: phy read timeout\n", hw->dev[port]->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) io_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	u16 v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	__gm_phy_read(hw, port, reg, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) static void sky2_power_on(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	/* switch power to VCC (WA for VAUX problem) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	sky2_write8(hw, B0_POWER_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	/* disable Core Clock Division, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		/* enable bits are inverted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		sky2_write8(hw, B2_Y2_CLK_GATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			    Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 			    Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 			    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		sky2_write8(hw, B2_Y2_CLK_GATE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		sky2_pci_write32(hw, PCI_DEV_REG3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		reg = sky2_pci_read32(hw, PCI_DEV_REG4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		/* set all bits to 0 except bits 15..12 and 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		reg &= P_ASPM_CONTROL_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		sky2_pci_write32(hw, PCI_DEV_REG4, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		reg = sky2_pci_read32(hw, PCI_DEV_REG5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		/* set all bits to 0 except bits 28 & 27 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		reg &= P_CTL_TIM_VMAIN_AV_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		sky2_pci_write32(hw, PCI_DEV_REG5, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		sky2_pci_write32(hw, PCI_CFG_REG_1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		/* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		reg = sky2_read32(hw, B2_GP_IO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		reg |= GLB_GPIO_STAT_RACE_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		sky2_write32(hw, B2_GP_IO, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		sky2_read32(hw, B2_GP_IO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	/* Turn on "driver loaded" LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	sky2_write16(hw, B0_CTST, Y2_LED_STAT_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) static void sky2_power_aux(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		sky2_write8(hw, B2_Y2_CLK_GATE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		/* enable bits are inverted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		sky2_write8(hw, B2_Y2_CLK_GATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			    Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 			    Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 			    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	/* switch power to VAUX if supported and PME from D3cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	if ( (sky2_read32(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	     pci_pme_capable(hw->pdev, PCI_D3cold))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		sky2_write8(hw, B0_POWER_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			    (PC_VAUX_ENA | PC_VCC_ENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			     PC_VAUX_ON | PC_VCC_OFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	/* turn off "driver loaded LED" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	sky2_write16(hw, B0_CTST, Y2_LED_STAT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	/* disable all GMAC IRQ's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	gma_write16(hw, port, GM_MC_ADDR_H1, 0);	/* clear MC hash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	gma_write16(hw, port, GM_MC_ADDR_H2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	gma_write16(hw, port, GM_MC_ADDR_H3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	gma_write16(hw, port, GM_MC_ADDR_H4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	reg = gma_read16(hw, port, GM_RX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	reg |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	gma_write16(hw, port, GM_RX_CTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) /* flow control to advertise bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) static const u16 copper_fc_adv[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	[FC_NONE]	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	[FC_TX]		= PHY_M_AN_ASP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	[FC_RX]		= PHY_M_AN_PC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	[FC_BOTH]	= PHY_M_AN_PC | PHY_M_AN_ASP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) /* flow control to advertise bits when using 1000BaseX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) static const u16 fiber_fc_adv[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	[FC_NONE] = PHY_M_P_NO_PAUSE_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	[FC_TX]   = PHY_M_P_ASYM_MD_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	[FC_RX]	  = PHY_M_P_SYM_MD_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	[FC_BOTH] = PHY_M_P_BOTH_MD_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) /* flow control to GMA disable bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) static const u16 gm_fc_disable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	[FC_NONE] = GM_GPCR_FC_RX_DIS | GM_GPCR_FC_TX_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	[FC_TX]	  = GM_GPCR_FC_RX_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	[FC_RX]	  = GM_GPCR_FC_TX_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	[FC_BOTH] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	    !(hw->flags & SKY2_HW_NEWER_PHY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 			   PHY_M_EC_MAC_S_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		/* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		if (hw->chip_id == CHIP_ID_YUKON_EC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 			/* set downshift counter to 3x and enable downshift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 			ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 			/* set master & slave downshift counter to 1x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 			ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	if (sky2_is_copper(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		if (!(hw->flags & SKY2_HW_GIGABIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 			/* enable automatic crossover */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			    hw->chip_rev == CHIP_REV_YU_FE2_A0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 				u16 spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 				/* Enable Class A driver for FE+ A0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 				spec = gm_phy_read(hw, port, PHY_MARV_FE_SPEC_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 				spec |= PHY_M_FESC_SEL_CL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 				gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 			/* disable energy detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 			ctrl &= ~PHY_M_PC_EN_DET_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 			/* enable automatic crossover */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			/* downshift on PHY 88E1112 and 88E1149 is changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 			if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			     (hw->flags & SKY2_HW_NEWER_PHY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 				/* set downshift counter to 3x and enable downshift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 				ctrl &= ~PHY_M_PC_DSC_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 				ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
^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) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		/* workaround for deviation #4.88 (CRC errors) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		/* disable Automatic Crossover */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		ctrl &= ~PHY_M_PC_MDIX_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	/* special setup for PHY 88E1112 Fiber */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	if (hw->chip_id == CHIP_ID_YUKON_XL && (hw->flags & SKY2_HW_FIBRE_PHY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		/* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		ctrl &= ~PHY_M_MAC_MD_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		if (hw->pmd_type  == 'P') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			/* select page 1 to access Fiber registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			/* for SFP-module set SIGDET polarity to low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			ctrl |= PHY_M_FIB_SIGD_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
^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) 	ctrl = PHY_CT_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	ct1000 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	adv = PHY_AN_CSMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	if (sky2->flags & SKY2_FLAG_AUTO_SPEED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		if (sky2_is_copper(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 			if (sky2->advertising & ADVERTISED_1000baseT_Full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 				ct1000 |= PHY_M_1000C_AFD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			if (sky2->advertising & ADVERTISED_1000baseT_Half)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 				ct1000 |= PHY_M_1000C_AHD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 			if (sky2->advertising & ADVERTISED_100baseT_Full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 				adv |= PHY_M_AN_100_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			if (sky2->advertising & ADVERTISED_100baseT_Half)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 				adv |= PHY_M_AN_100_HD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			if (sky2->advertising & ADVERTISED_10baseT_Full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				adv |= PHY_M_AN_10_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 			if (sky2->advertising & ADVERTISED_10baseT_Half)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 				adv |= PHY_M_AN_10_HD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		} else {	/* special defines for FIBER (88E1040S only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 			if (sky2->advertising & ADVERTISED_1000baseT_Full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				adv |= PHY_M_AN_1000X_AFD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			if (sky2->advertising & ADVERTISED_1000baseT_Half)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 				adv |= PHY_M_AN_1000X_AHD;
^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) 		/* Restart Auto-negotiation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		/* forced speed/duplex settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		ct1000 = PHY_M_1000C_MSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		/* Disable auto update for duplex flow control and duplex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		reg |= GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_SPD_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		switch (sky2->speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		case SPEED_1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			ctrl |= PHY_CT_SP1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			reg |= GM_GPCR_SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		case SPEED_100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 			ctrl |= PHY_CT_SP100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			reg |= GM_GPCR_SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		if (sky2->duplex == DUPLEX_FULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			reg |= GM_GPCR_DUP_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			ctrl |= PHY_CT_DUP_MD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		} else if (sky2->speed < SPEED_1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 			sky2->flow_mode = FC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	if (sky2->flags & SKY2_FLAG_AUTO_PAUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		if (sky2_is_copper(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 			adv |= copper_fc_adv[sky2->flow_mode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			adv |= fiber_fc_adv[sky2->flow_mode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		reg |= GM_GPCR_AU_FCT_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473)  		reg |= gm_fc_disable[sky2->flow_mode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		/* Forward pause packets to GMAC? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		if (sky2->flow_mode & FC_RX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	gma_write16(hw, port, GM_GP_CTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	if (hw->flags & SKY2_HW_GIGABIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	/* Setup Phy LED's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	ledover = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	switch (hw->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	case CHIP_ID_YUKON_FE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		/* on 88E3082 these bits are at 11..9 (shifted left) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		/* delete ACT LED control bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		ctrl &= ~PHY_M_FELP_LED1_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		/* change ACT LED control to blink mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	case CHIP_ID_YUKON_FE_P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		/* Enable Link Partner Next Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		ctrl |= PHY_M_PC_ENA_LIP_NP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		/* disable Energy Detect and enable scrambler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		/* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 			PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 			PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	case CHIP_ID_YUKON_XL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		/* select page 3 to access LED control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		/* set LED Function Control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 			     (PHY_M_LEDC_LOS_CTRL(1) |	/* LINK/ACT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 			      PHY_M_LEDC_INIT_CTRL(7) |	/* 10 Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 			      PHY_M_LEDC_STA1_CTRL(7) |	/* 100 Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 			      PHY_M_LEDC_STA0_CTRL(7)));	/* 1000 Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		/* set Polarity Control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 			     (PHY_M_POLC_LS1_P_MIX(4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 			      PHY_M_POLC_IS0_P_MIX(4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 			      PHY_M_POLC_LOS_CTRL(2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 			      PHY_M_POLC_INIT_CTRL(2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			      PHY_M_POLC_STA1_CTRL(2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			      PHY_M_POLC_STA0_CTRL(2)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		/* restore page register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	case CHIP_ID_YUKON_EC_U:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	case CHIP_ID_YUKON_EX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	case CHIP_ID_YUKON_SUPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		/* select page 3 to access LED control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		/* set LED Function Control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 			     (PHY_M_LEDC_LOS_CTRL(1) |	/* LINK/ACT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 			      PHY_M_LEDC_INIT_CTRL(8) |	/* 10 Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			      PHY_M_LEDC_STA1_CTRL(7) |	/* 100 Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 			      PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		/* set Blink Rate in LED Timer Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		gm_phy_write(hw, port, PHY_MARV_INT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 			     ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		/* restore page register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		/* turn off the Rx LED (LED_RX) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_UL_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		/* apply fixes in PHY AFE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		/* increase differential signal amplitude in 10BASE-T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		gm_phy_write(hw, port, 0x18, 0xaa99);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		gm_phy_write(hw, port, 0x17, 0x2011);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 			/* fix for IEEE A/B Symmetry failure in 1000BASE-T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 			gm_phy_write(hw, port, 0x18, 0xa204);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 			gm_phy_write(hw, port, 0x17, 0x2002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		/* set page register to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	} else if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		   hw->chip_rev == CHIP_REV_YU_FE2_A0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		/* apply workaround for integrated resistors calibration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	} else if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		/* apply fixes in PHY AFE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		/* apply RDAC termination workaround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		gm_phy_write(hw, port, 24, 0x2800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		gm_phy_write(hw, port, 23, 0x2001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		/* set page register back to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	} else if (hw->chip_id != CHIP_ID_YUKON_EX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		   hw->chip_id < CHIP_ID_YUKON_SUPR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		/* no effect on Yukon-XL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		if (!(sky2->flags & SKY2_FLAG_AUTO_SPEED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		    sky2->speed == SPEED_100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			/* turn on 100 Mbps LED (LED_LINK100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 			ledover |= PHY_M_LED_MO_100(MO_LED_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		if (ledover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 			gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	} else if (hw->chip_id == CHIP_ID_YUKON_PRM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		   (sky2_read8(hw, B2_MAC_CFG) & 0xf) == 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		/* This a phy register setup workaround copied from vendor driver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			u16 reg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		} eee_afe[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 			{ 0x156, 0x58ce },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			{ 0x153, 0x99eb },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			{ 0x141, 0x8064 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			/* { 0x155, 0x130b },*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			{ 0x000, 0x0000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			{ 0x151, 0x8433 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 			{ 0x14b, 0x8c44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			{ 0x14c, 0x0f90 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			{ 0x14f, 0x39aa },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			/* { 0x154, 0x2f39 },*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 			{ 0x14d, 0xba33 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			{ 0x144, 0x0048 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			{ 0x152, 0x2010 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			/* { 0x158, 0x1223 },*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			{ 0x140, 0x4444 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			{ 0x154, 0x2f3b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			{ 0x158, 0xb203 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			{ 0x157, 0x2029 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		/* Start Workaround for OptimaEEE Rev.Z0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		gm_phy_write(hw, port,  1, 0x4099);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		gm_phy_write(hw, port,  3, 0x1120);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		gm_phy_write(hw, port, 11, 0x113c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		gm_phy_write(hw, port, 14, 0x8100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		gm_phy_write(hw, port, 15, 0x112a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		gm_phy_write(hw, port, 17, 0x1008);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		gm_phy_write(hw, port,  1, 0x20b0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		for (i = 0; i < ARRAY_SIZE(eee_afe); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			/* apply AFE settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 			gm_phy_write(hw, port, 17, eee_afe[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			gm_phy_write(hw, port, 16, eee_afe[i].reg | 1u<<13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		/* End Workaround for OptimaEEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		/* Enable 10Base-Te (EEE) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		if (hw->chip_id >= CHIP_ID_YUKON_PRM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 			reg = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			gm_phy_write(hw, port, PHY_MARV_EXT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 				     reg | PHY_M_10B_TE_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	/* Enable phy interrupt on auto-negotiation complete (or link up) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	if (sky2->flags & SKY2_FLAG_AUTO_SPEED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	u32 reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	reg1 &= ~phy_power[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		reg1 |= coma_mode[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	sky2_pci_read32(hw, PCI_DEV_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	if (hw->chip_id == CHIP_ID_YUKON_FE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_ANE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	else if (hw->flags & SKY2_HW_ADV_POWER_CTL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	u32 reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	u16 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	/* release GPHY Control reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	/* release GMAC reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	if (hw->flags & SKY2_HW_NEWER_PHY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		/* select page 2 to access MAC control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		/* allow GMII Power Down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		ctrl &= ~PHY_M_MAC_GMIF_PUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		/* set page register back to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	/* setup General Purpose Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	gma_write16(hw, port, GM_GP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		    GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		    GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		    GM_GPCR_AU_SPD_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	if (hw->chip_id != CHIP_ID_YUKON_EC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			/* select page 2 to access MAC control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			/* enable Power Down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			ctrl |= PHY_M_PC_POW_D_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			/* set page register back to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		/* set IEEE compatible Power Down Mode (dev. #4.99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	reg1 |= phy_power[port];		/* set PHY to PowerDown/COMA Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) /* configure IPG according to used link speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) static void sky2_set_ipg(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	reg = gma_read16(sky2->hw, sky2->port, GM_SERIAL_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	reg &= ~GM_SMOD_IPG_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	if (sky2->speed > SPEED_100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		reg |= IPG_DATA_VAL(IPG_DATA_DEF_1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		reg |= IPG_DATA_VAL(IPG_DATA_DEF_10_100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	gma_write16(sky2->hw, sky2->port, GM_SERIAL_MODE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) /* Enable Rx/Tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) static void sky2_enable_rx_tx(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	reg = gma_read16(hw, port, GM_GP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	gma_write16(hw, port, GM_GP_CTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) /* Force a renegotiation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) static void sky2_phy_reinit(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	spin_lock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	sky2_phy_init(sky2->hw, sky2->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	sky2_enable_rx_tx(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	spin_unlock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) /* Put device in state to listen for Wake On Lan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) static void sky2_wol_init(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	enum flow_control save_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	u16 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	/* Bring hardware out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	sky2_write16(hw, B0_CTST, CS_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	sky2_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	/* Force to 10/100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	 * sky2_reset will re-enable on resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	save_mode = sky2->flow_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	ctrl = sky2->advertising;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	sky2->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	sky2->flow_mode = FC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	spin_lock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	sky2_phy_power_up(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	sky2_phy_init(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	spin_unlock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	sky2->flow_mode = save_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	sky2->advertising = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	/* Set GMAC to no flow control and auto update for speed/duplex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	gma_write16(hw, port, GM_GP_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		    GM_GPCR_FC_TX_DIS|GM_GPCR_TX_ENA|GM_GPCR_RX_ENA|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		    GM_GPCR_DUP_FULL|GM_GPCR_FC_RX_DIS|GM_GPCR_AU_FCT_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	/* Set WOL address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	memcpy_toio(hw->regs + WOL_REGS(port, WOL_MAC_ADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		    sky2->netdev->dev_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	/* Turn on appropriate WOL control bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), WOL_CTL_CLEAR_RESULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	if (sky2->wol & WAKE_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG|WOL_CTL_ENA_LINK_CHG_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG|WOL_CTL_DIS_LINK_CHG_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	if (sky2->wol & WAKE_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	/* Disable PiG firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	sky2_write16(hw, B0_CTST, Y2_HW_WOL_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	/* Needed by some broken BIOSes, use PCI rather than PCI-e for WOL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	if (legacy_pme) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		u32 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		reg1 |= PCI_Y2_PME_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	/* block receiver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	sky2_read32(hw, B0_CTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	struct net_device *dev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if ( (hw->chip_id == CHIP_ID_YUKON_EX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	      hw->chip_rev != CHIP_REV_YU_EX_A0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	     hw->chip_id >= CHIP_ID_YUKON_FE_P) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		/* Yukon-Extreme B0 and further Extreme devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	} else if (dev->mtu > ETH_DATA_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		/* set Tx GMAC FIFO Almost Empty Threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			     (ECU_JUMBO_WM << 16) | ECU_AE_THR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	u32 rx_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	const u8 *addr = hw->dev[port]->dev_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	if (hw->chip_id == CHIP_ID_YUKON_XL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	    hw->chip_rev == CHIP_REV_YU_XL_A0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	    port == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		/* WA DEV_472 -- looks like crossed wires on port 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		/* clear GMAC 1 Control reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		} while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 			 gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 			 gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	/* Enable Transmit FIFO Underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	spin_lock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	sky2_phy_power_up(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	sky2_phy_init(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	spin_unlock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	/* MIB clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	reg = gma_read16(hw, port, GM_PHY_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		gma_read16(hw, port, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	gma_write16(hw, port, GM_PHY_ADDR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	/* transmit control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	/* receive control reg: unicast + multicast + no FCS  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	gma_write16(hw, port, GM_RX_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		    GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/* transmit flow control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	/* transmit parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	gma_write16(hw, port, GM_TX_PARAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		    TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		    TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		    TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		    TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	/* serial mode register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF_1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (hw->dev[port]->mtu > ETH_DATA_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		reg |= GM_SMOD_JUMBO_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	    hw->chip_rev == CHIP_REV_YU_EC_U_B1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		reg |= GM_NEW_FLOW_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	gma_write16(hw, port, GM_SERIAL_MODE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	/* virtual address for data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	/* physical address: used for pause frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	/* ignore counter overflows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	/* Configure Rx MAC FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	if (hw->chip_id == CHIP_ID_YUKON_EX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	    hw->chip_id == CHIP_ID_YUKON_FE_P)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		rx_reg |= GMF_RX_OVER_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	if (hw->chip_id == CHIP_ID_YUKON_XL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		/* Hardware errata - clear flush mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		/* Flush Rx MAC FIFO on any flow control or error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	/* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	reg = RX_GMF_FL_THR_DEF + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	/* Another magic mystery workaround from sk98lin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	    hw->chip_rev == CHIP_REV_YU_FE2_A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		reg = 0x178;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	/* Configure Tx MAC FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	/* On chips without ram buffer, pause is controlled by MAC level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		/* Pause threshold is scaled by 8 in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		    hw->chip_rev == CHIP_REV_YU_FE2_A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			reg = 1568 / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			reg = 1024 / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		sky2_write16(hw, SK_REG(port, RX_GMF_UP_THR), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		sky2_write16(hw, SK_REG(port, RX_GMF_LP_THR), 768 / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		sky2_set_tx_stfwd(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	    hw->chip_rev == CHIP_REV_YU_FE2_A0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		/* disable dynamic watermark */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		reg = sky2_read16(hw, SK_REG(port, TX_GMF_EA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		reg &= ~TX_DYN_WM_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		sky2_write16(hw, SK_REG(port, TX_GMF_EA), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* Assign Ram Buffer allocation to queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	u32 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	/* convert from K bytes to qwords used for hw register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	start *= 1024/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	space *= 1024/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	end = start + space - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	sky2_write32(hw, RB_ADDR(q, RB_START), start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	sky2_write32(hw, RB_ADDR(q, RB_END), end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	sky2_write32(hw, RB_ADDR(q, RB_WP), start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	sky2_write32(hw, RB_ADDR(q, RB_RP), start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	if (q == Q_R1 || q == Q_R2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		u32 tp = space - space/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		/* On receive queue's set the thresholds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		 * give receiver priority when > 3/4 full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		 * send pause when down to 2K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		tp = space - 8192/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		/* Enable store & forward on Tx queue's because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		 * Tx FIFO is only 1K on Yukon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	sky2_read8(hw, RB_ADDR(q, RB_CTRL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /* Setup Bus Memory Interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static void sky2_qset(struct sky2_hw *hw, u16 q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	sky2_write32(hw, Q_ADDR(q, Q_WM),  BMU_WM_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* Setup prefetch unit registers. This is the interface between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)  * hardware and driver list elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 			       dma_addr_t addr, u32 last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), upper_32_bits(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), lower_32_bits(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	struct sky2_tx_le *le = sky2->tx_le + *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	*slot = RING_NEXT(*slot, sky2->tx_ring_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	le->ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	return le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void tx_init(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	struct sky2_tx_le *le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	sky2->tx_prod = sky2->tx_cons = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	sky2->tx_tcpsum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	sky2->tx_last_mss = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	netdev_reset_queue(sky2->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	le = get_tx_le(sky2, &sky2->tx_prod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	le->addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	le->opcode = OP_ADDR64 | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	sky2->tx_last_upper = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* Update chip's next pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	/* Make sure write' to descriptors are complete before we tell hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	le->ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	return le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static unsigned sky2_get_rx_threshold(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	unsigned size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	/* Space needed for frame data + headers rounded up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	/* Stopping point for hardware truncation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	return (size - 8) / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static unsigned sky2_get_rx_data_size(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	struct rx_ring_info *re;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	unsigned size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	/* Space needed for frame data + headers rounded up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	sky2->rx_nfrags = size >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	/* Compute residue after pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	size -= sky2->rx_nfrags << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	/* Optimize to handle small packets and headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	if (size < copybreak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		size = copybreak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	if (size < ETH_HLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		size = ETH_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* Build description to hardware for one receive segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static void sky2_rx_add(struct sky2_port *sky2, u8 op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 			dma_addr_t map, unsigned len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	struct sky2_rx_le *le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	if (sizeof(dma_addr_t) > sizeof(u32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		le = sky2_next_rx(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		le->addr = cpu_to_le32(upper_32_bits(map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		le->opcode = OP_ADDR64 | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	le = sky2_next_rx(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	le->addr = cpu_to_le32(lower_32_bits(map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	le->length = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	le->opcode = op | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* Build description to hardware for one possibly fragmented skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static void sky2_rx_submit(struct sky2_port *sky2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 			   const struct rx_ring_info *re)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	for (i = 0; i < skb_shinfo(re->skb)->nr_frags; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 			    unsigned size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	struct sk_buff *skb = re->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	re->data_addr = dma_map_single(&pdev->dev, skb->data, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 				       DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	if (dma_mapping_error(&pdev->dev, re->data_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		goto mapping_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	dma_unmap_len_set(re, data_size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		re->frag_addr[i] = skb_frag_dma_map(&pdev->dev, frag, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 						    skb_frag_size(frag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 						    DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		if (dma_mapping_error(&pdev->dev, re->frag_addr[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 			goto map_page_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) map_page_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		dma_unmap_page(&pdev->dev, re->frag_addr[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			       skb_frag_size(&skb_shinfo(skb)->frags[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			       DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	dma_unmap_single(&pdev->dev, re->data_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			 dma_unmap_len(re, data_size), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) mapping_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		dev_warn(&pdev->dev, "%s: rx mapping error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 			 skb->dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	struct sk_buff *skb = re->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	dma_unmap_single(&pdev->dev, re->data_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 			 dma_unmap_len(re, data_size), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		dma_unmap_page(&pdev->dev, re->frag_addr[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			       skb_frag_size(&skb_shinfo(skb)->frags[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 			       DMA_FROM_DEVICE);
^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) /* Tell chip where to start receive checksum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)  * Actually has two checksums, but set both same to avoid possible byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)  * order problems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static void rx_set_checksum(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	struct sky2_rx_le *le = sky2_next_rx(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	le->ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	le->opcode = OP_TCPSTART | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	sky2_write32(sky2->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		     Q_ADDR(rxqaddr[sky2->port], Q_CSR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		     (sky2->netdev->features & NETIF_F_RXCSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* Enable/disable receive hash calculation (RSS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) static void rx_set_rss(struct net_device *dev, netdev_features_t features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	int i, nkeys = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	/* Supports IPv6 and other modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	if (hw->flags & SKY2_HW_NEW_LE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		nkeys = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		sky2_write32(hw, SK_REG(sky2->port, RSS_CFG), HASH_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	/* Program RSS initial values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	if (features & NETIF_F_RXHASH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		u32 rss_key[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		netdev_rss_key_fill(rss_key, sizeof(rss_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		for (i = 0; i < nkeys; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 			sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 				     rss_key[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		/* Need to turn on (undocumented) flag to make hashing work  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 			     RX_STFW_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 			     BMU_ENA_RX_RSS_HASH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 			     BMU_DIS_RX_RSS_HASH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)  * The RX Stop command will not work for Yukon-2 if the BMU does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)  * reach the end of packet and since we can't make sure that we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)  * incoming data, we must reset the BMU while it is not doing a DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)  * transfer. Since it is possible that the RX path is still active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)  * the RX RAM buffer will be stopped first, so any possible incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)  * data will not trigger a DMA. After the RAM buffer is stopped, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)  * BMU is polled until any DMA in progress is ended and only then it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)  * will be reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static void sky2_rx_stop(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	unsigned rxq = rxqaddr[sky2->port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	/* disable the RAM Buffer receive queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	for (i = 0; i < 0xffff; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		    == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 			goto stopped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	netdev_warn(sky2->netdev, "receiver stop failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) stopped:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	/* reset the Rx prefetch unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
^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) /* Clean out receive buffer area, assumes receiver hardware stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) static void sky2_rx_clean(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	if (sky2->rx_le)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		memset(sky2->rx_le, 0, RX_LE_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	for (i = 0; i < sky2->rx_pending; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		struct rx_ring_info *re = sky2->rx_ring + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		if (re->skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 			sky2_rx_unmap_skb(sky2->hw->pdev, re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 			kfree_skb(re->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 			re->skb = NULL;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /* Basic MII support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	struct mii_ioctl_data *data = if_mii(ifr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	int err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		return -ENODEV;	/* Phy still in reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	case SIOCGMIIPHY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		data->phy_id = PHY_ADDR_MARV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	case SIOCGMIIREG: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		u16 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		spin_lock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		spin_unlock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		data->val_out = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	case SIOCSMIIREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		spin_lock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 				   data->val_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		spin_unlock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) #define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static void sky2_vlan_mode(struct net_device *dev, netdev_features_t features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	u16 port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	if (features & NETIF_F_HW_VLAN_CTAG_RX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 			     RX_VLAN_STRIP_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 			     RX_VLAN_STRIP_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	if (features & NETIF_F_HW_VLAN_CTAG_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 			     TX_VLAN_TAG_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 		dev->vlan_features |= SKY2_VLAN_OFFLOADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 			     TX_VLAN_TAG_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		/* Can't do transmit offload of vlan without hw vlan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 		dev->vlan_features &= ~SKY2_VLAN_OFFLOADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	}
^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) /* Amount of required worst case padding in rx buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) static inline unsigned sky2_rx_pad(const struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	return (hw->flags & SKY2_HW_RAM_BUFFER) ? 8 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)  * Allocate an skb for receiving. If the MTU is large enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)  * make the skb non-linear with a fragment list of pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	skb = __netdev_alloc_skb(sky2->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 				 sky2->rx_data_size + sky2_rx_pad(sky2->hw),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 				 gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 		goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	if (sky2->hw->flags & SKY2_HW_RAM_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		unsigned char *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		 * Workaround for a bug in FIFO that cause hang
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		 * if the FIFO if the receive buffer is not 64 byte aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 		 * The buffer returned from netdev_alloc_skb is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		 * aligned except if slab debugging is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		start = PTR_ALIGN(skb->data, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		skb_reserve(skb, start - skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		skb_reserve(skb, NET_IP_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	for (i = 0; i < sky2->rx_nfrags; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		struct page *page = alloc_page(gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 			goto free_partial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) free_partial:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) static int sky2_alloc_rx_skbs(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	sky2->rx_data_size = sky2_get_rx_data_size(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	/* Fill Rx ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	for (i = 0; i < sky2->rx_pending; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		struct rx_ring_info *re = sky2->rx_ring + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		re->skb = sky2_rx_alloc(sky2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		if (!re->skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 		if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 			dev_kfree_skb(re->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 			re->skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)  * Setup receiver buffer pool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)  * Normal case this ends up creating one list element for skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)  * in the receive ring. Worst case if using large MTU and each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)  * allocation falls on a different 64 bit region, that results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)  * in 6 list elements per ring entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)  * One element is used for checksum enable/disable, and one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)  * extra to avoid wrap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) static void sky2_rx_start(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	struct rx_ring_info *re;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	unsigned rxq = rxqaddr[sky2->port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	unsigned i, thresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	sky2->rx_put = sky2->rx_next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	sky2_qset(hw, rxq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	/* On PCI express lowering the watermark gives better performance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	if (pci_is_pcie(hw->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 		sky2_write32(hw, Q_ADDR(rxq, Q_WM), BMU_WM_PEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	/* These chips have no ram buffer?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	 * MAC Rx RAM Read is controlled by hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	    hw->chip_rev > CHIP_REV_YU_EC_U_A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	if (!(hw->flags & SKY2_HW_NEW_LE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		rx_set_checksum(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		rx_set_rss(sky2->netdev, sky2->netdev->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	/* submit Rx ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	for (i = 0; i < sky2->rx_pending; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		re = sky2->rx_ring + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		sky2_rx_submit(sky2, re);
^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) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	 * The receiver hangs if it receives frames larger than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	 * packet buffer. As a workaround, truncate oversize frames, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	 * the register is limited to 9 bits, so if you do frames > 2052
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	 * you better get the MTU right!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	thresh = sky2_get_rx_threshold(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	if (thresh > 0x1ff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 		sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	/* Tell chip about available buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	sky2_rx_update(sky2, rxq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	if (hw->chip_id == CHIP_ID_YUKON_EX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	    hw->chip_id == CHIP_ID_YUKON_SUPR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		 * Disable flushing of non ASF packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		 * must be done after initializing the BMUs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		 * drivers without ASF support should do this too, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		 * it may happen that they cannot run on ASF devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		 * remember that the MAC FIFO isn't reset during initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_MACSEC_FLUSH_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	if (hw->chip_id >= CHIP_ID_YUKON_SUPR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		/* Enable RX Home Address & Routing Header checksum fix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		sky2_write16(hw, SK_REG(sky2->port, RX_GMF_FL_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 			     RX_IPV6_SA_MOB_ENA | RX_IPV6_DA_MOB_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		/* Enable TX Home Address & Routing Header checksum fix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		sky2_write32(hw, Q_ADDR(txqaddr[sky2->port], Q_TEST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 			     TBMU_TEST_HOME_ADD_FIX_EN | TBMU_TEST_ROUTING_ADD_FIX_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) static int sky2_alloc_buffers(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	/* must be power of 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	sky2->tx_le = dma_alloc_coherent(&hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 					 sky2->tx_ring_size * sizeof(struct sky2_tx_le),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 					 &sky2->tx_le_map, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	if (!sky2->tx_le)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	if (!sky2->tx_ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	sky2->rx_le = dma_alloc_coherent(&hw->pdev->dev, RX_LE_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 					 &sky2->rx_le_map, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	if (!sky2->rx_le)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	if (!sky2->rx_ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 		goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	return sky2_alloc_rx_skbs(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) static void sky2_free_buffers(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	sky2_rx_clean(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	if (sky2->rx_le) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		dma_free_coherent(&hw->pdev->dev, RX_LE_BYTES, sky2->rx_le,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 				  sky2->rx_le_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		sky2->rx_le = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	if (sky2->tx_le) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		dma_free_coherent(&hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 				  sky2->tx_ring_size * sizeof(struct sky2_tx_le),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 				  sky2->tx_le, sky2->tx_le_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		sky2->tx_le = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	kfree(sky2->tx_ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	kfree(sky2->rx_ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	sky2->tx_ring = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	sky2->rx_ring = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static void sky2_hw_up(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	u32 ramsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	int cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	struct net_device *otherdev = hw->dev[sky2->port^1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	tx_init(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)  	 * On dual port PCI-X card, there is an problem where status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	 * can be received out of order due to split transactions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	if (otherdev && netif_running(otherdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)  	    (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)  		u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)  		cmd &= ~PCI_X_CMD_MAX_SPLIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)  		sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	sky2_mac_init(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	/* Register is number of 4K blocks on internal RAM buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	ramsize = sky2_read8(hw, B2_E_0) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	if (ramsize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 		u32 rxspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 		netdev_dbg(sky2->netdev, "ram buffer %dK\n", ramsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		if (ramsize < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 			rxspace = ramsize / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 			rxspace = 8 + (2*(ramsize - 16))/3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		sky2_ramset(hw, rxqaddr[port], 0, rxspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		/* Make sure SyncQ is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 			    RB_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	sky2_qset(hw, txqaddr[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	/* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	/* Set almost empty threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	    hw->chip_rev == CHIP_REV_YU_EC_U_A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 			   sky2->tx_ring_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	sky2_vlan_mode(sky2->netdev, sky2->netdev->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	netdev_update_features(sky2->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	sky2_rx_start(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) /* Setup device IRQ and enable napi to process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	struct pci_dev *pdev = hw->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	err = request_irq(pdev->irq, sky2_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 			  (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			  name, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 		hw->flags |= SKY2_HW_IRQ_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		napi_enable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) /* Bring up network interface. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) static int sky2_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	u32 imask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	err = sky2_alloc_buffers(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	/* With single port, IRQ is setup when device is brought up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	if (hw->ports == 1 && (err = sky2_setup_irq(hw, dev->name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	sky2_hw_up(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	/* Enable interrupts from phy/mac for port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	imask = sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	if (hw->chip_id == CHIP_ID_YUKON_OPT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	    hw->chip_id == CHIP_ID_YUKON_PRM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	    hw->chip_id == CHIP_ID_YUKON_OP_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 		imask |= Y2_IS_PHY_QLNK;	/* enable PHY Quick Link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	imask |= portirq_msk[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	sky2_write32(hw, B0_IMSK, imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	netif_info(sky2, ifup, dev, "enabling interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	sky2_free_buffers(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) /* Modular subtraction in ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) static inline int tx_inuse(const struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	return (sky2->tx_prod - sky2->tx_cons) & (sky2->tx_ring_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) /* Number of list elements available for next tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) static inline int tx_avail(const struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	return sky2->tx_pending - tx_inuse(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) /* Estimate of number of transmit list elements required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) static unsigned tx_le_req(const struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	unsigned count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	count = (skb_shinfo(skb)->nr_frags + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 		* (sizeof(dma_addr_t) / sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	if (skb_is_gso(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 		++count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	else if (sizeof(dma_addr_t) == sizeof(u32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 		++count;	/* possible vlan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	if (skb->ip_summed == CHECKSUM_PARTIAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 		++count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	if (re->flags & TX_MAP_SINGLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		dma_unmap_single(&pdev->dev, dma_unmap_addr(re, mapaddr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 				 dma_unmap_len(re, maplen), DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	else if (re->flags & TX_MAP_PAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 		dma_unmap_page(&pdev->dev, dma_unmap_addr(re, mapaddr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 			       dma_unmap_len(re, maplen), DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	re->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)  * Put one packet in ring for transmit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)  * A single packet can generate multiple list elements, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)  * the number of ring elements will probably be less than the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)  * of list elements used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 				   struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	struct sky2_tx_le *le = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	struct tx_ring_info *re;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	unsigned i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	dma_addr_t mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	u32 upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	u16 slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	u16 mss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	u8 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)  	if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)   		return NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	len = skb_headlen(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	mapping = dma_map_single(&hw->pdev->dev, skb->data, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 				 DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	if (dma_mapping_error(&hw->pdev->dev, mapping))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		goto mapping_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	slot = sky2->tx_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	netif_printk(sky2, tx_queued, KERN_DEBUG, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		     "tx queued, slot %u, len %d\n", slot, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	/* Send high bits if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	upper = upper_32_bits(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	if (upper != sky2->tx_last_upper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 		le = get_tx_le(sky2, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		le->addr = cpu_to_le32(upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 		sky2->tx_last_upper = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 		le->opcode = OP_ADDR64 | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	/* Check for TCP Segmentation Offload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	mss = skb_shinfo(skb)->gso_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	if (mss != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		if (!(hw->flags & SKY2_HW_NEW_LE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 			mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)   		if (mss != sky2->tx_last_mss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 			le = get_tx_le(sky2, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)   			le->addr = cpu_to_le32(mss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 			if (hw->flags & SKY2_HW_NEW_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 				le->opcode = OP_MSS | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 				le->opcode = OP_LRGLEN | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 			sky2->tx_last_mss = mss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	if (skb_vlan_tag_present(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 		if (!le) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 			le = get_tx_le(sky2, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 			le->addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 			le->opcode = OP_VLAN|HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 			le->opcode |= OP_VLAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 		le->length = cpu_to_be16(skb_vlan_tag_get(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 		ctrl |= INS_VLAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	/* Handle TCP checksum offload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		/* On Yukon EX (some versions) encoding change. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)  		if (hw->flags & SKY2_HW_AUTO_TX_SUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)  			ctrl |= CALSUM;	/* auto checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 			const unsigned offset = skb_transport_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 			u32 tcpsum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 			tcpsum = offset << 16;			/* sum start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 			tcpsum |= offset + skb->csum_offset;	/* sum write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 			ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 			if (ip_hdr(skb)->protocol == IPPROTO_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 				ctrl |= UDPTCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			if (tcpsum != sky2->tx_tcpsum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 				sky2->tx_tcpsum = tcpsum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 				le = get_tx_le(sky2, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 				le->addr = cpu_to_le32(tcpsum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 				le->length = 0;	/* initial checksum value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 				le->ctrl = 1;	/* one packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 				le->opcode = OP_TCPLISW | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	re = sky2->tx_ring + slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	re->flags = TX_MAP_SINGLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	dma_unmap_addr_set(re, mapaddr, mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	dma_unmap_len_set(re, maplen, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	le = get_tx_le(sky2, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	le->addr = cpu_to_le32(lower_32_bits(mapping));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	le->length = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	le->ctrl = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 		mapping = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 					   skb_frag_size(frag), DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		if (dma_mapping_error(&hw->pdev->dev, mapping))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 			goto mapping_unwind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 		upper = upper_32_bits(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		if (upper != sky2->tx_last_upper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 			le = get_tx_le(sky2, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 			le->addr = cpu_to_le32(upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 			sky2->tx_last_upper = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 			le->opcode = OP_ADDR64 | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 		re = sky2->tx_ring + slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 		re->flags = TX_MAP_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 		dma_unmap_addr_set(re, mapaddr, mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 		dma_unmap_len_set(re, maplen, skb_frag_size(frag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 		le = get_tx_le(sky2, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 		le->addr = cpu_to_le32(lower_32_bits(mapping));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		le->length = cpu_to_le16(skb_frag_size(frag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 		le->ctrl = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 		le->opcode = OP_BUFFER | HW_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	re->skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	le->ctrl |= EOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	sky2->tx_prod = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	if (tx_avail(sky2) <= MAX_SKB_TX_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	netdev_sent_queue(dev, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) mapping_unwind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	for (i = sky2->tx_prod; i != slot; i = RING_NEXT(i, sky2->tx_ring_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 		re = sky2->tx_ring + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 		sky2_tx_unmap(hw->pdev, re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) mapping_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)  * Free ring elements from starting at tx_cons until "done"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)  * NB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)  *  1. The hardware will tell us about partial completion of multi-part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)  *     buffers so make sure not to free skb to early.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)  *  2. This may run in parallel start_xmit because the it only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)  *     looks at the tail of the queue of FIFO (tx_cons), not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)  *     the head (tx_prod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	struct net_device *dev = sky2->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	u16 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	unsigned int bytes_compl = 0, pkts_compl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	BUG_ON(done >= sky2->tx_ring_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	for (idx = sky2->tx_cons; idx != done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	     idx = RING_NEXT(idx, sky2->tx_ring_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 		struct tx_ring_info *re = sky2->tx_ring + idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 		struct sk_buff *skb = re->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 		sky2_tx_unmap(sky2->hw->pdev, re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 			netif_printk(sky2, tx_done, KERN_DEBUG, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 				     "tx done %u\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 			pkts_compl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 			bytes_compl += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 			re->skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 			dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 			sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	sky2->tx_cons = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	smp_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	netdev_completed_queue(dev, pkts_compl, bytes_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	u64_stats_update_begin(&sky2->tx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	sky2->tx_stats.packets += pkts_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	sky2->tx_stats.bytes += bytes_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	u64_stats_update_end(&sky2->tx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	/* Disable Force Sync bit and Enable Alloc bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	sky2_write8(hw, SK_REG(port, TXA_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 	sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	/* Reset the PCI FIFO of the async Tx queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 		     BMU_RST_SET | BMU_FIFO_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	/* Reset the Tx prefetch units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 		     PREF_UNIT_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	sky2_read32(hw, B0_CTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) static void sky2_hw_down(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	u16 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	/* Force flow control off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	/* Stop transmitter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 		     RB_RST_SET | RB_DIS_OP_MD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	ctrl = gma_read16(hw, port, GM_GP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	gma_write16(hw, port, GM_GP_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	/* Workaround shared GMAC reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	      port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	/* Force any delayed status interrupt and NAPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	sky2_write32(hw, STAT_LEV_TIMER_CNT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	sky2_write32(hw, STAT_TX_TIMER_CNT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	sky2_write32(hw, STAT_ISR_TIMER_CNT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	sky2_read8(hw, STAT_ISR_TIMER_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	sky2_rx_stop(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	spin_lock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	sky2_phy_power_down(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	spin_unlock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	sky2_tx_reset(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	/* Free any pending frames stuck in HW queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	sky2_tx_complete(sky2, sky2->tx_prod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /* Network shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) static int sky2_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 	/* Never really got started! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	if (!sky2->tx_le)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	netif_info(sky2, ifdown, dev, "disabling interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	if (hw->ports == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 		sky2_write32(hw, B0_IMSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 		napi_disable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 		free_irq(hw->pdev->irq, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 		hw->flags &= ~SKY2_HW_IRQ_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 		u32 imask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 		/* Disable port IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 		imask  = sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 		imask &= ~portirq_msk[sky2->port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 		sky2_write32(hw, B0_IMSK, imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		synchronize_irq(hw->pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		napi_synchronize(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	sky2_hw_down(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	sky2_free_buffers(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	if (hw->flags & SKY2_HW_FIBRE_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		return SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 	if (!(hw->flags & SKY2_HW_GIGABIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		if (aux & PHY_M_PS_SPEED_100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 			return SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 			return SPEED_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	switch (aux & PHY_M_PS_SPEED_MSK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	case PHY_M_PS_SPEED_1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		return SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	case PHY_M_PS_SPEED_100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 		return SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 		return SPEED_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) static void sky2_link_up(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	static const char *fc_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 		[FC_NONE]	= "none",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 		[FC_TX]		= "tx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 		[FC_RX]		= "rx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 		[FC_BOTH]	= "both",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	sky2_set_ipg(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	sky2_enable_rx_tx(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	netif_carrier_on(sky2->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	mod_timer(&hw->watchdog_timer, jiffies + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	/* Turn on link LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	sky2_write8(hw, SK_REG(port, LNK_LED_REG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 		    LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	netif_info(sky2, link, sky2->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 		   "Link is up at %d Mbps, %s duplex, flow control %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 		   sky2->speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 		   sky2->duplex == DUPLEX_FULL ? "full" : "half",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 		   fc_name[sky2->flow_status]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) static void sky2_link_down(struct sky2_port *sky2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	reg = gma_read16(hw, port, GM_GP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	gma_write16(hw, port, GM_GP_CTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	netif_carrier_off(sky2->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	/* Turn off link LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	netif_info(sky2, link, sky2->netdev, "Link is down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	sky2_phy_init(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static enum flow_control sky2_flow(int rx, int tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	if (rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 		return tx ? FC_BOTH : FC_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		return tx ? FC_TX : FC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	u16 advert, lpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	if (lpa & PHY_M_AN_RF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 		netdev_err(sky2->netdev, "remote fault\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	if (!(aux & PHY_M_PS_SPDUP_RES)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 		netdev_err(sky2->netdev, "speed/duplex mismatch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	sky2->speed = sky2_phy_speed(hw, aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	/* Since the pause result bits seem to in different positions on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	 * different chips. look at registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	if (hw->flags & SKY2_HW_FIBRE_PHY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 		/* Shift for bits in fiber PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 		lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		if (advert & ADVERTISE_1000XPAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 			advert |= ADVERTISE_PAUSE_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 		if (advert & ADVERTISE_1000XPSE_ASYM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 			advert |= ADVERTISE_PAUSE_ASYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 		if (lpa & LPA_1000XPAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 			lpa |= LPA_PAUSE_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 		if (lpa & LPA_1000XPAUSE_ASYM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 			lpa |= LPA_PAUSE_ASYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	sky2->flow_status = FC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	if (advert & ADVERTISE_PAUSE_CAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		if (lpa & LPA_PAUSE_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 			sky2->flow_status = FC_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 		else if (advert & ADVERTISE_PAUSE_ASYM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 			sky2->flow_status = FC_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	} else if (advert & ADVERTISE_PAUSE_ASYM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		if ((lpa & LPA_PAUSE_CAP) && (lpa & LPA_PAUSE_ASYM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 			sky2->flow_status = FC_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	    !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 		sky2->flow_status = FC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	if (sky2->flow_status & FC_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) /* Interrupt from PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	struct net_device *dev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	u16 istatus, phystat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	spin_lock(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	netif_info(sky2, intr, sky2->netdev, "phy interrupt status 0x%x 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 		   istatus, phystat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	if (istatus & PHY_M_IS_AN_COMPL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		if (sky2_autoneg_done(sky2, phystat) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		    !netif_carrier_ok(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 			sky2_link_up(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	if (istatus & PHY_M_IS_LSP_CHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 		sky2->speed = sky2_phy_speed(hw, phystat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	if (istatus & PHY_M_IS_DUP_CHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 		sky2->duplex =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 		    (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 	if (istatus & PHY_M_IS_LST_CHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 		if (phystat & PHY_M_PS_LINK_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 			sky2_link_up(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			sky2_link_down(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	spin_unlock(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) /* Special quick link interrupt (Yukon-2 Optima only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) static void sky2_qlink_intr(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	struct sky2_port *sky2 = netdev_priv(hw->dev[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	u32 imask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	u16 phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	/* disable irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	imask = sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	imask &= ~Y2_IS_PHY_QLNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	sky2_write32(hw, B0_IMSK, imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	/* reset PHY Link Detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	phy = sky2_pci_read16(hw, PSM_CONFIG_REG4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	sky2_pci_write16(hw, PSM_CONFIG_REG4, phy | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	sky2_link_up(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) /* Transmit timeout is only called if we are running, carrier is up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)  * and tx queue is full (stopped).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) static void sky2_tx_timeout(struct net_device *dev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	netif_err(sky2, timer, dev, "tx timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	netdev_printk(KERN_DEBUG, dev, "transmit ring %u .. %u report=%u done=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		      sky2->tx_cons, sky2->tx_prod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		      sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		      sky2_read16(hw, Q_ADDR(txqaddr[sky2->port], Q_DONE)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	/* can't restart safely under softirq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	schedule_work(&hw->restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) static int sky2_change_mtu(struct net_device *dev, int new_mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	u16 ctl, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	u32 imask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	if (!netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		dev->mtu = new_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 		netdev_update_features(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	imask = sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	sky2_write32(hw, B0_IMSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	netif_trans_update(dev);	/* prevent tx timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	napi_disable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	netif_tx_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	synchronize_irq(hw->pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	if (!(hw->flags & SKY2_HW_RAM_BUFFER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 		sky2_set_tx_stfwd(hw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	ctl = gma_read16(hw, port, GM_GP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	sky2_rx_stop(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	sky2_rx_clean(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	dev->mtu = new_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	netdev_update_features(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |	GM_SMOD_VLAN_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	if (sky2->speed > SPEED_100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		mode |= IPG_DATA_VAL(IPG_DATA_DEF_1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		mode |= IPG_DATA_VAL(IPG_DATA_DEF_10_100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	if (dev->mtu > ETH_DATA_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 		mode |= GM_SMOD_JUMBO_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	gma_write16(hw, port, GM_SERIAL_MODE, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	err = sky2_alloc_rx_skbs(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		sky2_rx_start(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		sky2_rx_clean(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	sky2_write32(hw, B0_IMSK, imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	sky2_read32(hw, B0_Y2_SP_LISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	napi_enable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 		dev_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		gma_write16(hw, port, GM_GP_CTRL, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 		netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) static inline bool needs_copy(const struct rx_ring_info *re,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 			      unsigned length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	/* Some architectures need the IP header to be aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	if (!IS_ALIGNED(re->data_addr + ETH_HLEN, sizeof(u32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	return length < copybreak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) /* For small just reuse existing skb for next receive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) static struct sk_buff *receive_copy(struct sky2_port *sky2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 				    const struct rx_ring_info *re,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 				    unsigned length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	skb = netdev_alloc_skb_ip_align(sky2->netdev, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	if (likely(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		dma_sync_single_for_cpu(&sky2->hw->pdev->dev, re->data_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 					length, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 		skb_copy_from_linear_data(re->skb, skb->data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		skb->ip_summed = re->skb->ip_summed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 		skb->csum = re->skb->csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		skb_copy_hash(skb, re->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 		__vlan_hwaccel_copy_tag(skb, re->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		dma_sync_single_for_device(&sky2->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 					   re->data_addr, length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 					   DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 		__vlan_hwaccel_clear_tag(re->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 		skb_clear_hash(re->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 		re->skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 		skb_put(skb, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) /* Adjust length of skb with fragments to match received data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 			  unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	int i, num_frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	/* put header into skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	size = min(length, hdr_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	skb->tail += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	skb->len += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	length -= size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	num_frags = skb_shinfo(skb)->nr_frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	for (i = 0; i < num_frags; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		if (length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 			/* don't need this page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 			__skb_frag_unref(frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 			--skb_shinfo(skb)->nr_frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 			size = min(length, (unsigned) PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 			skb_frag_size_set(frag, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 			skb->data_len += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 			skb->truesize += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 			skb->len += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 			length -= size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) /* Normal packet - take skb from ring element and put in a new one  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) static struct sk_buff *receive_new(struct sky2_port *sky2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 				   struct rx_ring_info *re,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 				   unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	struct rx_ring_info nre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	unsigned hdr_space = sky2->rx_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	nre.skb = sky2_rx_alloc(sky2, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	if (unlikely(!nre.skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		goto nobuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	if (sky2_rx_map_skb(sky2->hw->pdev, &nre, hdr_space))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 		goto nomap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	skb = re->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	sky2_rx_unmap_skb(sky2->hw->pdev, re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	prefetch(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	*re = nre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	if (skb_shinfo(skb)->nr_frags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 		skb_put_frags(skb, hdr_space, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 		skb_put(skb, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) nomap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	dev_kfree_skb(nre.skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) nobuf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)  * Receive one packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553)  * For larger packets, get new buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) static struct sk_buff *sky2_receive(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 				    u16 length, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)  	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	u16 count = (status & GMR_FS_LEN) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	netif_printk(sky2, rx_status, KERN_DEBUG, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 		     "rx slot %u status 0x%x len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		     sky2->rx_next, status, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 	prefetch(sky2->rx_ring + sky2->rx_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	if (skb_vlan_tag_present(re->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 		count -= VLAN_HLEN;	/* Account for vlan tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	/* This chip has hardware problems that generates bogus status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	 * So do only marginal checking and expect higher level protocols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	 * to handle crap frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 	    sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	    length != count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 		goto okay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	if (status & GMR_FS_ANY_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	if (!(status & GMR_FS_RX_OK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 		goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	/* if length reported by DMA does not match PHY, packet was truncated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	if (length != count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) okay:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	if (needs_copy(re, length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 		skb = receive_copy(sky2, re, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		skb = receive_new(sky2, re, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	dev->stats.rx_dropped += (skb == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) resubmit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	sky2_rx_submit(sky2, re);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	++dev->stats.rx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		netif_info(sky2, rx_err, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			   "rx error, status 0x%x length %d\n", status, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) /* Transmit complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) static inline void sky2_tx_done(struct net_device *dev, u16 last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	if (netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 		sky2_tx_complete(sky2, last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 		/* Wake unless it's detached, and called e.g. from sky2_close() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 		if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 			netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) static inline void sky2_skb_rx(const struct sky2_port *sky2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 			       struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	if (skb->ip_summed == CHECKSUM_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 		netif_receive_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 		napi_gro_receive(&sky2->hw->napi, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 				unsigned packets, unsigned bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	struct net_device *dev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	if (packets == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	u64_stats_update_begin(&sky2->rx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	sky2->rx_stats.packets += packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	sky2->rx_stats.bytes += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	u64_stats_update_end(&sky2->rx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	sky2->last_rx = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	sky2_rx_update(netdev_priv(dev), rxqaddr[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	/* If this happens then driver assuming wrong format for chip type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	BUG_ON(sky2->hw->flags & SKY2_HW_NEW_LE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	/* Both checksum counters are programmed to start at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 	 * the same offset, so unless there is a problem they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 	 * should match. This failure is an early indication that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	 * hardware receive checksumming won't work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	if (likely((u16)(status >> 16) == (u16)status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 		struct sk_buff *skb = sky2->rx_ring[sky2->rx_next].skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		skb->ip_summed = CHECKSUM_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		skb->csum = le16_to_cpu(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		dev_notice(&sky2->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 			   "%s: receive checksum problem (status = %#x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 			   sky2->netdev->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		/* Disable checksum offload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 		 * It will be reenabled on next ndo_set_features, but if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		 * really broken, will get disabled again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 		sky2->netdev->features &= ~NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 		sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 			     BMU_DIS_RX_CHKSUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) static void sky2_rx_tag(struct sky2_port *sky2, u16 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	skb = sky2->rx_ring[sky2->rx_next].skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), be16_to_cpu(length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	skb = sky2->rx_ring[sky2->rx_next].skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 	skb_set_hash(skb, le32_to_cpu(status), PKT_HASH_TYPE_L3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) /* Process status response ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	int work_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	unsigned int total_bytes[2] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	unsigned int total_packets[2] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	if (to_do <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		return work_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 		struct sky2_port *sky2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 		struct sky2_status_le *le  = hw->st_le + hw->st_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 		unsigned port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 		struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 		u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 		u16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 		u8 opcode = le->opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		if (!(opcode & HW_OWNER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		hw->st_idx = RING_NEXT(hw->st_idx, hw->st_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 		port = le->css & CSS_LINK_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 		dev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 		sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 		length = le16_to_cpu(le->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 		status = le32_to_cpu(le->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 		le->opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 		switch (opcode & ~HW_OWNER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 		case OP_RXSTAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 			total_packets[port]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 			total_bytes[port] += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 			skb = sky2_receive(dev, length, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 			if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 			/* This chip reports checksum status differently */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 			if (hw->flags & SKY2_HW_NEW_LE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 				if ((dev->features & NETIF_F_RXCSUM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 				    (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 				    (le->css & CSS_TCPUDPCSOK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 					skb->ip_summed = CHECKSUM_UNNECESSARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 					skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 			skb->protocol = eth_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 			sky2_skb_rx(sky2, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 			/* Stop after net poll weight */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 			if (++work_done >= to_do)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 				goto exit_loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 		case OP_RXVLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 			sky2_rx_tag(sky2, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		case OP_RXCHKSVLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 			sky2_rx_tag(sky2, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 		case OP_RXCHKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 			if (likely(dev->features & NETIF_F_RXCSUM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 				sky2_rx_checksum(sky2, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 		case OP_RSS_HASH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 			sky2_rx_hash(sky2, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 		case OP_TXINDEXLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 			/* TX index reports status for both ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 			sky2_tx_done(hw->dev[0], status & 0xfff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			if (hw->dev[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 				sky2_tx_done(hw->dev[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 				     ((status >> 24) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 					     | (u16)(length & 0xf) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 			if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 				pr_warn("unknown status opcode 0x%x\n", opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	} while (hw->st_idx != idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	/* Fully processed status ring so clear irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) exit_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	sky2_rx_done(hw, 0, total_packets[0], total_bytes[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	sky2_rx_done(hw, 1, total_packets[1], total_bytes[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	return work_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	struct net_device *dev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 		netdev_info(dev, "hw error interrupt status 0x%x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	if (status & Y2_IS_PAR_RD1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 		if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 			netdev_err(dev, "ram data read parity error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 		/* Clear IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	if (status & Y2_IS_PAR_WR1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 		if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 			netdev_err(dev, "ram data write parity error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	if (status & Y2_IS_PAR_MAC1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 		if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 			netdev_err(dev, "MAC parity error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 	if (status & Y2_IS_PAR_RX1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 			netdev_err(dev, "RX parity error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 		sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	if (status & Y2_IS_TCP_TXA1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 			netdev_err(dev, "TCP segmentation error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) static void sky2_hw_intr(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	struct pci_dev *pdev = hw->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	u32 status = sky2_read32(hw, B0_HWE_ISRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	status &= hwmsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	if (status & Y2_IS_TIST_OV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 		sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 		u16 pci_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		pci_err = sky2_pci_read16(hw, PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 		if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 			dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 			        pci_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 		sky2_pci_write16(hw, PCI_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 				      pci_err | PCI_STATUS_ERROR_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	if (status & Y2_IS_PCI_EXP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		/* PCI-Express uncorrectable Error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 		u32 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 		sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 			     0xfffffffful);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 		if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 			dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	if (status & Y2_HWE_L1_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 		sky2_hw_error(hw, 0, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	status >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	if (status & Y2_HWE_L1_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 		sky2_hw_error(hw, 1, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	struct net_device *dev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 	netif_info(sky2, intr, dev, "mac interrupt status 0x%x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	if (status & GM_IS_RX_CO_OV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		gma_read16(hw, port, GM_RX_IRQ_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	if (status & GM_IS_TX_CO_OV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		gma_read16(hw, port, GM_TX_IRQ_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	if (status & GM_IS_RX_FF_OR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		++dev->stats.rx_fifo_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 		sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	if (status & GM_IS_TX_FF_UR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 		++dev->stats.tx_fifo_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) /* This should never happen it is a bug. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) static void sky2_le_error(struct sky2_hw *hw, unsigned port, u16 q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 	struct net_device *dev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	u16 idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	dev_err(&hw->pdev->dev, "%s: descriptor error q=%#x get=%u put=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		dev->name, (unsigned) q, (unsigned) idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 		(unsigned) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) static int sky2_rx_hung(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	unsigned rxq = rxqaddr[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	u32 mac_rp = sky2_read32(hw, SK_REG(port, RX_GMF_RP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	u8 mac_lev = sky2_read8(hw, SK_REG(port, RX_GMF_RLEV));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	u8 fifo_rp = sky2_read8(hw, Q_ADDR(rxq, Q_RP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	u8 fifo_lev = sky2_read8(hw, Q_ADDR(rxq, Q_RL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	/* If idle and MAC or PCI is stuck */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	if (sky2->check.last == sky2->last_rx &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	    ((mac_rp == sky2->check.mac_rp &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	      mac_lev != 0 && mac_lev >= sky2->check.mac_lev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	     /* Check if the PCI RX hang */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	     (fifo_rp == sky2->check.fifo_rp &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	      fifo_lev != 0 && fifo_lev >= sky2->check.fifo_lev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 		netdev_printk(KERN_DEBUG, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 			      "hung mac %d:%d fifo %d (%d:%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 			      mac_lev, mac_rp, fifo_lev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 			      fifo_rp, sky2_read8(hw, Q_ADDR(rxq, Q_WP)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 		sky2->check.last = sky2->last_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 		sky2->check.mac_rp = mac_rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 		sky2->check.mac_lev = mac_lev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 		sky2->check.fifo_rp = fifo_rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		sky2->check.fifo_lev = fifo_lev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) static void sky2_watchdog(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	struct sky2_hw *hw = from_timer(hw, t, watchdog_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	/* Check for lost IRQ once a second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	if (sky2_read32(hw, B0_ISRC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 		napi_schedule(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 		int i, active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 		for (i = 0; i < hw->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 			struct net_device *dev = hw->dev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 			if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 			++active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 			/* For chips with Rx FIFO, check if stuck */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 			if ((hw->flags & SKY2_HW_RAM_BUFFER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 			     sky2_rx_hung(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 				netdev_info(dev, "receiver hang detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 				schedule_work(&hw->restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 		if (active == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 	mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) /* Hardware/software error handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) static void sky2_err_intr(struct sky2_hw *hw, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 		dev_warn(&hw->pdev->dev, "error interrupt status=%#x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	if (status & Y2_IS_HW_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 		sky2_hw_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	if (status & Y2_IS_IRQ_MAC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 		sky2_mac_intr(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	if (status & Y2_IS_IRQ_MAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 		sky2_mac_intr(hw, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	if (status & Y2_IS_CHK_RX1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 		sky2_le_error(hw, 0, Q_R1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	if (status & Y2_IS_CHK_RX2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		sky2_le_error(hw, 1, Q_R2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	if (status & Y2_IS_CHK_TXA1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 		sky2_le_error(hw, 0, Q_XA1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	if (status & Y2_IS_CHK_TXA2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 		sky2_le_error(hw, 1, Q_XA2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) static int sky2_poll(struct napi_struct *napi, int work_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	struct sky2_hw *hw = container_of(napi, struct sky2_hw, napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	int work_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 	u16 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	if (unlikely(status & Y2_IS_ERROR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 		sky2_err_intr(hw, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	if (status & Y2_IS_IRQ_PHY1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 		sky2_phy_intr(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	if (status & Y2_IS_IRQ_PHY2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 		sky2_phy_intr(hw, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 	if (status & Y2_IS_PHY_QLNK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 		sky2_qlink_intr(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 	while ((idx = sky2_read16(hw, STAT_PUT_IDX)) != hw->st_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 		work_done += sky2_status_intr(hw, work_limit - work_done, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 		if (work_done >= work_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 	napi_complete_done(napi, work_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	sky2_read32(hw, B0_Y2_SP_LISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	return work_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) static irqreturn_t sky2_intr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 	struct sky2_hw *hw = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	/* Reading this mask interrupts as side effect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	status = sky2_read32(hw, B0_Y2_SP_ISRC2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 	if (status == 0 || status == ~0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 		sky2_write32(hw, B0_Y2_SP_ICR, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 	prefetch(&hw->st_le[hw->st_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 	napi_schedule(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) static void sky2_netpoll(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	napi_schedule(&sky2->hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) /* Chip internal frequency for clock calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) static u32 sky2_mhz(const struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	switch (hw->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 	case CHIP_ID_YUKON_EC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 	case CHIP_ID_YUKON_EC_U:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	case CHIP_ID_YUKON_EX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	case CHIP_ID_YUKON_SUPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	case CHIP_ID_YUKON_UL_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	case CHIP_ID_YUKON_OPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 	case CHIP_ID_YUKON_PRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 	case CHIP_ID_YUKON_OP_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 		return 125;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	case CHIP_ID_YUKON_FE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 		return 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	case CHIP_ID_YUKON_FE_P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 		return 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	case CHIP_ID_YUKON_XL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		return 156;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	return sky2_mhz(hw) * us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	return clk / sky2_mhz(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) static int sky2_init(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	u8 t8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 	/* Enable all clocks and check for bad PCI access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	sky2_pci_write32(hw, PCI_DEV_REG3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	sky2_write8(hw, B0_CTST, CS_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 	hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	switch (hw->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 	case CHIP_ID_YUKON_XL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 		hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 		if (hw->chip_rev < CHIP_REV_YU_XL_A2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 			hw->flags |= SKY2_HW_RSS_BROKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	case CHIP_ID_YUKON_EC_U:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 		hw->flags = SKY2_HW_GIGABIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 			| SKY2_HW_NEWER_PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 			| SKY2_HW_ADV_POWER_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	case CHIP_ID_YUKON_EX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		hw->flags = SKY2_HW_GIGABIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 			| SKY2_HW_NEWER_PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 			| SKY2_HW_NEW_LE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 			| SKY2_HW_ADV_POWER_CTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 			| SKY2_HW_RSS_CHKSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 		/* New transmit checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		if (hw->chip_rev != CHIP_REV_YU_EX_B0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 			hw->flags |= SKY2_HW_AUTO_TX_SUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	case CHIP_ID_YUKON_EC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		/* This rev is really old, and requires untested workarounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 		if (hw->chip_rev == CHIP_REV_YU_EC_A1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 			dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 		hw->flags = SKY2_HW_GIGABIT | SKY2_HW_RSS_BROKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	case CHIP_ID_YUKON_FE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 		hw->flags = SKY2_HW_RSS_BROKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	case CHIP_ID_YUKON_FE_P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 		hw->flags = SKY2_HW_NEWER_PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 			| SKY2_HW_NEW_LE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 			| SKY2_HW_AUTO_TX_SUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 			| SKY2_HW_ADV_POWER_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 		/* The workaround for status conflicts VLAN tag detection. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 		if (hw->chip_rev == CHIP_REV_YU_FE2_A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 			hw->flags |= SKY2_HW_VLAN_BROKEN | SKY2_HW_RSS_CHKSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 	case CHIP_ID_YUKON_SUPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 		hw->flags = SKY2_HW_GIGABIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 			| SKY2_HW_NEWER_PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 			| SKY2_HW_NEW_LE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 			| SKY2_HW_AUTO_TX_SUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 			| SKY2_HW_ADV_POWER_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 		if (hw->chip_rev == CHIP_REV_YU_SU_A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 			hw->flags |= SKY2_HW_RSS_CHKSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 	case CHIP_ID_YUKON_UL_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 		hw->flags = SKY2_HW_GIGABIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 			| SKY2_HW_ADV_POWER_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 	case CHIP_ID_YUKON_OPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	case CHIP_ID_YUKON_PRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	case CHIP_ID_YUKON_OP_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 		hw->flags = SKY2_HW_GIGABIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 			| SKY2_HW_NEW_LE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 			| SKY2_HW_ADV_POWER_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 			hw->chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 		hw->flags |= SKY2_HW_FIBRE_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	hw->ports = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	t8 = sky2_read8(hw, B2_Y2_HW_RES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 		if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 			++hw->ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	if (sky2_read8(hw, B2_E_0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 		hw->flags |= SKY2_HW_RAM_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) static void sky2_reset(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	struct pci_dev *pdev = hw->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	u32 hwe_mask = Y2_HWE_ALL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	/* disable ASF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	if (hw->chip_id == CHIP_ID_YUKON_EX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	    || hw->chip_id == CHIP_ID_YUKON_SUPR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 		sky2_write32(hw, CPU_WDOG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 		status = sky2_read16(hw, HCU_CCSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 		status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 			    HCU_CCSR_UC_STATE_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 		 * CPU clock divider shouldn't be used because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 		 * - ASF firmware may malfunction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 		 * - Yukon-Supreme: Parallel FLASH doesn't support divided clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 		status &= ~HCU_CCSR_CPU_CLK_DIVIDE_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 		sky2_write16(hw, HCU_CCSR, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 		sky2_write32(hw, CPU_WDOG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 	sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 	/* do a SW reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 	sky2_write8(hw, B0_CTST, CS_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	sky2_write8(hw, B0_CTST, CS_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 	/* allow writes to PCI config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	/* clear PCI errors, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 	status = sky2_pci_read16(hw, PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	status |= PCI_STATUS_ERROR_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 	sky2_pci_write16(hw, PCI_STATUS, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	sky2_write8(hw, B0_CTST, CS_MRST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	if (pci_is_pcie(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 		sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 			     0xfffffffful);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 		/* If error bit is stuck on ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 		if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 			dev_info(&pdev->dev, "ignoring stuck error report bit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 			hwe_mask |= Y2_IS_PCI_EXP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 	sky2_power_on(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 	for (i = 0; i < hw->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 		if (hw->chip_id == CHIP_ID_YUKON_EX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 		    hw->chip_id == CHIP_ID_YUKON_SUPR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 			sky2_write16(hw, SK_REG(i, GMAC_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 				     GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 				     | GMC_BYP_RETR_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 	if (hw->chip_id == CHIP_ID_YUKON_SUPR && hw->chip_rev > CHIP_REV_YU_SU_B0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 		/* enable MACSec clock gating */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 		sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 	if (hw->chip_id == CHIP_ID_YUKON_OPT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 	    hw->chip_id == CHIP_ID_YUKON_PRM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 	    hw->chip_id == CHIP_ID_YUKON_OP_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 			/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 			sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 			/* set PHY Link Detect Timer to 1.1 second (11x 100ms) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 			reg = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 			/* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 			sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 			/* set PHY Link Detect Timer to 0.4 second (4x 100ms) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 			reg = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 		reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 		reg |= PSM_CONFIG_REG4_RST_PHY_LINK_DETECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 		/* reset PHY Link Detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 		sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 		/* check if PSMv2 was running before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 		reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 		if (reg & PCI_EXP_LNKCTL_ASPMC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 			/* restore the PCIe Link Control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 			sky2_pci_write16(hw, pdev->pcie_cap + PCI_EXP_LNKCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 					 reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 		if (hw->chip_id == CHIP_ID_YUKON_PRM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 			hw->chip_rev == CHIP_REV_YU_PRM_A0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 			/* change PHY Interrupt polarity to low active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 			reg = sky2_read16(hw, GPHY_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 			sky2_write16(hw, GPHY_CTRL, reg | GPC_INTPOL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 			/* adapt HW for low active PHY Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 			reg = sky2_read16(hw, Y2_CFG_SPC + PCI_LDO_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 			sky2_write16(hw, Y2_CFG_SPC + PCI_LDO_CTRL, reg | PHY_M_UNDOC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 		/* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 		sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 	/* Clear I2C IRQ noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	sky2_write32(hw, B2_I2C_IRQ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	/* turn off hardware timer (unused) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 	/* Turn off descriptor polling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 	sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	/* Turn off receive timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 	sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	/* enable the Tx Arbiters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 	for (i = 0; i < hw->ports; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 		sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	/* Initialize ram interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	for (i = 0; i < hw->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	sky2_write32(hw, B0_HWE_IMSK, hwe_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 	for (i = 0; i < hw->ports; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 		sky2_gmac_reset(hw, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 	memset(hw->st_le, 0, hw->st_size * sizeof(struct sky2_status_le));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	hw->st_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 	sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 	sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 	sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 	sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 	/* Set the list last index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 	sky2_write16(hw, STAT_LAST_IDX, hw->st_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 	sky2_write16(hw, STAT_TX_IDX_TH, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 	sky2_write8(hw, STAT_FIFO_WM, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 	/* set Status-FIFO ISR watermark */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 		sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 		sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	/* enable status unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 	sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) /* Take device down (offline).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424)  * Equivalent to doing dev_stop() but this does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)  * inform upper layers of the transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) static void sky2_detach(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	if (netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 		netif_tx_lock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 		netif_device_detach(dev);	/* stop txq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 		netif_tx_unlock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 		sky2_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) /* Bring device back after doing sky2_detach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) static int sky2_reattach(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	if (netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		err = sky2_open(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 			netdev_info(dev, "could not restart %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 			dev_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 			netif_device_attach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 			sky2_set_multicast(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) static void sky2_all_down(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 	if (hw->flags & SKY2_HW_IRQ_SETUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 		sky2_write32(hw, B0_IMSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 		sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 		synchronize_irq(hw->pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 		napi_disable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	for (i = 0; i < hw->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 		struct net_device *dev = hw->dev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 		struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 		if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 		netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 		netif_tx_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 		sky2_hw_down(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) static void sky2_all_up(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	u32 imask = Y2_IS_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 	for (i = 0; i < hw->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 		struct net_device *dev = hw->dev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 		struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 		if (!netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 		sky2_hw_up(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 		sky2_set_multicast(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 		imask |= portirq_msk[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 		netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 	if (hw->flags & SKY2_HW_IRQ_SETUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 		sky2_write32(hw, B0_IMSK, imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 		sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 		sky2_read32(hw, B0_Y2_SP_LISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 		napi_enable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) static void sky2_restart(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	sky2_all_down(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	sky2_reset(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	sky2_all_up(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) static inline u8 sky2_wol_supported(const struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 	return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	const struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	wol->supported = sky2_wol_supported(sky2->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	wol->wolopts = sky2->wol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 	bool enable_wakeup = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	    !device_can_wakeup(&hw->pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 	sky2->wol = wol->wolopts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 	for (i = 0; i < hw->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 		struct net_device *dev = hw->dev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 		struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 		if (sky2->wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 			enable_wakeup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	device_set_wakeup_enable(&hw->pdev->dev, enable_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) static u32 sky2_supported_modes(const struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 	if (sky2_is_copper(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 		u32 modes = SUPPORTED_10baseT_Half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 			| SUPPORTED_10baseT_Full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 			| SUPPORTED_100baseT_Half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 			| SUPPORTED_100baseT_Full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 		if (hw->flags & SKY2_HW_GIGABIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 			modes |= SUPPORTED_1000baseT_Half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 				| SUPPORTED_1000baseT_Full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 		return modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 		return SUPPORTED_1000baseT_Half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 			| SUPPORTED_1000baseT_Full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) static int sky2_get_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 				   struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 	u32 supported, advertising;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 	supported = sky2_supported_modes(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	cmd->base.phy_address = PHY_ADDR_MARV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	if (sky2_is_copper(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 		cmd->base.port = PORT_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 		cmd->base.speed = sky2->speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 		supported |=  SUPPORTED_Autoneg | SUPPORTED_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 		cmd->base.speed = SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 		cmd->base.port = PORT_FIBRE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 		supported |=  SUPPORTED_Autoneg | SUPPORTED_FIBRE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	advertising = sky2->advertising;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 	cmd->base.autoneg = (sky2->flags & SKY2_FLAG_AUTO_SPEED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 		? AUTONEG_ENABLE : AUTONEG_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 	cmd->base.duplex = sky2->duplex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 						supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 						advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) static int sky2_set_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 				   const struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	const struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	u32 supported = sky2_supported_modes(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	u32 new_advertising;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	ethtool_convert_link_mode_to_legacy_u32(&new_advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 						cmd->link_modes.advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	if (cmd->base.autoneg == AUTONEG_ENABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 		if (new_advertising & ~supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 		if (sky2_is_copper(hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 			sky2->advertising = new_advertising |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 					    ADVERTISED_TP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 					    ADVERTISED_Autoneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 			sky2->advertising = new_advertising |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 					    ADVERTISED_FIBRE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 					    ADVERTISED_Autoneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 		sky2->flags |= SKY2_FLAG_AUTO_SPEED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 		sky2->duplex = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 		sky2->speed = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 		u32 setting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 		u32 speed = cmd->base.speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 		switch (speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 		case SPEED_1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 			if (cmd->base.duplex == DUPLEX_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 				setting = SUPPORTED_1000baseT_Full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 			else if (cmd->base.duplex == DUPLEX_HALF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 				setting = SUPPORTED_1000baseT_Half;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 		case SPEED_100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 			if (cmd->base.duplex == DUPLEX_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 				setting = SUPPORTED_100baseT_Full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 			else if (cmd->base.duplex == DUPLEX_HALF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 				setting = SUPPORTED_100baseT_Half;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 		case SPEED_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 			if (cmd->base.duplex == DUPLEX_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 				setting = SUPPORTED_10baseT_Full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 			else if (cmd->base.duplex == DUPLEX_HALF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 				setting = SUPPORTED_10baseT_Half;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 		if ((setting & supported) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 		sky2->speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 		sky2->duplex = cmd->base.duplex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 		sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 	if (netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 		sky2_phy_reinit(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 		sky2_set_multicast(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) static void sky2_get_drvinfo(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 			     struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 	strlcpy(info->bus_info, pci_name(sky2->hw->pdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 		sizeof(info->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) static const struct sky2_stat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 	char name[ETH_GSTRING_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 	u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) } sky2_stats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 	{ "tx_bytes",	   GM_TXO_OK_HI },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 	{ "rx_bytes",	   GM_RXO_OK_HI },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 	{ "tx_broadcast",  GM_TXF_BC_OK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 	{ "rx_broadcast",  GM_RXF_BC_OK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 	{ "tx_multicast",  GM_TXF_MC_OK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 	{ "rx_multicast",  GM_RXF_MC_OK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 	{ "tx_unicast",    GM_TXF_UC_OK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 	{ "rx_unicast",    GM_RXF_UC_OK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	{ "tx_mac_pause",  GM_TXF_MPAUSE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 	{ "rx_mac_pause",  GM_RXF_MPAUSE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 	{ "collisions",    GM_TXF_COL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 	{ "late_collision",GM_TXF_LAT_COL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 	{ "aborted", 	   GM_TXF_ABO_COL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	{ "single_collisions", GM_TXF_SNG_COL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 	{ "multi_collisions", GM_TXF_MUL_COL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 	{ "rx_short",      GM_RXF_SHT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	{ "rx_runt", 	   GM_RXE_FRAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 	{ "rx_64_byte_packets", GM_RXF_64B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 	{ "rx_65_to_127_byte_packets", GM_RXF_127B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 	{ "rx_128_to_255_byte_packets", GM_RXF_255B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 	{ "rx_256_to_511_byte_packets", GM_RXF_511B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 	{ "rx_512_to_1023_byte_packets", GM_RXF_1023B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 	{ "rx_1024_to_1518_byte_packets", GM_RXF_1518B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	{ "rx_1518_to_max_byte_packets", GM_RXF_MAX_SZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 	{ "rx_too_long",   GM_RXF_LNG_ERR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 	{ "rx_fifo_overflow", GM_RXE_FIFO_OV },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 	{ "rx_jabber",     GM_RXF_JAB_PKT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 	{ "rx_fcs_error",   GM_RXF_FCS_ERR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 	{ "tx_64_byte_packets", GM_TXF_64B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 	{ "tx_65_to_127_byte_packets", GM_TXF_127B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 	{ "tx_128_to_255_byte_packets", GM_TXF_255B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 	{ "tx_256_to_511_byte_packets", GM_TXF_511B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 	{ "tx_512_to_1023_byte_packets", GM_TXF_1023B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 	{ "tx_1024_to_1518_byte_packets", GM_TXF_1518B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 	{ "tx_1519_to_max_byte_packets", GM_TXF_MAX_SZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	{ "tx_fifo_underrun", GM_TXE_FIFO_UR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) static u32 sky2_get_msglevel(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 	struct sky2_port *sky2 = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 	return sky2->msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) static int sky2_nway_reset(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 	if (!netif_running(dev) || !(sky2->flags & SKY2_FLAG_AUTO_SPEED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 	sky2_phy_reinit(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 	sky2_set_multicast(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 	data[0] = get_stats64(hw, port, GM_TXO_OK_LO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 	data[1] = get_stats64(hw, port, GM_RXO_OK_LO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 	for (i = 2; i < count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 		data[i] = get_stats32(hw, port, sky2_stats[i].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) static void sky2_set_msglevel(struct net_device *netdev, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 	struct sky2_port *sky2 = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 	sky2->msg_enable = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) static int sky2_get_sset_count(struct net_device *dev, int sset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 	switch (sset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	case ETH_SS_STATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 		return ARRAY_SIZE(sky2_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) static void sky2_get_ethtool_stats(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 				   struct ethtool_stats *stats, u64 * data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 	sky2_phy_stats(sky2, data, ARRAY_SIZE(sky2_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) static void sky2_get_strings(struct net_device *dev, u32 stringset, u8 * data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	switch (stringset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	case ETH_SS_STATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 		for (i = 0; i < ARRAY_SIZE(sky2_stats); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 			memcpy(data + i * ETH_GSTRING_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 			       sky2_stats[i].name, ETH_GSTRING_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) static int sky2_set_mac_address(struct net_device *dev, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	const struct sockaddr *addr = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 	if (!is_valid_ether_addr(addr->sa_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 		return -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	memcpy_toio(hw->regs + B2_MAC_1 + port * 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 		    dev->dev_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 	memcpy_toio(hw->regs + B2_MAC_2 + port * 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 		    dev->dev_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 	/* virtual address for data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 	gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 	/* physical address: used for pause frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) static inline void sky2_add_filter(u8 filter[8], const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 	u32 bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 	bit = ether_crc(ETH_ALEN, addr) & 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 	filter[bit >> 3] |= 1 << (bit & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) static void sky2_set_multicast(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 	struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 	u8 filter[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 	int rx_pause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 	static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 	rx_pause = (sky2->flow_status == FC_RX || sky2->flow_status == FC_BOTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 	memset(filter, 0, sizeof(filter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 	reg = gma_read16(hw, port, GM_RX_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 	reg |= GM_RXCR_UCF_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 	if (dev->flags & IFF_PROMISC)	/* promiscuous */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 	else if (dev->flags & IFF_ALLMULTI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 		memset(filter, 0xff, sizeof(filter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 	else if (netdev_mc_empty(dev) && !rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 		reg &= ~GM_RXCR_MCF_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 		reg |= GM_RXCR_MCF_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 		if (rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 			sky2_add_filter(filter, pause_mc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 		netdev_for_each_mc_addr(ha, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 			sky2_add_filter(filter, ha->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 	gma_write16(hw, port, GM_MC_ADDR_H1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 		    (u16) filter[0] | ((u16) filter[1] << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 	gma_write16(hw, port, GM_MC_ADDR_H2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 		    (u16) filter[2] | ((u16) filter[3] << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 	gma_write16(hw, port, GM_MC_ADDR_H3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 		    (u16) filter[4] | ((u16) filter[5] << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 	gma_write16(hw, port, GM_MC_ADDR_H4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 		    (u16) filter[6] | ((u16) filter[7] << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	gma_write16(hw, port, GM_RX_CTRL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) static void sky2_get_stats(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 			   struct rtnl_link_stats64 *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 	unsigned int start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 	u64 _bytes, _packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 		start = u64_stats_fetch_begin_irq(&sky2->rx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 		_bytes = sky2->rx_stats.bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 		_packets = sky2->rx_stats.packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 	} while (u64_stats_fetch_retry_irq(&sky2->rx_stats.syncp, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 	stats->rx_packets = _packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 	stats->rx_bytes = _bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 		start = u64_stats_fetch_begin_irq(&sky2->tx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 		_bytes = sky2->tx_stats.bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 		_packets = sky2->tx_stats.packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 	} while (u64_stats_fetch_retry_irq(&sky2->tx_stats.syncp, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	stats->tx_packets = _packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 	stats->tx_bytes = _bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	stats->multicast = get_stats32(hw, port, GM_RXF_MC_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 		+ get_stats32(hw, port, GM_RXF_BC_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 	stats->collisions = get_stats32(hw, port, GM_TXF_COL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 	stats->rx_length_errors = get_stats32(hw, port, GM_RXF_LNG_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 	stats->rx_crc_errors = get_stats32(hw, port, GM_RXF_FCS_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 	stats->rx_frame_errors = get_stats32(hw, port, GM_RXF_SHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 		+ get_stats32(hw, port, GM_RXE_FRAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 	stats->rx_over_errors = get_stats32(hw, port, GM_RXE_FIFO_OV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 	stats->rx_dropped = dev->stats.rx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 	stats->rx_fifo_errors = dev->stats.rx_fifo_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 	stats->tx_fifo_errors = dev->stats.tx_fifo_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) /* Can have one global because blinking is controlled by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930)  * ethtool and that is always under RTNL mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) static void sky2_led(struct sky2_port *sky2, enum led_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 	spin_lock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 	if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 	    hw->chip_id == CHIP_ID_YUKON_EX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 	    hw->chip_id == CHIP_ID_YUKON_SUPR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 		u16 pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 		case MO_LED_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 				     PHY_M_LEDC_LOS_CTRL(8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 				     PHY_M_LEDC_INIT_CTRL(8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 				     PHY_M_LEDC_STA1_CTRL(8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 				     PHY_M_LEDC_STA0_CTRL(8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 		case MO_LED_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 				     PHY_M_LEDC_LOS_CTRL(9) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 				     PHY_M_LEDC_INIT_CTRL(9) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 				     PHY_M_LEDC_STA1_CTRL(9) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 				     PHY_M_LEDC_STA0_CTRL(9));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 		case MO_LED_BLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 				     PHY_M_LEDC_LOS_CTRL(0xa) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 				     PHY_M_LEDC_INIT_CTRL(0xa) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 				     PHY_M_LEDC_STA1_CTRL(0xa) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 				     PHY_M_LEDC_STA0_CTRL(0xa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 		case MO_LED_NORM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 				     PHY_M_LEDC_LOS_CTRL(1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 				     PHY_M_LEDC_INIT_CTRL(8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 				     PHY_M_LEDC_STA1_CTRL(7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 				     PHY_M_LEDC_STA0_CTRL(7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 		gm_phy_write(hw, port, PHY_MARV_LED_OVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 				     PHY_M_LED_MO_DUP(mode) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 				     PHY_M_LED_MO_10(mode) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 				     PHY_M_LED_MO_100(mode) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 				     PHY_M_LED_MO_1000(mode) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 				     PHY_M_LED_MO_RX(mode) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 				     PHY_M_LED_MO_TX(mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 	spin_unlock_bh(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) /* blink LED's for finding board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) static int sky2_set_phys_id(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 			    enum ethtool_phys_id_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 	switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	case ETHTOOL_ID_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 		return 1;	/* cycle on/off once per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 	case ETHTOOL_ID_INACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 		sky2_led(sky2, MO_LED_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 	case ETHTOOL_ID_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 		sky2_led(sky2, MO_LED_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 	case ETHTOOL_ID_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 		sky2_led(sky2, MO_LED_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) static void sky2_get_pauseparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 				struct ethtool_pauseparam *ecmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 	switch (sky2->flow_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 	case FC_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 		ecmd->tx_pause = ecmd->rx_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 	case FC_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 		ecmd->tx_pause = 1, ecmd->rx_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 	case FC_RX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 		ecmd->tx_pause = 0, ecmd->rx_pause = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 	case FC_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 		ecmd->tx_pause = ecmd->rx_pause = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 	ecmd->autoneg = (sky2->flags & SKY2_FLAG_AUTO_PAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 		? AUTONEG_ENABLE : AUTONEG_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) static int sky2_set_pauseparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 			       struct ethtool_pauseparam *ecmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 	if (ecmd->autoneg == AUTONEG_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 		sky2->flags |= SKY2_FLAG_AUTO_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 		sky2->flags &= ~SKY2_FLAG_AUTO_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 	sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 	if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 		sky2_phy_reinit(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) static int sky2_get_coalesce(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 			     struct ethtool_coalesce *ecmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 	if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 		ecmd->tx_coalesce_usecs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 		u32 clks = sky2_read32(hw, STAT_TX_TIMER_INI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 		ecmd->tx_coalesce_usecs = sky2_clk2us(hw, clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	ecmd->tx_max_coalesced_frames = sky2_read16(hw, STAT_TX_IDX_TH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 	if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 		ecmd->rx_coalesce_usecs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 		u32 clks = sky2_read32(hw, STAT_LEV_TIMER_INI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 		ecmd->rx_coalesce_usecs = sky2_clk2us(hw, clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 	ecmd->rx_max_coalesced_frames = sky2_read8(hw, STAT_FIFO_WM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 	if (sky2_read8(hw, STAT_ISR_TIMER_CTRL) == TIM_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 		ecmd->rx_coalesce_usecs_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 		u32 clks = sky2_read32(hw, STAT_ISR_TIMER_INI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 		ecmd->rx_coalesce_usecs_irq = sky2_clk2us(hw, clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 	ecmd->rx_max_coalesced_frames_irq = sky2_read8(hw, STAT_FIFO_ISR_WM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) /* Note: this affect both ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) static int sky2_set_coalesce(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 			     struct ethtool_coalesce *ecmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 	const u32 tmax = sky2_clk2us(hw, 0x0ffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 	if (ecmd->tx_coalesce_usecs > tmax ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 	    ecmd->rx_coalesce_usecs > tmax ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 	    ecmd->rx_coalesce_usecs_irq > tmax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 	if (ecmd->tx_max_coalesced_frames >= sky2->tx_ring_size-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 	if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 	if (ecmd->rx_max_coalesced_frames_irq > RX_MAX_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 	if (ecmd->tx_coalesce_usecs == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 		sky2_write32(hw, STAT_TX_TIMER_INI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 			     sky2_us2clk(hw, ecmd->tx_coalesce_usecs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 	sky2_write16(hw, STAT_TX_IDX_TH, ecmd->tx_max_coalesced_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 	if (ecmd->rx_coalesce_usecs == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 		sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 		sky2_write32(hw, STAT_LEV_TIMER_INI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 			     sky2_us2clk(hw, ecmd->rx_coalesce_usecs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 		sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 	sky2_write8(hw, STAT_FIFO_WM, ecmd->rx_max_coalesced_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 	if (ecmd->rx_coalesce_usecs_irq == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 		sky2_write32(hw, STAT_ISR_TIMER_INI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 			     sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 	sky2_write8(hw, STAT_FIFO_ISR_WM, ecmd->rx_max_coalesced_frames_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136)  * Hardware is limited to min of 128 and max of 2048 for ring size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137)  * and  rounded up to next power of two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138)  * to avoid division in modulus calclation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) static unsigned long roundup_ring_size(unsigned long pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 	return max(128ul, roundup_pow_of_two(pending+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) static void sky2_get_ringparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 			       struct ethtool_ringparam *ering)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 	ering->rx_max_pending = RX_MAX_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 	ering->tx_max_pending = TX_MAX_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 	ering->rx_pending = sky2->rx_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 	ering->tx_pending = sky2->tx_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) static int sky2_set_ringparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 			      struct ethtool_ringparam *ering)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 	if (ering->rx_pending > RX_MAX_PENDING ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 	    ering->rx_pending < 8 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 	    ering->tx_pending < TX_MIN_PENDING ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 	    ering->tx_pending > TX_MAX_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	sky2_detach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	sky2->rx_pending = ering->rx_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 	sky2->tx_pending = ering->tx_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	sky2->tx_ring_size = roundup_ring_size(sky2->tx_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 	return sky2_reattach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) static int sky2_get_regs_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 	return 0x4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) static int sky2_reg_access_ok(struct sky2_hw *hw, unsigned int b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 	/* This complicated switch statement is to make sure and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 	 * only access regions that are unreserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 	 * Some blocks are only valid on dual port cards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 	switch (b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 	/* second port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 	case 5:		/* Tx Arbiter 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 	case 9:		/* RX2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 	case 14 ... 15:	/* TX2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 	case 17: case 19: /* Ram Buffer 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 	case 22 ... 23: /* Tx Ram Buffer 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 	case 25:	/* Rx MAC Fifo 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 	case 27:	/* Tx MAC Fifo 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 	case 31:	/* GPHY 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 	case 40 ... 47: /* Pattern Ram 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 	case 52: case 54: /* TCP Segmentation 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 	case 112 ... 116: /* GMAC 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 		return hw->ports > 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 	case 0:		/* Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 	case 2:		/* Mac address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 	case 4:		/* Tx Arbiter 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 	case 7:		/* PCI express reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 	case 8:		/* RX1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 	case 12 ... 13: /* TX1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 	case 16: case 18:/* Rx Ram Buffer 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 	case 20 ... 21: /* Tx Ram Buffer 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 	case 24:	/* Rx MAC Fifo 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 	case 26:	/* Tx MAC Fifo 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 	case 28 ... 29: /* Descriptor and status unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 	case 30:	/* GPHY 1*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 	case 32 ... 39: /* Pattern Ram 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 	case 48: case 50: /* TCP Segmentation 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 	case 56 ... 60:	/* PCI space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 	case 80 ... 84:	/* GMAC 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227)  * Returns copy of control register region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228)  * Note: ethtool_get_regs always provides full size (16k) buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 			  void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 	const struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 	const void __iomem *io = sky2->hw->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 	unsigned int b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	regs->version = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 	for (b = 0; b < 128; b++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 		/* skip poisonous diagnostic ram region in block 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 		if (b == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 			memcpy_fromio(p + 0x10, io + 0x10, 128 - 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 		else if (sky2_reg_access_ok(sky2->hw, b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 			memcpy_fromio(p, io, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 			memset(p, 0, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 		p += 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 		io += 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) static int sky2_get_eeprom_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	u16 reg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 	reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 	return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) static int sky2_vpd_wait(const struct sky2_hw *hw, int cap, u16 busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 	unsigned long start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 	while ( (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F) == busy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 		/* Can take up to 10.6 ms for write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 		if (time_after(jiffies, start + HZ/4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 			dev_err(&hw->pdev->dev, "VPD cycle timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 			return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) static int sky2_vpd_read(struct sky2_hw *hw, int cap, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 			 u16 offset, size_t length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 	while (length > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 		u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 		rc = sky2_vpd_wait(hw, cap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 		val = sky2_pci_read32(hw, cap + PCI_VPD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 		memcpy(data, &val, min(sizeof(val), length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 		offset += sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 		data += sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 		length -= sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) static int sky2_vpd_write(struct sky2_hw *hw, int cap, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 			  u16 offset, unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 	for (i = 0; i < length; i += sizeof(u32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 		u32 val = *(u32 *)(data + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 		sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 		sky2_pci_write32(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 		rc = sky2_vpd_wait(hw, cap, PCI_VPD_ADDR_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 			   u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 	int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 	if (!cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 	eeprom->magic = SKY2_EEPROM_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 	return sky2_vpd_read(sky2->hw, cap, data, eeprom->offset, eeprom->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 			   u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 	int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 	if (!cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	if (eeprom->magic != SKY2_EEPROM_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 	/* Partial writes not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 	if ((eeprom->offset & 3) || (eeprom->len & 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 	return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) static netdev_features_t sky2_fix_features(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 	netdev_features_t features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 	const struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	const struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 	/* In order to do Jumbo packets on these chips, need to turn off the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 	 * transmit store/forward. Therefore checksum offload won't work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 		netdev_info(dev, "checksum offload not possible with jumbo frames\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 		features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_CSUM_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 	/* Some hardware requires receive checksum for RSS to work. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 	if ( (features & NETIF_F_RXHASH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	     !(features & NETIF_F_RXCSUM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 	     (sky2->hw->flags & SKY2_HW_RSS_CHKSUM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 		netdev_info(dev, "receive hashing forces receive checksum\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 		features |= NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 	return features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) static int sky2_set_features(struct net_device *dev, netdev_features_t features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 	netdev_features_t changed = dev->features ^ features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 	if ((changed & NETIF_F_RXCSUM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 	    !(sky2->hw->flags & SKY2_HW_NEW_LE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 		sky2_write32(sky2->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 			     Q_ADDR(rxqaddr[sky2->port], Q_CSR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 			     (features & NETIF_F_RXCSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 			     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 	if (changed & NETIF_F_RXHASH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 		rx_set_rss(dev, features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 	if (changed & (NETIF_F_HW_VLAN_CTAG_TX|NETIF_F_HW_VLAN_CTAG_RX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 		sky2_vlan_mode(dev, features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) static const struct ethtool_ops sky2_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 				     ETHTOOL_COALESCE_MAX_FRAMES |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 				     ETHTOOL_COALESCE_RX_USECS_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 				     ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 	.get_drvinfo	= sky2_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 	.get_wol	= sky2_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 	.set_wol	= sky2_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 	.get_msglevel	= sky2_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 	.set_msglevel	= sky2_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 	.nway_reset	= sky2_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 	.get_regs_len	= sky2_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 	.get_regs	= sky2_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	.get_link	= ethtool_op_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	.get_eeprom_len	= sky2_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 	.get_eeprom	= sky2_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 	.set_eeprom	= sky2_set_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 	.get_strings	= sky2_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 	.get_coalesce	= sky2_get_coalesce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 	.set_coalesce	= sky2_set_coalesce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 	.get_ringparam	= sky2_get_ringparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 	.set_ringparam	= sky2_set_ringparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 	.get_pauseparam = sky2_get_pauseparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 	.set_pauseparam = sky2_set_pauseparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 	.set_phys_id	= sky2_set_phys_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 	.get_sset_count = sky2_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 	.get_ethtool_stats = sky2_get_ethtool_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 	.get_link_ksettings = sky2_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 	.set_link_ksettings = sky2_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) #ifdef CONFIG_SKY2_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) static struct dentry *sky2_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439)  * Read and parse the first part of Vital Product Data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) #define VPD_SIZE	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) #define VPD_MAGIC	0x82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) static const struct vpd_tag {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 	char tag[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 	char *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) } vpd_tags[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 	{ "PN",	"Part Number" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 	{ "EC", "Engineering Level" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 	{ "MN", "Manufacturer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 	{ "SN", "Serial Number" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 	{ "YA", "Asset Tag" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 	{ "VL", "First Error Log Message" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 	{ "VF", "Second Error Log Message" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 	{ "VB", "Boot Agent ROM Configuration" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 	{ "VE", "EFI UNDI Configuration" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) static void sky2_show_vpd(struct seq_file *seq, struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 	size_t vpd_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 	loff_t offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 	u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 	unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 	u16 reg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 	reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 	vpd_size = 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 	seq_printf(seq, "%s Product Data\n", pci_name(hw->pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	buf = kmalloc(vpd_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 	if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 		seq_puts(seq, "no memory!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 	if (pci_read_vpd(hw->pdev, 0, vpd_size, buf) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 		seq_puts(seq, "VPD read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 	if (buf[0] != VPD_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 		seq_printf(seq, "VPD tag mismatch: %#x\n", buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 	len = buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 	if (len == 0 || len > vpd_size - 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 		seq_printf(seq, "Invalid id length: %d\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 	seq_printf(seq, "%.*s\n", len, buf + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 	offs = len + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) 	while (offs < vpd_size - 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 		if (!memcmp("RW", buf + offs, 2))	/* end marker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 		len = buf[offs + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 		if (offs + len + 3 >= vpd_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 		for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 			if (!memcmp(vpd_tags[i].tag, buf + offs, 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 				seq_printf(seq, " %s: %.*s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 					   vpd_tags[i].label, len, buf + offs + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 		offs += len + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) static int sky2_debug_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 	struct net_device *dev = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 	const struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 	struct sky2_hw *hw = sky2->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 	unsigned port = sky2->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 	unsigned idx, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 	int sop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	sky2_show_vpd(seq, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 	seq_printf(seq, "\nIRQ src=%x mask=%x control=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 		   sky2_read32(hw, B0_ISRC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 		   sky2_read32(hw, B0_IMSK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 		   sky2_read32(hw, B0_Y2_SP_ICR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 	if (!netif_running(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 		seq_puts(seq, "network not running\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	napi_disable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 	last = sky2_read16(hw, STAT_PUT_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 	seq_printf(seq, "Status ring %u\n", hw->st_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 	if (hw->st_idx == last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 		seq_puts(seq, "Status ring (empty)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 		seq_puts(seq, "Status ring\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 		for (idx = hw->st_idx; idx != last && idx < hw->st_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 		     idx = RING_NEXT(idx, hw->st_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 			const struct sky2_status_le *le = hw->st_le + idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 			seq_printf(seq, "[%d] %#x %d %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 				   idx, le->opcode, le->length, le->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 		seq_puts(seq, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 	seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 		   sky2->tx_cons, sky2->tx_prod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 		   sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 		   sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 	/* Dump contents of tx ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 	sop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 	for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < sky2->tx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 	     idx = RING_NEXT(idx, sky2->tx_ring_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 		const struct sky2_tx_le *le = sky2->tx_le + idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 		u32 a = le32_to_cpu(le->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 		if (sop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 			seq_printf(seq, "%u:", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 		sop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 		switch (le->opcode & ~HW_OWNER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 		case OP_ADDR64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 			seq_printf(seq, " %#x:", a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 		case OP_LRGLEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) 			seq_printf(seq, " mtu=%d", a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 		case OP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 			seq_printf(seq, " vlan=%d", be16_to_cpu(le->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 		case OP_TCPLISW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 			seq_printf(seq, " csum=%#x", a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 		case OP_LARGESEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 			seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 		case OP_PACKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 			seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 		case OP_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 			seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 			seq_printf(seq, " op=%#x,%#x(%d)", le->opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) 				   a, le16_to_cpu(le->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 		if (le->ctrl & EOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 			seq_putc(seq, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 			sop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) 	seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) 		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) 		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 	sky2_read32(hw, B0_Y2_SP_LISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 	napi_enable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) DEFINE_SHOW_ATTRIBUTE(sky2_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616)  * Use network device events to create/remove/rename
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617)  * debugfs file entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) static int sky2_device_event(struct notifier_block *unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) 			     unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) 	struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) 	if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) 		return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) 	case NETDEV_CHANGENAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 		if (sky2->debugfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 			sky2->debugfs = debugfs_rename(sky2_debug, sky2->debugfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) 						       sky2_debug, dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 	case NETDEV_GOING_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 		if (sky2->debugfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 			netdev_printk(KERN_DEBUG, dev, "remove debugfs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 			debugfs_remove(sky2->debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 			sky2->debugfs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 	case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 		sky2->debugfs = debugfs_create_file(dev->name, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 						    sky2_debug, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 						    &sky2_debug_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 		if (IS_ERR(sky2->debugfs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 			sky2->debugfs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) static struct notifier_block sky2_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) 	.notifier_call = sky2_device_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) static __init void sky2_debug_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) 	struct dentry *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) 	ent = debugfs_create_dir("sky2", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) 	if (!ent || IS_ERR(ent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) 	sky2_debug = ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) 	register_netdevice_notifier(&sky2_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) static __exit void sky2_debug_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 	if (sky2_debug) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) 		unregister_netdevice_notifier(&sky2_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) 		debugfs_remove(sky2_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) 		sky2_debug = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) #define sky2_debug_init()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) #define sky2_debug_cleanup()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) /* Two copies of network device operations to handle special case of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687)    not allowing netpoll on second port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) static const struct net_device_ops sky2_netdev_ops[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) 	.ndo_open		= sky2_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) 	.ndo_stop		= sky2_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) 	.ndo_start_xmit		= sky2_xmit_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) 	.ndo_do_ioctl		= sky2_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) 	.ndo_validate_addr	= eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) 	.ndo_set_mac_address	= sky2_set_mac_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) 	.ndo_set_rx_mode	= sky2_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) 	.ndo_change_mtu		= sky2_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) 	.ndo_fix_features	= sky2_fix_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) 	.ndo_set_features	= sky2_set_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) 	.ndo_tx_timeout		= sky2_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 	.ndo_get_stats64	= sky2_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 	.ndo_poll_controller	= sky2_netpoll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705)   },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 	.ndo_open		= sky2_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) 	.ndo_stop		= sky2_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) 	.ndo_start_xmit		= sky2_xmit_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 	.ndo_do_ioctl		= sky2_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 	.ndo_validate_addr	= eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) 	.ndo_set_mac_address	= sky2_set_mac_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 	.ndo_set_rx_mode	= sky2_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) 	.ndo_change_mtu		= sky2_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) 	.ndo_fix_features	= sky2_fix_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) 	.ndo_set_features	= sky2_set_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) 	.ndo_tx_timeout		= sky2_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) 	.ndo_get_stats64	= sky2_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719)   },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) /* Initialize network device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) 					   int highmem, int wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) 	struct sky2_port *sky2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 	struct net_device *dev = alloc_etherdev(sizeof(*sky2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 	const void *iap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 	dev->irq = hw->pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 	dev->ethtool_ops = &sky2_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 	dev->watchdog_timeo = TX_WATCHDOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 	dev->netdev_ops = &sky2_netdev_ops[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) 	sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 	sky2->netdev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 	sky2->hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) 	sky2->msg_enable = netif_msg_init(debug, default_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) 	u64_stats_init(&sky2->tx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) 	u64_stats_init(&sky2->rx_stats.syncp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) 	/* Auto speed and flow control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) 	sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) 	if (hw->chip_id != CHIP_ID_YUKON_XL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 		dev->hw_features |= NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) 	sky2->flow_mode = FC_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) 	sky2->duplex = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) 	sky2->speed = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 	sky2->advertising = sky2_supported_modes(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 	sky2->wol = wol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) 	spin_lock_init(&sky2->phy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) 	sky2->tx_pending = TX_DEF_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) 	sky2->tx_ring_size = roundup_ring_size(TX_DEF_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) 	sky2->rx_pending = RX_DEF_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) 	hw->dev[port] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) 	sky2->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) 	dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) 	if (highmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 		dev->features |= NETIF_F_HIGHDMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) 	/* Enable receive hashing unless hardware is known broken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) 	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) 		dev->hw_features |= NETIF_F_RXHASH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) 	if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 		dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) 				    NETIF_F_HW_VLAN_CTAG_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 		dev->vlan_features |= SKY2_VLAN_OFFLOADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) 	dev->features |= dev->hw_features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) 	/* MTU range: 60 - 1500 or 9000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) 	dev->min_mtu = ETH_ZLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) 	if (hw->chip_id == CHIP_ID_YUKON_FE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) 	    hw->chip_id == CHIP_ID_YUKON_FE_P)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) 		dev->max_mtu = ETH_DATA_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) 		dev->max_mtu = ETH_JUMBO_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) 	/* try to get mac address in the following order:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) 	 * 1) from device tree data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) 	 * 2) from internal registers set by bootloader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) 	iap = of_get_mac_address(hw->pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) 	if (!IS_ERR(iap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) 		ether_addr_copy(dev->dev_addr, iap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 		memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 			      ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) 	/* if the address is invalid, use a random value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 	if (!is_valid_ether_addr(dev->dev_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 		struct sockaddr sa = { AF_UNSPEC };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) 		netdev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 			    "Invalid MAC address, defaulting to random\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) 		eth_hw_addr_random(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) 		memcpy(sa.sa_data, dev->dev_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) 		if (sky2_set_mac_address(dev, &sa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) 			netdev_warn(dev, "Failed to set MAC address.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) 	return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) static void sky2_show_addr(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) 	const struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) 	netif_info(sky2, probe, dev, "addr %pM\n", dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) /* Handle software interrupt used during MSI test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) static irqreturn_t sky2_test_intr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 	struct sky2_hw *hw = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 	u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 	if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 	if (status & Y2_IS_IRQ_SW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) 		hw->flags |= SKY2_HW_USE_MSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 		wake_up(&hw->msi_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) 		sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 	sky2_write32(hw, B0_Y2_SP_ICR, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) /* Test interrupt path by forcing a a software IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) static int sky2_test_msi(struct sky2_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) 	struct pci_dev *pdev = hw->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) 	init_waitqueue_head(&hw->msi_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) 	err = request_irq(pdev->irq, sky2_test_intr, 0, DRV_NAME, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) 		dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) 	sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) 	sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) 	sky2_read8(hw, B0_CTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) 	wait_event_timeout(hw->msi_wait, (hw->flags & SKY2_HW_USE_MSI), HZ/10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 	if (!(hw->flags & SKY2_HW_USE_MSI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) 		/* MSI test failed, go back to INTx mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 		dev_info(&pdev->dev, "No interrupt generated using MSI, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 			 "switching to INTx mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) 		sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) 	sky2_write32(hw, B0_IMSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 	sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) 	free_irq(pdev->irq, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) /* This driver supports yukon2 chipset only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) static const char *sky2_name(u8 chipid, char *buf, int sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 	const char *name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 		"XL",		/* 0xb3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 		"EC Ultra", 	/* 0xb4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 		"Extreme",	/* 0xb5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) 		"EC",		/* 0xb6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 		"FE",		/* 0xb7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) 		"FE+",		/* 0xb8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 		"Supreme",	/* 0xb9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) 		"UL 2",		/* 0xba */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) 		"Unknown",	/* 0xbb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) 		"Optima",	/* 0xbc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) 		"OptimaEEE",    /* 0xbd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) 		"Optima 2",	/* 0xbe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) 	if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OP_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) 		strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) 		snprintf(buf, sz, "(chip %#x)", chipid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) 	return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) static const struct dmi_system_id msi_blacklist[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 		.ident = "Dell Inspiron 1545",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) 			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1545"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) 		.ident = "Gateway P-79",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) 			DMI_MATCH(DMI_SYS_VENDOR, "Gateway"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) 			DMI_MATCH(DMI_PRODUCT_NAME, "P-79"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) 		.ident = "ASUS P5W DH Deluxe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTEK COMPUTER INC"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) 			DMI_MATCH(DMI_PRODUCT_NAME, "P5W DH Deluxe"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) 		.ident = "ASUS P6T",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) 			DMI_MATCH(DMI_BOARD_NAME, "P6T"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) 		.ident = "ASUS P6X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) 		.matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) 			DMI_MATCH(DMI_BOARD_NAME, "P6X"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) 	struct net_device *dev, *dev1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) 	struct sky2_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) 	int err, using_dac = 0, wol_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) 	char buf1[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) 	err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) 		dev_err(&pdev->dev, "cannot enable PCI device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) 	/* Get configuration information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) 	 * Note: only regular PCI config access once to test for HW issues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) 	 *       other PCI access through shared memory for speed and to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) 	 *	 avoid MMCONFIG problems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) 	err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) 		dev_err(&pdev->dev, "PCI read config failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) 		goto err_out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) 	if (~reg == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) 		dev_err(&pdev->dev, "PCI configuration read error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) 		err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) 		goto err_out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) 	err = pci_request_regions(pdev, DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) 		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) 		goto err_out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) 	if (sizeof(dma_addr_t) > sizeof(u32) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) 	    !(err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) 		using_dac = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) 		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) 			dev_err(&pdev->dev, "unable to obtain 64 bit DMA "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) 				"for consistent allocations\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) 			goto err_out_free_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) 		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) 			dev_err(&pdev->dev, "no usable DMA configuration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) 			goto err_out_free_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) #ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) 	/* The sk98lin vendor driver uses hardware byte swapping but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) 	 * this driver uses software swapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) 	reg &= ~PCI_REV_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) 	err = pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) 		dev_err(&pdev->dev, "PCI write config failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) 		goto err_out_free_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) 	wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) 	err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) 	hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) 		     + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) 	if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) 		goto err_out_free_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) 	hw->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) 	sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) 	hw->regs = ioremap(pci_resource_start(pdev, 0), 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) 	if (!hw->regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) 		dev_err(&pdev->dev, "cannot map device registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) 		goto err_out_free_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) 	err = sky2_init(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) 		goto err_out_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) 	/* ring for status responses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) 	hw->st_size = hw->ports * roundup_pow_of_two(3*RX_MAX_PENDING + TX_MAX_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) 	hw->st_le = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) 				       hw->st_size * sizeof(struct sky2_status_le),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) 				       &hw->st_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) 	if (!hw->st_le) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) 		goto err_out_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) 	dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) 		 sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) 	sky2_reset(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) 	dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) 	if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) 		goto err_out_free_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) 	if (disable_msi == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) 		disable_msi = !!dmi_check_system(msi_blacklist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) 	if (!disable_msi && pci_enable_msi(pdev) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) 		err = sky2_test_msi(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066)  			pci_disable_msi(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) 			if (err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) 				goto err_out_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070)  	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) 	netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) 	err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) 		dev_err(&pdev->dev, "cannot register net device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) 		goto err_out_free_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) 	netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) 	sky2_show_addr(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) 	if (hw->ports > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) 		dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) 		if (!dev1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) 			goto err_out_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) 		err = register_netdev(dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) 			dev_err(&pdev->dev, "cannot register second net device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) 			goto err_out_free_dev1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) 		err = sky2_setup_irq(hw, hw->irq_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) 			goto err_out_unregister_dev1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) 		sky2_show_addr(dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) 	timer_setup(&hw->watchdog_timer, sky2_watchdog, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) 	INIT_WORK(&hw->restart_work, sky2_restart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) 	pci_set_drvdata(pdev, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) 	pdev->d3hot_delay = 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) err_out_unregister_dev1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) 	unregister_netdev(dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) err_out_free_dev1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) 	free_netdev(dev1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) err_out_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) 	unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) err_out_free_netdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) 	if (hw->flags & SKY2_HW_USE_MSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) 		pci_disable_msi(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) 	free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) err_out_free_pci:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) 	dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) 			  hw->st_size * sizeof(struct sky2_status_le),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) 			  hw->st_le, hw->st_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) err_out_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) 	sky2_write8(hw, B0_CTST, CS_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) err_out_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) 	iounmap(hw->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) err_out_free_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) 	kfree(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) err_out_free_regions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) 	pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) err_out_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) static void sky2_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) 	struct sky2_hw *hw = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) 	if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) 	del_timer_sync(&hw->watchdog_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) 	cancel_work_sync(&hw->restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) 	for (i = hw->ports-1; i >= 0; --i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) 		unregister_netdev(hw->dev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) 	sky2_write32(hw, B0_IMSK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) 	sky2_read32(hw, B0_IMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) 	sky2_power_aux(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) 	sky2_write8(hw, B0_CTST, CS_RST_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) 	sky2_read8(hw, B0_CTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) 	if (hw->ports > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) 		napi_disable(&hw->napi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) 		free_irq(pdev->irq, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) 	if (hw->flags & SKY2_HW_USE_MSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) 		pci_disable_msi(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) 	dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) 			  hw->st_size * sizeof(struct sky2_status_le),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) 			  hw->st_le, hw->st_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) 	pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) 	for (i = hw->ports-1; i >= 0; --i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) 		free_netdev(hw->dev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) 	iounmap(hw->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) 	kfree(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) static int sky2_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) 	struct sky2_hw *hw = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) 	if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) 	del_timer_sync(&hw->watchdog_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) 	cancel_work_sync(&hw->restart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) 	sky2_all_down(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) 	for (i = 0; i < hw->ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) 		struct net_device *dev = hw->dev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) 		struct sky2_port *sky2 = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) 		if (sky2->wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) 			sky2_wol_init(sky2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) 	sky2_power_aux(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) static int sky2_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) 	struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) 	struct sky2_hw *hw = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) 	if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) 	/* Re-enable all clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) 	err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) 		dev_err(&pdev->dev, "PCI write config failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) 	sky2_reset(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) 	sky2_all_up(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) 	dev_err(&pdev->dev, "resume failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) #define SKY2_PM_OPS (&sky2_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) #define SKY2_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) static void sky2_shutdown(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) 	struct sky2_hw *hw = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) 	int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) 	for (port = 0; port < hw->ports; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) 		struct net_device *ndev = hw->dev[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) 		rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) 		if (netif_running(ndev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) 			dev_close(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) 			netif_device_detach(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) 		rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) 	sky2_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) 	pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) 	pci_set_power_state(pdev, PCI_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) static struct pci_driver sky2_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) 	.name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) 	.id_table = sky2_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) 	.probe = sky2_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) 	.remove = sky2_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) 	.shutdown = sky2_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) 	.driver.pm = SKY2_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) static int __init sky2_init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) 	pr_info("driver version " DRV_VERSION "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) 	sky2_debug_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) 	return pci_register_driver(&sky2_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) static void __exit sky2_cleanup_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) 	pci_unregister_driver(&sky2_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) 	sky2_debug_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) module_init(sky2_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) module_exit(sky2_cleanup_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) MODULE_VERSION(DRV_VERSION);