···2515251525162516source "drivers/net/stmmac/Kconfig"2517251725182518+config PCH_GBE25192519+ tristate "PCH Gigabit Ethernet"25202520+ depends on PCI25212521+ ---help---25222522+ This is a gigabit ethernet driver for Topcliff PCH.25232523+ Topcliff PCH is the platform controller hub that is used in Intel's25242524+ general embedded platform.25252525+ Topcliff PCH has Gigabit Ethernet interface.25262526+ Using this interface, it is able to access system devices connected25272527+ to Gigabit Ethernet.25282528+ This driver enables Gigabit Ethernet function.25292529+25182530endif # NETDEV_10002519253125202532#
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+2121+#ifndef _PCH_GBE_H_2222+#define _PCH_GBE_H_2323+2424+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt2525+2626+#include <linux/mii.h>2727+#include <linux/delay.h>2828+#include <linux/pci.h>2929+#include <linux/netdevice.h>3030+#include <linux/etherdevice.h>3131+#include <linux/ethtool.h>3232+#include <linux/vmalloc.h>3333+#include <net/ip.h>3434+3535+/**3636+ * pch_gbe_regs_mac_adr - Structure holding values of mac address registers3737+ * @high Denotes the 1st to 4th byte from the initial of MAC address3838+ * @low Denotes the 5th to 6th byte from the initial of MAC address3939+ */4040+struct pch_gbe_regs_mac_adr {4141+ u32 high;4242+ u32 low;4343+};4444+/**4545+ * pch_udc_regs - Structure holding values of MAC registers4646+ */4747+struct pch_gbe_regs {4848+ u32 INT_ST;4949+ u32 INT_EN;5050+ u32 MODE;5151+ u32 RESET;5252+ u32 TCPIP_ACC;5353+ u32 EX_LIST;5454+ u32 INT_ST_HOLD;5555+ u32 PHY_INT_CTRL;5656+ u32 MAC_RX_EN;5757+ u32 RX_FCTRL;5858+ u32 PAUSE_REQ;5959+ u32 RX_MODE;6060+ u32 TX_MODE;6161+ u32 RX_FIFO_ST;6262+ u32 TX_FIFO_ST;6363+ u32 TX_FID;6464+ u32 TX_RESULT;6565+ u32 PAUSE_PKT1;6666+ u32 PAUSE_PKT2;6767+ u32 PAUSE_PKT3;6868+ u32 PAUSE_PKT4;6969+ u32 PAUSE_PKT5;7070+ u32 reserve[2];7171+ struct pch_gbe_regs_mac_adr mac_adr[16];7272+ u32 ADDR_MASK;7373+ u32 MIIM;7474+ u32 reserve2;7575+ u32 RGMII_ST;7676+ u32 RGMII_CTRL;7777+ u32 reserve3[3];7878+ u32 DMA_CTRL;7979+ u32 reserve4[3];8080+ u32 RX_DSC_BASE;8181+ u32 RX_DSC_SIZE;8282+ u32 RX_DSC_HW_P;8383+ u32 RX_DSC_HW_P_HLD;8484+ u32 RX_DSC_SW_P;8585+ u32 reserve5[3];8686+ u32 TX_DSC_BASE;8787+ u32 TX_DSC_SIZE;8888+ u32 TX_DSC_HW_P;8989+ u32 TX_DSC_HW_P_HLD;9090+ u32 TX_DSC_SW_P;9191+ u32 reserve6[3];9292+ u32 RX_DMA_ST;9393+ u32 TX_DMA_ST;9494+ u32 reserve7[2];9595+ u32 WOL_ST;9696+ u32 WOL_CTRL;9797+ u32 WOL_ADDR_MASK;9898+};9999+100100+/* Interrupt Status */101101+/* Interrupt Status Hold */102102+/* Interrupt Enable */103103+#define PCH_GBE_INT_RX_DMA_CMPLT 0x00000001 /* Receive DMA Transfer Complete */104104+#define PCH_GBE_INT_RX_VALID 0x00000002 /* MAC Normal Receive Complete */105105+#define PCH_GBE_INT_RX_FRAME_ERR 0x00000004 /* Receive frame error */106106+#define PCH_GBE_INT_RX_FIFO_ERR 0x00000008 /* Receive FIFO Overflow */107107+#define PCH_GBE_INT_RX_DMA_ERR 0x00000010 /* Receive DMA Transfer Error */108108+#define PCH_GBE_INT_RX_DSC_EMP 0x00000020 /* Receive Descriptor Empty */109109+#define PCH_GBE_INT_TX_CMPLT 0x00000100 /* MAC Transmission Complete */110110+#define PCH_GBE_INT_TX_DMA_CMPLT 0x00000200 /* DMA Transfer Complete */111111+#define PCH_GBE_INT_TX_FIFO_ERR 0x00000400 /* Transmission FIFO underflow. */112112+#define PCH_GBE_INT_TX_DMA_ERR 0x00000800 /* Transmission DMA Error */113113+#define PCH_GBE_INT_PAUSE_CMPLT 0x00001000 /* Pause Transmission complete */114114+#define PCH_GBE_INT_MIIM_CMPLT 0x00010000 /* MIIM I/F Read completion */115115+#define PCH_GBE_INT_PHY_INT 0x00100000 /* Interruption from PHY */116116+#define PCH_GBE_INT_WOL_DET 0x01000000 /* Wake On LAN Event detection. */117117+#define PCH_GBE_INT_TCPIP_ERR 0x10000000 /* TCP/IP Accelerator Error */118118+119119+/* Mode */120120+#define PCH_GBE_MODE_MII_ETHER 0x00000000 /* GIGA Ethernet Mode [MII] */121121+#define PCH_GBE_MODE_GMII_ETHER 0x80000000 /* GIGA Ethernet Mode [GMII] */122122+#define PCH_GBE_MODE_HALF_DUPLEX 0x00000000 /* Duplex Mode [half duplex] */123123+#define PCH_GBE_MODE_FULL_DUPLEX 0x40000000 /* Duplex Mode [full duplex] */124124+#define PCH_GBE_MODE_FR_BST 0x04000000 /* Frame bursting is done */125125+126126+/* Reset */127127+#define PCH_GBE_ALL_RST 0x80000000 /* All reset */128128+#define PCH_GBE_TX_RST 0x40000000 /* TX MAC, TX FIFO, TX DMA reset */129129+#define PCH_GBE_RX_RST 0x04000000 /* RX MAC, RX FIFO, RX DMA reset */130130+131131+/* TCP/IP Accelerator Control */132132+#define PCH_GBE_EX_LIST_EN 0x00000008 /* External List Enable */133133+#define PCH_GBE_RX_TCPIPACC_OFF 0x00000004 /* RX TCP/IP ACC Disabled */134134+#define PCH_GBE_TX_TCPIPACC_EN 0x00000002 /* TX TCP/IP ACC Enable */135135+#define PCH_GBE_RX_TCPIPACC_EN 0x00000001 /* RX TCP/IP ACC Enable */136136+137137+/* MAC RX Enable */138138+#define PCH_GBE_MRE_MAC_RX_EN 0x00000001 /* MAC Receive Enable */139139+140140+/* RX Flow Control */141141+#define PCH_GBE_FL_CTRL_EN 0x80000000 /* Pause packet is enabled */142142+143143+/* Pause Packet Request */144144+#define PCH_GBE_PS_PKT_RQ 0x80000000 /* Pause packet Request */145145+146146+/* RX Mode */147147+#define PCH_GBE_ADD_FIL_EN 0x80000000 /* Address Filtering Enable */148148+/* Multicast Filtering Enable */149149+#define PCH_GBE_MLT_FIL_EN 0x40000000150150+/* Receive Almost Empty Threshold */151151+#define PCH_GBE_RH_ALM_EMP_4 0x00000000 /* 4 words */152152+#define PCH_GBE_RH_ALM_EMP_8 0x00004000 /* 8 words */153153+#define PCH_GBE_RH_ALM_EMP_16 0x00008000 /* 16 words */154154+#define PCH_GBE_RH_ALM_EMP_32 0x0000C000 /* 32 words */155155+/* Receive Almost Full Threshold */156156+#define PCH_GBE_RH_ALM_FULL_4 0x00000000 /* 4 words */157157+#define PCH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */158158+#define PCH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */159159+#define PCH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */160160+/* RX FIFO Read Triger Threshold */161161+#define PCH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */162162+#define PCH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */163163+#define PCH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */164164+#define PCH_GBE_RH_RD_TRG_32 0x00000600 /* 32 words */165165+#define PCH_GBE_RH_RD_TRG_64 0x00000800 /* 64 words */166166+#define PCH_GBE_RH_RD_TRG_128 0x00000A00 /* 128 words */167167+#define PCH_GBE_RH_RD_TRG_256 0x00000C00 /* 256 words */168168+#define PCH_GBE_RH_RD_TRG_512 0x00000E00 /* 512 words */169169+170170+/* Receive Descriptor bit definitions */171171+#define PCH_GBE_RXD_ACC_STAT_BCAST 0x00000400172172+#define PCH_GBE_RXD_ACC_STAT_MCAST 0x00000200173173+#define PCH_GBE_RXD_ACC_STAT_UCAST 0x00000100174174+#define PCH_GBE_RXD_ACC_STAT_TCPIPOK 0x000000C0175175+#define PCH_GBE_RXD_ACC_STAT_IPOK 0x00000080176176+#define PCH_GBE_RXD_ACC_STAT_TCPOK 0x00000040177177+#define PCH_GBE_RXD_ACC_STAT_IP6ERR 0x00000020178178+#define PCH_GBE_RXD_ACC_STAT_OFLIST 0x00000010179179+#define PCH_GBE_RXD_ACC_STAT_TYPEIP 0x00000008180180+#define PCH_GBE_RXD_ACC_STAT_MACL 0x00000004181181+#define PCH_GBE_RXD_ACC_STAT_PPPOE 0x00000002182182+#define PCH_GBE_RXD_ACC_STAT_VTAGT 0x00000001183183+#define PCH_GBE_RXD_GMAC_STAT_PAUSE 0x0200184184+#define PCH_GBE_RXD_GMAC_STAT_MARBR 0x0100185185+#define PCH_GBE_RXD_GMAC_STAT_MARMLT 0x0080186186+#define PCH_GBE_RXD_GMAC_STAT_MARIND 0x0040187187+#define PCH_GBE_RXD_GMAC_STAT_MARNOTMT 0x0020188188+#define PCH_GBE_RXD_GMAC_STAT_TLONG 0x0010189189+#define PCH_GBE_RXD_GMAC_STAT_TSHRT 0x0008190190+#define PCH_GBE_RXD_GMAC_STAT_NOTOCTAL 0x0004191191+#define PCH_GBE_RXD_GMAC_STAT_NBLERR 0x0002192192+#define PCH_GBE_RXD_GMAC_STAT_CRCERR 0x0001193193+194194+/* Transmit Descriptor bit definitions */195195+#define PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF 0x0008196196+#define PCH_GBE_TXD_CTRL_ITAG 0x0004197197+#define PCH_GBE_TXD_CTRL_ICRC 0x0002198198+#define PCH_GBE_TXD_CTRL_APAD 0x0001199199+#define PCH_GBE_TXD_WORDS_SHIFT 2200200+#define PCH_GBE_TXD_GMAC_STAT_CMPLT 0x2000201201+#define PCH_GBE_TXD_GMAC_STAT_ABT 0x1000202202+#define PCH_GBE_TXD_GMAC_STAT_EXCOL 0x0800203203+#define PCH_GBE_TXD_GMAC_STAT_SNGCOL 0x0400204204+#define PCH_GBE_TXD_GMAC_STAT_MLTCOL 0x0200205205+#define PCH_GBE_TXD_GMAC_STAT_CRSER 0x0100206206+#define PCH_GBE_TXD_GMAC_STAT_TLNG 0x0080207207+#define PCH_GBE_TXD_GMAC_STAT_TSHRT 0x0040208208+#define PCH_GBE_TXD_GMAC_STAT_LTCOL 0x0020209209+#define PCH_GBE_TXD_GMAC_STAT_TFUNDFLW 0x0010210210+#define PCH_GBE_TXD_GMAC_STAT_RTYCNT_MASK 0x000F211211+212212+/* TX Mode */213213+#define PCH_GBE_TM_NO_RTRY 0x80000000 /* No Retransmission */214214+#define PCH_GBE_TM_LONG_PKT 0x40000000 /* Long Packt TX Enable */215215+#define PCH_GBE_TM_ST_AND_FD 0x20000000 /* Stare and Forward */216216+#define PCH_GBE_TM_SHORT_PKT 0x10000000 /* Short Packet TX Enable */217217+#define PCH_GBE_TM_LTCOL_RETX 0x08000000 /* Retransmission at Late Collision */218218+/* Frame Start Threshold */219219+#define PCH_GBE_TM_TH_TX_STRT_4 0x00000000 /* 4 words */220220+#define PCH_GBE_TM_TH_TX_STRT_8 0x00004000 /* 8 words */221221+#define PCH_GBE_TM_TH_TX_STRT_16 0x00008000 /* 16 words */222222+#define PCH_GBE_TM_TH_TX_STRT_32 0x0000C000 /* 32 words */223223+/* Transmit Almost Empty Threshold */224224+#define PCH_GBE_TM_TH_ALM_EMP_4 0x00000000 /* 4 words */225225+#define PCH_GBE_TM_TH_ALM_EMP_8 0x00000800 /* 8 words */226226+#define PCH_GBE_TM_TH_ALM_EMP_16 0x00001000 /* 16 words */227227+#define PCH_GBE_TM_TH_ALM_EMP_32 0x00001800 /* 32 words */228228+#define PCH_GBE_TM_TH_ALM_EMP_64 0x00002000 /* 64 words */229229+#define PCH_GBE_TM_TH_ALM_EMP_128 0x00002800 /* 128 words */230230+#define PCH_GBE_TM_TH_ALM_EMP_256 0x00003000 /* 256 words */231231+#define PCH_GBE_TM_TH_ALM_EMP_512 0x00003800 /* 512 words */232232+/* Transmit Almost Full Threshold */233233+#define PCH_GBE_TM_TH_ALM_FULL_4 0x00000000 /* 4 words */234234+#define PCH_GBE_TM_TH_ALM_FULL_8 0x00000200 /* 8 words */235235+#define PCH_GBE_TM_TH_ALM_FULL_16 0x00000400 /* 16 words */236236+#define PCH_GBE_TM_TH_ALM_FULL_32 0x00000600 /* 32 words */237237+238238+/* RX FIFO Status */239239+#define PCH_GBE_RF_ALM_FULL 0x80000000 /* RX FIFO is almost full. */240240+#define PCH_GBE_RF_ALM_EMP 0x40000000 /* RX FIFO is almost empty. */241241+#define PCH_GBE_RF_RD_TRG 0x20000000 /* Become more than RH_RD_TRG. */242242+#define PCH_GBE_RF_STRWD 0x1FFE0000 /* The word count of RX FIFO. */243243+#define PCH_GBE_RF_RCVING 0x00010000 /* Stored in RX FIFO. */244244+245245+/* MAC Address Mask */246246+#define PCH_GBE_BUSY 0x80000000247247+248248+/* MIIM */249249+#define PCH_GBE_MIIM_OPER_WRITE 0x04000000250250+#define PCH_GBE_MIIM_OPER_READ 0x00000000251251+#define PCH_GBE_MIIM_OPER_READY 0x04000000252252+#define PCH_GBE_MIIM_PHY_ADDR_SHIFT 21253253+#define PCH_GBE_MIIM_REG_ADDR_SHIFT 16254254+255255+/* RGMII Status */256256+#define PCH_GBE_LINK_UP 0x80000008257257+#define PCH_GBE_RXC_SPEED_MSK 0x00000006258258+#define PCH_GBE_RXC_SPEED_2_5M 0x00000000 /* 2.5MHz */259259+#define PCH_GBE_RXC_SPEED_25M 0x00000002 /* 25MHz */260260+#define PCH_GBE_RXC_SPEED_125M 0x00000004 /* 100MHz */261261+#define PCH_GBE_DUPLEX_FULL 0x00000001262262+263263+/* RGMII Control */264264+#define PCH_GBE_CRS_SEL 0x00000010265265+#define PCH_GBE_RGMII_RATE_125M 0x00000000266266+#define PCH_GBE_RGMII_RATE_25M 0x00000008267267+#define PCH_GBE_RGMII_RATE_2_5M 0x0000000C268268+#define PCH_GBE_RGMII_MODE_GMII 0x00000000269269+#define PCH_GBE_RGMII_MODE_RGMII 0x00000002270270+#define PCH_GBE_CHIP_TYPE_EXTERNAL 0x00000000271271+#define PCH_GBE_CHIP_TYPE_INTERNAL 0x00000001272272+273273+/* DMA Control */274274+#define PCH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */275275+#define PCH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */276276+277277+/* Wake On LAN Status */278278+#define PCH_GBE_WLS_BR 0x00000008 /* Broadcas Address */279279+#define PCH_GBE_WLS_MLT 0x00000004 /* Multicast Address */280280+281281+/* The Frame registered in Address Recognizer */282282+#define PCH_GBE_WLS_IND 0x00000002283283+#define PCH_GBE_WLS_MP 0x00000001 /* Magic packet Address */284284+285285+/* Wake On LAN Control */286286+#define PCH_GBE_WLC_WOL_MODE 0x00010000287287+#define PCH_GBE_WLC_IGN_TLONG 0x00000100288288+#define PCH_GBE_WLC_IGN_TSHRT 0x00000080289289+#define PCH_GBE_WLC_IGN_OCTER 0x00000040290290+#define PCH_GBE_WLC_IGN_NBLER 0x00000020291291+#define PCH_GBE_WLC_IGN_CRCER 0x00000010292292+#define PCH_GBE_WLC_BR 0x00000008293293+#define PCH_GBE_WLC_MLT 0x00000004294294+#define PCH_GBE_WLC_IND 0x00000002295295+#define PCH_GBE_WLC_MP 0x00000001296296+297297+/* Wake On LAN Address Mask */298298+#define PCH_GBE_WLA_BUSY 0x80000000299299+300300+301301+302302+/* TX/RX descriptor defines */303303+#define PCH_GBE_MAX_TXD 4096304304+#define PCH_GBE_DEFAULT_TXD 256305305+#define PCH_GBE_MIN_TXD 8306306+#define PCH_GBE_MAX_RXD 4096307307+#define PCH_GBE_DEFAULT_RXD 256308308+#define PCH_GBE_MIN_RXD 8309309+310310+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */311311+#define PCH_GBE_TX_DESC_MULTIPLE 8312312+#define PCH_GBE_RX_DESC_MULTIPLE 8313313+314314+/* Read/Write operation is done through MII Management IF */315315+#define PCH_GBE_HAL_MIIM_READ ((u32)0x00000000)316316+#define PCH_GBE_HAL_MIIM_WRITE ((u32)0x04000000)317317+318318+/* flow control values */319319+#define PCH_GBE_FC_NONE 0320320+#define PCH_GBE_FC_RX_PAUSE 1321321+#define PCH_GBE_FC_TX_PAUSE 2322322+#define PCH_GBE_FC_FULL 3323323+#define PCH_GBE_FC_DEFAULT PCH_GBE_FC_FULL324324+325325+326326+struct pch_gbe_hw;327327+/**328328+ * struct pch_gbe_functions - HAL APi function pointer329329+ * @get_bus_info: for pch_gbe_hal_get_bus_info330330+ * @init_hw: for pch_gbe_hal_init_hw331331+ * @read_phy_reg: for pch_gbe_hal_read_phy_reg332332+ * @write_phy_reg: for pch_gbe_hal_write_phy_reg333333+ * @reset_phy: for pch_gbe_hal_phy_hw_reset334334+ * @sw_reset_phy: for pch_gbe_hal_phy_sw_reset335335+ * @power_up_phy: for pch_gbe_hal_power_up_phy336336+ * @power_down_phy: for pch_gbe_hal_power_down_phy337337+ * @read_mac_addr: for pch_gbe_hal_read_mac_addr338338+ */339339+struct pch_gbe_functions {340340+ void (*get_bus_info) (struct pch_gbe_hw *);341341+ s32 (*init_hw) (struct pch_gbe_hw *);342342+ s32 (*read_phy_reg) (struct pch_gbe_hw *, u32, u16 *);343343+ s32 (*write_phy_reg) (struct pch_gbe_hw *, u32, u16);344344+ void (*reset_phy) (struct pch_gbe_hw *);345345+ void (*sw_reset_phy) (struct pch_gbe_hw *);346346+ void (*power_up_phy) (struct pch_gbe_hw *hw);347347+ void (*power_down_phy) (struct pch_gbe_hw *hw);348348+ s32 (*read_mac_addr) (struct pch_gbe_hw *);349349+};350350+351351+/**352352+ * struct pch_gbe_mac_info - MAC infomation353353+ * @addr[6]: Store the MAC address354354+ * @fc: Mode of flow control355355+ * @fc_autoneg: Auto negotiation enable for flow control setting356356+ * @tx_fc_enable: Enable flag of Transmit flow control357357+ * @max_frame_size: Max transmit frame size358358+ * @min_frame_size: Min transmit frame size359359+ * @autoneg: Auto negotiation enable360360+ * @link_speed: Link speed361361+ * @link_duplex: Link duplex362362+ */363363+struct pch_gbe_mac_info {364364+ u8 addr[6];365365+ u8 fc;366366+ u8 fc_autoneg;367367+ u8 tx_fc_enable;368368+ u32 max_frame_size;369369+ u32 min_frame_size;370370+ u8 autoneg;371371+ u16 link_speed;372372+ u16 link_duplex;373373+};374374+375375+/**376376+ * struct pch_gbe_phy_info - PHY infomation377377+ * @addr: PHY address378378+ * @id: PHY's identifier379379+ * @revision: PHY's revision380380+ * @reset_delay_us: HW reset delay time[us]381381+ * @autoneg_advertised: Autoneg advertised382382+ */383383+struct pch_gbe_phy_info {384384+ u32 addr;385385+ u32 id;386386+ u32 revision;387387+ u32 reset_delay_us;388388+ u16 autoneg_advertised;389389+};390390+391391+/*!392392+ * @ingroup Gigabit Ether driver Layer393393+ * @struct pch_gbe_bus_info394394+ * @brief Bus infomation395395+ */396396+struct pch_gbe_bus_info {397397+ u8 type;398398+ u8 speed;399399+ u8 width;400400+};401401+402402+/*!403403+ * @ingroup Gigabit Ether driver Layer404404+ * @struct pch_gbe_hw405405+ * @brief Hardware infomation406406+ */407407+struct pch_gbe_hw {408408+ void *back;409409+410410+ struct pch_gbe_regs __iomem *reg;411411+ spinlock_t miim_lock;412412+413413+ const struct pch_gbe_functions *func;414414+ struct pch_gbe_mac_info mac;415415+ struct pch_gbe_phy_info phy;416416+ struct pch_gbe_bus_info bus;417417+};418418+419419+/**420420+ * struct pch_gbe_rx_desc - Receive Descriptor421421+ * @buffer_addr: RX Frame Buffer Address422422+ * @tcp_ip_status: TCP/IP Accelerator Status423423+ * @rx_words_eob: RX word count and Byte position424424+ * @gbec_status: GMAC Status425425+ * @dma_status: DMA Status426426+ * @reserved1: Reserved427427+ * @reserved2: Reserved428428+ */429429+struct pch_gbe_rx_desc {430430+ u32 buffer_addr;431431+ u32 tcp_ip_status;432432+ u16 rx_words_eob;433433+ u16 gbec_status;434434+ u8 dma_status;435435+ u8 reserved1;436436+ u16 reserved2;437437+};438438+439439+/**440440+ * struct pch_gbe_tx_desc - Transmit Descriptor441441+ * @buffer_addr: TX Frame Buffer Address442442+ * @length: Data buffer length443443+ * @reserved1: Reserved444444+ * @tx_words_eob: TX word count and Byte position445445+ * @tx_frame_ctrl: TX Frame Control446446+ * @dma_status: DMA Status447447+ * @reserved2: Reserved448448+ * @gbec_status: GMAC Status449449+ */450450+struct pch_gbe_tx_desc {451451+ u32 buffer_addr;452452+ u16 length;453453+ u16 reserved1;454454+ u16 tx_words_eob;455455+ u16 tx_frame_ctrl;456456+ u8 dma_status;457457+ u8 reserved2;458458+ u16 gbec_status;459459+};460460+461461+462462+/**463463+ * struct pch_gbe_buffer - Buffer infomation464464+ * @skb: pointer to a socket buffer465465+ * @dma: DMA address466466+ * @time_stamp: time stamp467467+ * @length: data size468468+ */469469+struct pch_gbe_buffer {470470+ struct sk_buff *skb;471471+ dma_addr_t dma;472472+ unsigned long time_stamp;473473+ u16 length;474474+ bool mapped;475475+};476476+477477+/**478478+ * struct pch_gbe_tx_ring - tx ring infomation479479+ * @tx_lock: spinlock structs480480+ * @desc: pointer to the descriptor ring memory481481+ * @dma: physical address of the descriptor ring482482+ * @size: length of descriptor ring in bytes483483+ * @count: number of descriptors in the ring484484+ * @next_to_use: next descriptor to associate a buffer with485485+ * @next_to_clean: next descriptor to check for DD status bit486486+ * @buffer_info: array of buffer information structs487487+ */488488+struct pch_gbe_tx_ring {489489+ spinlock_t tx_lock;490490+ struct pch_gbe_tx_desc *desc;491491+ dma_addr_t dma;492492+ unsigned int size;493493+ unsigned int count;494494+ unsigned int next_to_use;495495+ unsigned int next_to_clean;496496+ struct pch_gbe_buffer *buffer_info;497497+};498498+499499+/**500500+ * struct pch_gbe_rx_ring - rx ring infomation501501+ * @desc: pointer to the descriptor ring memory502502+ * @dma: physical address of the descriptor ring503503+ * @size: length of descriptor ring in bytes504504+ * @count: number of descriptors in the ring505505+ * @next_to_use: next descriptor to associate a buffer with506506+ * @next_to_clean: next descriptor to check for DD status bit507507+ * @buffer_info: array of buffer information structs508508+ */509509+struct pch_gbe_rx_ring {510510+ struct pch_gbe_rx_desc *desc;511511+ dma_addr_t dma;512512+ unsigned int size;513513+ unsigned int count;514514+ unsigned int next_to_use;515515+ unsigned int next_to_clean;516516+ struct pch_gbe_buffer *buffer_info;517517+};518518+519519+/**520520+ * struct pch_gbe_hw_stats - Statistics counters collected by the MAC521521+ * @rx_packets: total packets received522522+ * @tx_packets: total packets transmitted523523+ * @rx_bytes: total bytes received524524+ * @tx_bytes: total bytes transmitted525525+ * @rx_errors: bad packets received526526+ * @tx_errors: packet transmit problems527527+ * @rx_dropped: no space in Linux buffers528528+ * @tx_dropped: no space available in Linux529529+ * @multicast: multicast packets received530530+ * @collisions: collisions531531+ * @rx_crc_errors: received packet with crc error532532+ * @rx_frame_errors: received frame alignment error533533+ * @rx_alloc_buff_failed: allocate failure of a receive buffer534534+ * @tx_length_errors: transmit length error535535+ * @tx_aborted_errors: transmit aborted error536536+ * @tx_carrier_errors: transmit carrier error537537+ * @tx_timeout_count: Number of transmit timeout538538+ * @tx_restart_count: Number of transmit restert539539+ * @intr_rx_dsc_empty_count: Interrupt count of receive descriptor empty540540+ * @intr_rx_frame_err_count: Interrupt count of receive frame error541541+ * @intr_rx_fifo_err_count: Interrupt count of receive FIFO error542542+ * @intr_rx_dma_err_count: Interrupt count of receive DMA error543543+ * @intr_tx_fifo_err_count: Interrupt count of transmit FIFO error544544+ * @intr_tx_dma_err_count: Interrupt count of transmit DMA error545545+ * @intr_tcpip_err_count: Interrupt count of TCP/IP Accelerator546546+ */547547+struct pch_gbe_hw_stats {548548+ u32 rx_packets;549549+ u32 tx_packets;550550+ u32 rx_bytes;551551+ u32 tx_bytes;552552+ u32 rx_errors;553553+ u32 tx_errors;554554+ u32 rx_dropped;555555+ u32 tx_dropped;556556+ u32 multicast;557557+ u32 collisions;558558+ u32 rx_crc_errors;559559+ u32 rx_frame_errors;560560+ u32 rx_alloc_buff_failed;561561+ u32 tx_length_errors;562562+ u32 tx_aborted_errors;563563+ u32 tx_carrier_errors;564564+ u32 tx_timeout_count;565565+ u32 tx_restart_count;566566+ u32 intr_rx_dsc_empty_count;567567+ u32 intr_rx_frame_err_count;568568+ u32 intr_rx_fifo_err_count;569569+ u32 intr_rx_dma_err_count;570570+ u32 intr_tx_fifo_err_count;571571+ u32 intr_tx_dma_err_count;572572+ u32 intr_tcpip_err_count;573573+};574574+575575+/**576576+ * struct pch_gbe_adapter - board specific private data structure577577+ * @stats_lock: Spinlock structure for status578578+ * @tx_queue_lock: Spinlock structure for transmit579579+ * @ethtool_lock: Spinlock structure for ethtool580580+ * @irq_sem: Semaphore for interrupt581581+ * @netdev: Pointer of network device structure582582+ * @pdev: Pointer of pci device structure583583+ * @polling_netdev: Pointer of polling network device structure584584+ * @napi: NAPI structure585585+ * @hw: Pointer of hardware structure586586+ * @stats: Hardware status587587+ * @reset_task: Reset task588588+ * @mii: MII information structure589589+ * @watchdog_timer: Watchdog timer list590590+ * @wake_up_evt: Wake up event591591+ * @config_space: Configuration space592592+ * @msg_enable: Driver message level593593+ * @led_status: LED status594594+ * @tx_ring: Pointer of Tx descriptor ring structure595595+ * @rx_ring: Pointer of Rx descriptor ring structure596596+ * @rx_buffer_len: Receive buffer length597597+ * @tx_queue_len: Transmit queue length598598+ * @rx_csum: Receive TCP/IP checksum enable/disable599599+ * @tx_csum: Transmit TCP/IP checksum enable/disable600600+ * @have_msi: PCI MSI mode flag601601+ */602602+603603+struct pch_gbe_adapter {604604+ spinlock_t stats_lock;605605+ spinlock_t tx_queue_lock;606606+ spinlock_t ethtool_lock;607607+ atomic_t irq_sem;608608+ struct net_device *netdev;609609+ struct pci_dev *pdev;610610+ struct net_device *polling_netdev;611611+ struct napi_struct napi;612612+ struct pch_gbe_hw hw;613613+ struct pch_gbe_hw_stats stats;614614+ struct work_struct reset_task;615615+ struct mii_if_info mii;616616+ struct timer_list watchdog_timer;617617+ u32 wake_up_evt;618618+ u32 *config_space;619619+ unsigned long led_status;620620+ struct pch_gbe_tx_ring *tx_ring;621621+ struct pch_gbe_rx_ring *rx_ring;622622+ unsigned long rx_buffer_len;623623+ unsigned long tx_queue_len;624624+ bool rx_csum;625625+ bool tx_csum;626626+ bool have_msi;627627+};628628+629629+extern const char pch_driver_version[];630630+631631+/* pch_gbe_main.c */632632+extern int pch_gbe_up(struct pch_gbe_adapter *adapter);633633+extern void pch_gbe_down(struct pch_gbe_adapter *adapter);634634+extern void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter);635635+extern void pch_gbe_reset(struct pch_gbe_adapter *adapter);636636+extern int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,637637+ struct pch_gbe_tx_ring *txdr);638638+extern int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter,639639+ struct pch_gbe_rx_ring *rxdr);640640+extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter,641641+ struct pch_gbe_tx_ring *tx_ring);642642+extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter,643643+ struct pch_gbe_rx_ring *rx_ring);644644+extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter);645645+extern int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg);646646+extern void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg,647647+ int data);648648+/* pch_gbe_param.c */649649+extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter);650650+651651+/* pch_gbe_ethtool.c */652652+extern void pch_gbe_set_ethtool_ops(struct net_device *netdev);653653+654654+/* pch_gbe_mac.c */655655+extern s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw);656656+extern s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw);657657+extern u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw,658658+ u32 addr, u32 dir, u32 reg, u16 data);659659+#endif /* _PCH_GBE_H_ */
+245
drivers/net/pch_gbe/pch_gbe_api.c
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+#include "pch_gbe.h"2121+#include "pch_gbe_phy.h"2222+2323+/* bus type values */2424+#define pch_gbe_bus_type_unknown 02525+#define pch_gbe_bus_type_pci 12626+#define pch_gbe_bus_type_pcix 22727+#define pch_gbe_bus_type_pci_express 32828+#define pch_gbe_bus_type_reserved 42929+3030+/* bus speed values */3131+#define pch_gbe_bus_speed_unknown 03232+#define pch_gbe_bus_speed_33 13333+#define pch_gbe_bus_speed_66 23434+#define pch_gbe_bus_speed_100 33535+#define pch_gbe_bus_speed_120 43636+#define pch_gbe_bus_speed_133 53737+#define pch_gbe_bus_speed_2500 63838+#define pch_gbe_bus_speed_reserved 73939+4040+/* bus width values */4141+#define pch_gbe_bus_width_unknown 04242+#define pch_gbe_bus_width_pcie_x1 14343+#define pch_gbe_bus_width_pcie_x2 24444+#define pch_gbe_bus_width_pcie_x4 44545+#define pch_gbe_bus_width_32 54646+#define pch_gbe_bus_width_64 64747+#define pch_gbe_bus_width_reserved 74848+4949+/**5050+ * pch_gbe_plat_get_bus_info - Obtain bus information for adapter5151+ * @hw: Pointer to the HW structure5252+ */5353+static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw)5454+{5555+ hw->bus.type = pch_gbe_bus_type_pci_express;5656+ hw->bus.speed = pch_gbe_bus_speed_2500;5757+ hw->bus.width = pch_gbe_bus_width_pcie_x1;5858+}5959+6060+/**6161+ * pch_gbe_plat_init_hw - Initialize hardware6262+ * @hw: Pointer to the HW structure6363+ * Returns6464+ * 0: Successfully6565+ * Negative value: Failed-EBUSY6666+ */6767+static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw)6868+{6969+ s32 ret_val;7070+7171+ ret_val = pch_gbe_phy_get_id(hw);7272+ if (ret_val) {7373+ pr_err("pch_gbe_phy_get_id error\n");7474+ return ret_val;7575+ }7676+ pch_gbe_phy_init_setting(hw);7777+ /* Setup Mac interface option RGMII */7878+#ifdef PCH_GBE_MAC_IFOP_RGMII7979+ pch_gbe_phy_set_rgmii(hw);8080+#endif8181+ return ret_val;8282+}8383+8484+static const struct pch_gbe_functions pch_gbe_ops = {8585+ .get_bus_info = pch_gbe_plat_get_bus_info,8686+ .init_hw = pch_gbe_plat_init_hw,8787+ .read_phy_reg = pch_gbe_phy_read_reg_miic,8888+ .write_phy_reg = pch_gbe_phy_write_reg_miic,8989+ .reset_phy = pch_gbe_phy_hw_reset,9090+ .sw_reset_phy = pch_gbe_phy_sw_reset,9191+ .power_up_phy = pch_gbe_phy_power_up,9292+ .power_down_phy = pch_gbe_phy_power_down,9393+ .read_mac_addr = pch_gbe_mac_read_mac_addr9494+};9595+9696+/**9797+ * pch_gbe_plat_init_function_pointers - Init func ptrs9898+ * @hw: Pointer to the HW structure9999+ */100100+void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw)101101+{102102+ /* Set PHY parameter */103103+ hw->phy.reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US;104104+ /* Set function pointers */105105+ hw->func = &pch_gbe_ops;106106+}107107+108108+/**109109+ * pch_gbe_hal_setup_init_funcs - Initializes function pointers110110+ * @hw: Pointer to the HW structure111111+ * Returns112112+ * 0: Successfully113113+ * ENOSYS: Function is not registered114114+ */115115+inline s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)116116+{117117+ if (!hw->reg) {118118+ pr_err("ERROR: Registers not mapped\n");119119+ return -ENOSYS;120120+ }121121+ pch_gbe_plat_init_function_pointers(hw);122122+ return 0;123123+}124124+125125+/**126126+ * pch_gbe_hal_get_bus_info - Obtain bus information for adapter127127+ * @hw: Pointer to the HW structure128128+ */129129+inline void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)130130+{131131+ if (!hw->func->get_bus_info)132132+ pr_err("ERROR: configuration\n");133133+ else134134+ hw->func->get_bus_info(hw);135135+}136136+137137+/**138138+ * pch_gbe_hal_init_hw - Initialize hardware139139+ * @hw: Pointer to the HW structure140140+ * Returns141141+ * 0: Successfully142142+ * ENOSYS: Function is not registered143143+ */144144+inline s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)145145+{146146+ if (!hw->func->init_hw) {147147+ pr_err("ERROR: configuration\n");148148+ return -ENOSYS;149149+ }150150+ return hw->func->init_hw(hw);151151+}152152+153153+/**154154+ * pch_gbe_hal_read_phy_reg - Reads PHY register155155+ * @hw: Pointer to the HW structure156156+ * @offset: The register to read157157+ * @data: The buffer to store the 16-bit read.158158+ * Returns159159+ * 0: Successfully160160+ * Negative value: Failed161161+ */162162+inline s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset,163163+ u16 *data)164164+{165165+ if (!hw->func->read_phy_reg)166166+ return 0;167167+ return hw->func->read_phy_reg(hw, offset, data);168168+}169169+170170+/**171171+ * pch_gbe_hal_write_phy_reg - Writes PHY register172172+ * @hw: Pointer to the HW structure173173+ * @offset: The register to read174174+ * @data: The value to write.175175+ * Returns176176+ * 0: Successfully177177+ * Negative value: Failed178178+ */179179+inline s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset,180180+ u16 data)181181+{182182+ if (!hw->func->write_phy_reg)183183+ return 0;184184+ return hw->func->write_phy_reg(hw, offset, data);185185+}186186+187187+/**188188+ * pch_gbe_hal_phy_hw_reset - Hard PHY reset189189+ * @hw: Pointer to the HW structure190190+ */191191+inline void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)192192+{193193+ if (!hw->func->reset_phy)194194+ pr_err("ERROR: configuration\n");195195+ else196196+ hw->func->reset_phy(hw);197197+}198198+199199+/**200200+ * pch_gbe_hal_phy_sw_reset - Soft PHY reset201201+ * @hw: Pointer to the HW structure202202+ */203203+inline void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)204204+{205205+ if (!hw->func->sw_reset_phy)206206+ pr_err("ERROR: configuration\n");207207+ else208208+ hw->func->sw_reset_phy(hw);209209+}210210+211211+/**212212+ * pch_gbe_hal_read_mac_addr - Reads MAC address213213+ * @hw: Pointer to the HW structure214214+ * Returns215215+ * 0: Successfully216216+ * ENOSYS: Function is not registered217217+ */218218+inline s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)219219+{220220+ if (!hw->func->read_mac_addr) {221221+ pr_err("ERROR: configuration\n");222222+ return -ENOSYS;223223+ }224224+ return hw->func->read_mac_addr(hw);225225+}226226+227227+/**228228+ * pch_gbe_hal_power_up_phy - Power up PHY229229+ * @hw: Pointer to the HW structure230230+ */231231+inline void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)232232+{233233+ if (hw->func->power_up_phy)234234+ hw->func->power_up_phy(hw);235235+}236236+237237+/**238238+ * pch_gbe_hal_power_down_phy - Power down PHY239239+ * @hw: Pointer to the HW structure240240+ */241241+inline void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)242242+{243243+ if (hw->func->power_down_phy)244244+ hw->func->power_down_phy(hw);245245+}
+36
drivers/net/pch_gbe/pch_gbe_api.h
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+#ifndef _PCH_GBE_API_H_2121+#define _PCH_GBE_API_H_2222+2323+#include "pch_gbe_phy.h"2424+2525+s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw);2626+void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw);2727+s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw);2828+s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 *data);2929+s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 data);3030+void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw);3131+void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw);3232+s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw);3333+void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw);3434+void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw);3535+3636+#endif
+584
drivers/net/pch_gbe/pch_gbe_ethtool.c
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+#include "pch_gbe.h"2121+#include "pch_gbe_api.h"2222+2323+/**2424+ * pch_gbe_stats - Stats item infomation2525+ */2626+struct pch_gbe_stats {2727+ char string[ETH_GSTRING_LEN];2828+ size_t size;2929+ size_t offset;3030+};3131+3232+#define PCH_GBE_STAT(m) \3333+{ \3434+ .string = #m, \3535+ .size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m), \3636+ .offset = offsetof(struct pch_gbe_hw_stats, m), \3737+}3838+3939+/**4040+ * pch_gbe_gstrings_stats - ethtool information status name list4141+ */4242+static const struct pch_gbe_stats pch_gbe_gstrings_stats[] = {4343+ PCH_GBE_STAT(rx_packets),4444+ PCH_GBE_STAT(tx_packets),4545+ PCH_GBE_STAT(rx_bytes),4646+ PCH_GBE_STAT(tx_bytes),4747+ PCH_GBE_STAT(rx_errors),4848+ PCH_GBE_STAT(tx_errors),4949+ PCH_GBE_STAT(rx_dropped),5050+ PCH_GBE_STAT(tx_dropped),5151+ PCH_GBE_STAT(multicast),5252+ PCH_GBE_STAT(collisions),5353+ PCH_GBE_STAT(rx_crc_errors),5454+ PCH_GBE_STAT(rx_frame_errors),5555+ PCH_GBE_STAT(rx_alloc_buff_failed),5656+ PCH_GBE_STAT(tx_length_errors),5757+ PCH_GBE_STAT(tx_aborted_errors),5858+ PCH_GBE_STAT(tx_carrier_errors),5959+ PCH_GBE_STAT(tx_timeout_count),6060+ PCH_GBE_STAT(tx_restart_count),6161+ PCH_GBE_STAT(intr_rx_dsc_empty_count),6262+ PCH_GBE_STAT(intr_rx_frame_err_count),6363+ PCH_GBE_STAT(intr_rx_fifo_err_count),6464+ PCH_GBE_STAT(intr_rx_dma_err_count),6565+ PCH_GBE_STAT(intr_tx_fifo_err_count),6666+ PCH_GBE_STAT(intr_tx_dma_err_count),6767+ PCH_GBE_STAT(intr_tcpip_err_count)6868+};6969+7070+#define PCH_GBE_QUEUE_STATS_LEN 07171+#define PCH_GBE_GLOBAL_STATS_LEN ARRAY_SIZE(pch_gbe_gstrings_stats)7272+#define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN)7373+7474+#define PCH_GBE_MAC_REGS_LEN (sizeof(struct pch_gbe_regs) / 4)7575+#define PCH_GBE_REGS_LEN (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN)7676+/**7777+ * pch_gbe_get_settings - Get device-specific settings7878+ * @netdev: Network interface device structure7979+ * @ecmd: Ethtool command8080+ * Returns8181+ * 0: Successful.8282+ * Negative value: Failed.8383+ */8484+static int pch_gbe_get_settings(struct net_device *netdev,8585+ struct ethtool_cmd *ecmd)8686+{8787+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);8888+ int ret;8989+9090+ ret = mii_ethtool_gset(&adapter->mii, ecmd);9191+ ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half);9292+ ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);9393+9494+ if (!netif_carrier_ok(adapter->netdev))9595+ ecmd->speed = -1;9696+ return ret;9797+}9898+9999+/**100100+ * pch_gbe_set_settings - Set device-specific settings101101+ * @netdev: Network interface device structure102102+ * @ecmd: Ethtool command103103+ * Returns104104+ * 0: Successful.105105+ * Negative value: Failed.106106+ */107107+static int pch_gbe_set_settings(struct net_device *netdev,108108+ struct ethtool_cmd *ecmd)109109+{110110+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);111111+ struct pch_gbe_hw *hw = &adapter->hw;112112+ int ret;113113+114114+ pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);115115+116116+ if (ecmd->speed == -1)117117+ ecmd->speed = SPEED_1000;118118+ ecmd->duplex = DUPLEX_FULL;119119+ ret = mii_ethtool_sset(&adapter->mii, ecmd);120120+ if (ret) {121121+ pr_err("Error: mii_ethtool_sset\n");122122+ return ret;123123+ }124124+ hw->mac.link_speed = ecmd->speed;125125+ hw->mac.link_duplex = ecmd->duplex;126126+ hw->phy.autoneg_advertised = ecmd->advertising;127127+ hw->mac.autoneg = ecmd->autoneg;128128+ pch_gbe_hal_phy_sw_reset(hw);129129+130130+ /* reset the link */131131+ if (netif_running(adapter->netdev)) {132132+ pch_gbe_down(adapter);133133+ ret = pch_gbe_up(adapter);134134+ } else {135135+ pch_gbe_reset(adapter);136136+ }137137+ return ret;138138+}139139+140140+/**141141+ * pch_gbe_get_regs_len - Report the size of device registers142142+ * @netdev: Network interface device structure143143+ * Returns: the size of device registers.144144+ */145145+static int pch_gbe_get_regs_len(struct net_device *netdev)146146+{147147+ return PCH_GBE_REGS_LEN * (int)sizeof(u32);148148+}149149+150150+/**151151+ * pch_gbe_get_drvinfo - Report driver information152152+ * @netdev: Network interface device structure153153+ * @drvinfo: Driver information structure154154+ */155155+static void pch_gbe_get_drvinfo(struct net_device *netdev,156156+ struct ethtool_drvinfo *drvinfo)157157+{158158+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);159159+160160+ strcpy(drvinfo->driver, KBUILD_MODNAME);161161+ strcpy(drvinfo->version, pch_driver_version);162162+ strcpy(drvinfo->fw_version, "N/A");163163+ strcpy(drvinfo->bus_info, pci_name(adapter->pdev));164164+ drvinfo->regdump_len = pch_gbe_get_regs_len(netdev);165165+}166166+167167+/**168168+ * pch_gbe_get_regs - Get device registers169169+ * @netdev: Network interface device structure170170+ * @regs: Ethtool register structure171171+ * @p: Buffer pointer of read device register date172172+ */173173+static void pch_gbe_get_regs(struct net_device *netdev,174174+ struct ethtool_regs *regs, void *p)175175+{176176+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);177177+ struct pch_gbe_hw *hw = &adapter->hw;178178+ struct pci_dev *pdev = adapter->pdev;179179+ u32 *regs_buff = p;180180+ u16 i, tmp;181181+182182+ regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device;183183+ for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++)184184+ *regs_buff++ = ioread32(&hw->reg->INT_ST + i);185185+ /* PHY register */186186+ for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) {187187+ pch_gbe_hal_read_phy_reg(&adapter->hw, i, &tmp);188188+ *regs_buff++ = tmp;189189+ }190190+}191191+192192+/**193193+ * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled194194+ * @netdev: Network interface device structure195195+ * @wol: Wake-on-Lan information196196+ */197197+static void pch_gbe_get_wol(struct net_device *netdev,198198+ struct ethtool_wolinfo *wol)199199+{200200+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);201201+202202+ wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;203203+ wol->wolopts = 0;204204+205205+ if ((adapter->wake_up_evt & PCH_GBE_WLC_IND))206206+ wol->wolopts |= WAKE_UCAST;207207+ if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT))208208+ wol->wolopts |= WAKE_MCAST;209209+ if ((adapter->wake_up_evt & PCH_GBE_WLC_BR))210210+ wol->wolopts |= WAKE_BCAST;211211+ if ((adapter->wake_up_evt & PCH_GBE_WLC_MP))212212+ wol->wolopts |= WAKE_MAGIC;213213+}214214+215215+/**216216+ * pch_gbe_set_wol - Turn Wake-on-Lan on or off217217+ * @netdev: Network interface device structure218218+ * @wol: Pointer of wake-on-Lan information straucture219219+ * Returns220220+ * 0: Successful.221221+ * Negative value: Failed.222222+ */223223+static int pch_gbe_set_wol(struct net_device *netdev,224224+ struct ethtool_wolinfo *wol)225225+{226226+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);227227+228228+ if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)))229229+ return -EOPNOTSUPP;230230+ /* these settings will always override what we currently have */231231+ adapter->wake_up_evt = 0;232232+233233+ if ((wol->wolopts & WAKE_UCAST))234234+ adapter->wake_up_evt |= PCH_GBE_WLC_IND;235235+ if ((wol->wolopts & WAKE_MCAST))236236+ adapter->wake_up_evt |= PCH_GBE_WLC_MLT;237237+ if ((wol->wolopts & WAKE_BCAST))238238+ adapter->wake_up_evt |= PCH_GBE_WLC_BR;239239+ if ((wol->wolopts & WAKE_MAGIC))240240+ adapter->wake_up_evt |= PCH_GBE_WLC_MP;241241+ return 0;242242+}243243+244244+/**245245+ * pch_gbe_nway_reset - Restart autonegotiation246246+ * @netdev: Network interface device structure247247+ * Returns248248+ * 0: Successful.249249+ * Negative value: Failed.250250+ */251251+static int pch_gbe_nway_reset(struct net_device *netdev)252252+{253253+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);254254+255255+ return mii_nway_restart(&adapter->mii);256256+}257257+258258+/**259259+ * pch_gbe_get_ringparam - Report ring sizes260260+ * @netdev: Network interface device structure261261+ * @ring: Ring param structure262262+ */263263+static void pch_gbe_get_ringparam(struct net_device *netdev,264264+ struct ethtool_ringparam *ring)265265+{266266+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);267267+ struct pch_gbe_tx_ring *txdr = adapter->tx_ring;268268+ struct pch_gbe_rx_ring *rxdr = adapter->rx_ring;269269+270270+ ring->rx_max_pending = PCH_GBE_MAX_RXD;271271+ ring->tx_max_pending = PCH_GBE_MAX_TXD;272272+ ring->rx_mini_max_pending = 0;273273+ ring->rx_jumbo_max_pending = 0;274274+ ring->rx_pending = rxdr->count;275275+ ring->tx_pending = txdr->count;276276+ ring->rx_mini_pending = 0;277277+ ring->rx_jumbo_pending = 0;278278+}279279+280280+/**281281+ * pch_gbe_set_ringparam - Set ring sizes282282+ * @netdev: Network interface device structure283283+ * @ring: Ring param structure284284+ * Returns285285+ * 0: Successful.286286+ * Negative value: Failed.287287+ */288288+static int pch_gbe_set_ringparam(struct net_device *netdev,289289+ struct ethtool_ringparam *ring)290290+{291291+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);292292+ struct pch_gbe_tx_ring *txdr, *tx_old;293293+ struct pch_gbe_rx_ring *rxdr, *rx_old;294294+ int tx_ring_size, rx_ring_size;295295+ int err = 0;296296+297297+ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))298298+ return -EINVAL;299299+ tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring);300300+ rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring);301301+302302+ if ((netif_running(adapter->netdev)))303303+ pch_gbe_down(adapter);304304+ tx_old = adapter->tx_ring;305305+ rx_old = adapter->rx_ring;306306+307307+ txdr = kzalloc(tx_ring_size, GFP_KERNEL);308308+ if (!txdr) {309309+ err = -ENOMEM;310310+ goto err_alloc_tx;311311+ }312312+ rxdr = kzalloc(rx_ring_size, GFP_KERNEL);313313+ if (!rxdr) {314314+ err = -ENOMEM;315315+ goto err_alloc_rx;316316+ }317317+ adapter->tx_ring = txdr;318318+ adapter->rx_ring = rxdr;319319+320320+ rxdr->count =321321+ clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);322322+ rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE);323323+324324+ txdr->count =325325+ clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);326326+ txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE);327327+328328+ if ((netif_running(adapter->netdev))) {329329+ /* Try to get new resources before deleting old */330330+ err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);331331+ if (err)332332+ goto err_setup_rx;333333+ err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);334334+ if (err)335335+ goto err_setup_tx;336336+ /* save the new, restore the old in order to free it,337337+ * then restore the new back again */338338+#ifdef RINGFREE339339+ adapter->rx_ring = rx_old;340340+ adapter->tx_ring = tx_old;341341+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);342342+ pch_gbe_free_tx_resources(adapter, adapter->tx_ring);343343+ kfree(tx_old);344344+ kfree(rx_old);345345+ adapter->rx_ring = rxdr;346346+ adapter->tx_ring = txdr;347347+#else348348+ pch_gbe_free_rx_resources(adapter, rx_old);349349+ pch_gbe_free_tx_resources(adapter, tx_old);350350+ kfree(tx_old);351351+ kfree(rx_old);352352+ adapter->rx_ring = rxdr;353353+ adapter->tx_ring = txdr;354354+#endif355355+ err = pch_gbe_up(adapter);356356+ }357357+ return err;358358+359359+err_setup_tx:360360+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);361361+err_setup_rx:362362+ adapter->rx_ring = rx_old;363363+ adapter->tx_ring = tx_old;364364+ kfree(rxdr);365365+err_alloc_rx:366366+ kfree(txdr);367367+err_alloc_tx:368368+ if (netif_running(adapter->netdev))369369+ pch_gbe_up(adapter);370370+ return err;371371+}372372+373373+/**374374+ * pch_gbe_get_pauseparam - Report pause parameters375375+ * @netdev: Network interface device structure376376+ * @pause: Pause parameters structure377377+ */378378+static void pch_gbe_get_pauseparam(struct net_device *netdev,379379+ struct ethtool_pauseparam *pause)380380+{381381+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);382382+ struct pch_gbe_hw *hw = &adapter->hw;383383+384384+ pause->autoneg =385385+ ((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE);386386+387387+ if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) {388388+ pause->rx_pause = 1;389389+ } else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) {390390+ pause->tx_pause = 1;391391+ } else if (hw->mac.fc == PCH_GBE_FC_FULL) {392392+ pause->rx_pause = 1;393393+ pause->tx_pause = 1;394394+ }395395+}396396+397397+/**398398+ * pch_gbe_set_pauseparam - Set pause paramters399399+ * @netdev: Network interface device structure400400+ * @pause: Pause parameters structure401401+ * Returns402402+ * 0: Successful.403403+ * Negative value: Failed.404404+ */405405+static int pch_gbe_set_pauseparam(struct net_device *netdev,406406+ struct ethtool_pauseparam *pause)407407+{408408+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);409409+ struct pch_gbe_hw *hw = &adapter->hw;410410+ int ret = 0;411411+412412+ hw->mac.fc_autoneg = pause->autoneg;413413+ if ((pause->rx_pause) && (pause->tx_pause))414414+ hw->mac.fc = PCH_GBE_FC_FULL;415415+ else if ((pause->rx_pause) && (!pause->tx_pause))416416+ hw->mac.fc = PCH_GBE_FC_RX_PAUSE;417417+ else if ((!pause->rx_pause) && (pause->tx_pause))418418+ hw->mac.fc = PCH_GBE_FC_TX_PAUSE;419419+ else if ((!pause->rx_pause) && (!pause->tx_pause))420420+ hw->mac.fc = PCH_GBE_FC_NONE;421421+422422+ if (hw->mac.fc_autoneg == AUTONEG_ENABLE) {423423+ if ((netif_running(adapter->netdev))) {424424+ pch_gbe_down(adapter);425425+ ret = pch_gbe_up(adapter);426426+ } else {427427+ pch_gbe_reset(adapter);428428+ }429429+ } else {430430+ ret = pch_gbe_mac_force_mac_fc(hw);431431+ }432432+ return ret;433433+}434434+435435+/**436436+ * pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off437437+ * @netdev: Network interface device structure438438+ * Returns439439+ * true(1): Checksum On440440+ * false(0): Checksum Off441441+ */442442+static u32 pch_gbe_get_rx_csum(struct net_device *netdev)443443+{444444+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);445445+446446+ return adapter->rx_csum;447447+}448448+449449+/**450450+ * pch_gbe_set_rx_csum - Turn receive checksum on or off451451+ * @netdev: Network interface device structure452452+ * @data: Checksum On[true] or Off[false]453453+ * Returns454454+ * 0: Successful.455455+ * Negative value: Failed.456456+ */457457+static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)458458+{459459+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);460460+461461+ adapter->rx_csum = data;462462+ if ((netif_running(netdev)))463463+ pch_gbe_reinit_locked(adapter);464464+ else465465+ pch_gbe_reset(adapter);466466+467467+ return 0;468468+}469469+470470+/**471471+ * pch_gbe_get_tx_csum - Report whether transmit checksums are turned on or off472472+ * @netdev: Network interface device structure473473+ * Returns474474+ * true(1): Checksum On475475+ * false(0): Checksum Off476476+ */477477+static u32 pch_gbe_get_tx_csum(struct net_device *netdev)478478+{479479+ return (netdev->features & NETIF_F_HW_CSUM) != 0;480480+}481481+482482+/**483483+ * pch_gbe_set_tx_csum - Turn transmit checksums on or off484484+ * @netdev: Network interface device structure485485+ * @data: Checksum on[true] or off[false]486486+ * Returns487487+ * 0: Successful.488488+ * Negative value: Failed.489489+ */490490+static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)491491+{492492+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);493493+494494+ adapter->tx_csum = data;495495+ if (data)496496+ netdev->features |= NETIF_F_HW_CSUM;497497+ else498498+ netdev->features &= ~NETIF_F_HW_CSUM;499499+ return 0;500500+}501501+502502+/**503503+ * pch_gbe_get_strings - Return a set of strings that describe the requested504504+ * objects505505+ * @netdev: Network interface device structure506506+ * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]507507+ * @data: Pointer of read string data.508508+ */509509+static void pch_gbe_get_strings(struct net_device *netdev, u32 stringset,510510+ u8 *data)511511+{512512+ u8 *p = data;513513+ int i;514514+515515+ switch (stringset) {516516+ case (u32) ETH_SS_STATS:517517+ for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {518518+ memcpy(p, pch_gbe_gstrings_stats[i].string,519519+ ETH_GSTRING_LEN);520520+ p += ETH_GSTRING_LEN;521521+ }522522+ break;523523+ }524524+}525525+526526+/**527527+ * pch_gbe_get_ethtool_stats - Return statistics about the device528528+ * @netdev: Network interface device structure529529+ * @stats: Ethtool statue structure530530+ * @data: Pointer of read status area531531+ */532532+static void pch_gbe_get_ethtool_stats(struct net_device *netdev,533533+ struct ethtool_stats *stats, u64 *data)534534+{535535+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);536536+ int i;537537+ const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats;538538+ char *hw_stats = (char *)&adapter->stats;539539+540540+ pch_gbe_update_stats(adapter);541541+ for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {542542+ char *p = hw_stats + gstats->offset;543543+ data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p);544544+ gstats++;545545+ }546546+}547547+548548+static int pch_gbe_get_sset_count(struct net_device *netdev, int sset)549549+{550550+ switch (sset) {551551+ case ETH_SS_STATS:552552+ return PCH_GBE_STATS_LEN;553553+ default:554554+ return -EOPNOTSUPP;555555+ }556556+}557557+558558+static const struct ethtool_ops pch_gbe_ethtool_ops = {559559+ .get_settings = pch_gbe_get_settings,560560+ .set_settings = pch_gbe_set_settings,561561+ .get_drvinfo = pch_gbe_get_drvinfo,562562+ .get_regs_len = pch_gbe_get_regs_len,563563+ .get_regs = pch_gbe_get_regs,564564+ .get_wol = pch_gbe_get_wol,565565+ .set_wol = pch_gbe_set_wol,566566+ .nway_reset = pch_gbe_nway_reset,567567+ .get_link = ethtool_op_get_link,568568+ .get_ringparam = pch_gbe_get_ringparam,569569+ .set_ringparam = pch_gbe_set_ringparam,570570+ .get_pauseparam = pch_gbe_get_pauseparam,571571+ .set_pauseparam = pch_gbe_set_pauseparam,572572+ .get_rx_csum = pch_gbe_get_rx_csum,573573+ .set_rx_csum = pch_gbe_set_rx_csum,574574+ .get_tx_csum = pch_gbe_get_tx_csum,575575+ .set_tx_csum = pch_gbe_set_tx_csum,576576+ .get_strings = pch_gbe_get_strings,577577+ .get_ethtool_stats = pch_gbe_get_ethtool_stats,578578+ .get_sset_count = pch_gbe_get_sset_count,579579+};580580+581581+void pch_gbe_set_ethtool_ops(struct net_device *netdev)582582+{583583+ SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops);584584+}
+2473
drivers/net/pch_gbe/pch_gbe_main.c
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+2121+#include "pch_gbe.h"2222+#include "pch_gbe_api.h"2323+2424+#define DRV_VERSION "1.00"2525+const char pch_driver_version[] = DRV_VERSION;2626+2727+#define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */2828+#define PCH_GBE_MAR_ENTRIES 162929+#define PCH_GBE_SHORT_PKT 643030+#define DSC_INIT16 0xC0003131+#define PCH_GBE_DMA_ALIGN 03232+#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */3333+#define PCH_GBE_COPYBREAK_DEFAULT 2563434+#define PCH_GBE_PCI_BAR 13535+3636+#define PCH_GBE_TX_WEIGHT 643737+#define PCH_GBE_RX_WEIGHT 643838+#define PCH_GBE_RX_BUFFER_WRITE 163939+4040+/* Initialize the wake-on-LAN settings */4141+#define PCH_GBE_WL_INIT_SETTING (PCH_GBE_WLC_MP)4242+4343+#define PCH_GBE_MAC_RGMII_CTRL_SETTING ( \4444+ PCH_GBE_CHIP_TYPE_INTERNAL | \4545+ PCH_GBE_RGMII_MODE_RGMII | \4646+ PCH_GBE_CRS_SEL \4747+ )4848+4949+/* Ethertype field values */5050+#define PCH_GBE_MAX_JUMBO_FRAME_SIZE 103185151+#define PCH_GBE_FRAME_SIZE_2048 20485252+#define PCH_GBE_FRAME_SIZE_4096 40965353+#define PCH_GBE_FRAME_SIZE_8192 81925454+5555+#define PCH_GBE_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))5656+#define PCH_GBE_RX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_rx_desc)5757+#define PCH_GBE_TX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_tx_desc)5858+#define PCH_GBE_DESC_UNUSED(R) \5959+ ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \6060+ (R)->next_to_clean - (R)->next_to_use - 1)6161+6262+/* Pause packet value */6363+#define PCH_GBE_PAUSE_PKT1_VALUE 0x00C280016464+#define PCH_GBE_PAUSE_PKT2_VALUE 0x000001006565+#define PCH_GBE_PAUSE_PKT4_VALUE 0x010008886666+#define PCH_GBE_PAUSE_PKT5_VALUE 0x0000FFFF6767+6868+#define PCH_GBE_ETH_ALEN 66969+7070+/* This defines the bits that are set in the Interrupt Mask7171+ * Set/Read Register. Each bit is documented below:7272+ * o RXT0 = Receiver Timer Interrupt (ring 0)7373+ * o TXDW = Transmit Descriptor Written Back7474+ * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)7575+ * o RXSEQ = Receive Sequence Error7676+ * o LSC = Link Status Change7777+ */7878+#define PCH_GBE_INT_ENABLE_MASK ( \7979+ PCH_GBE_INT_RX_DMA_CMPLT | \8080+ PCH_GBE_INT_RX_DSC_EMP | \8181+ PCH_GBE_INT_WOL_DET | \8282+ PCH_GBE_INT_TX_CMPLT \8383+ )8484+8585+8686+static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT;8787+8888+/**8989+ * pch_gbe_mac_read_mac_addr - Read MAC address9090+ * @hw: Pointer to the HW structure9191+ * Returns9292+ * 0: Successful.9393+ */9494+s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw)9595+{9696+ u32 adr1a, adr1b;9797+9898+ adr1a = ioread32(&hw->reg->mac_adr[0].high);9999+ adr1b = ioread32(&hw->reg->mac_adr[0].low);100100+101101+ hw->mac.addr[0] = (u8)(adr1a & 0xFF);102102+ hw->mac.addr[1] = (u8)((adr1a >> 8) & 0xFF);103103+ hw->mac.addr[2] = (u8)((adr1a >> 16) & 0xFF);104104+ hw->mac.addr[3] = (u8)((adr1a >> 24) & 0xFF);105105+ hw->mac.addr[4] = (u8)(adr1b & 0xFF);106106+ hw->mac.addr[5] = (u8)((adr1b >> 8) & 0xFF);107107+108108+ pr_debug("hw->mac.addr : %pM\n", hw->mac.addr);109109+ return 0;110110+}111111+112112+/**113113+ * pch_gbe_wait_clr_bit - Wait to clear a bit114114+ * @reg: Pointer of register115115+ * @busy: Busy bit116116+ */117117+void pch_gbe_wait_clr_bit(void *reg, u32 bit)118118+{119119+ u32 tmp;120120+ /* wait busy */121121+ tmp = 1000;122122+ while ((ioread32(reg) & bit) && --tmp)123123+ cpu_relax();124124+ if (!tmp)125125+ pr_err("Error: busy bit is not cleared\n");126126+}127127+/**128128+ * pch_gbe_mac_mar_set - Set MAC address register129129+ * @hw: Pointer to the HW structure130130+ * @addr: Pointer to the MAC address131131+ * @index: MAC address array register132132+ */133133+void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index)134134+{135135+ u32 mar_low, mar_high, adrmask;136136+137137+ pr_debug("index : 0x%x\n", index);138138+139139+ /*140140+ * HW expects these in little endian so we reverse the byte order141141+ * from network order (big endian) to little endian142142+ */143143+ mar_high = ((u32) addr[0] | ((u32) addr[1] << 8) |144144+ ((u32) addr[2] << 16) | ((u32) addr[3] << 24));145145+ mar_low = ((u32) addr[4] | ((u32) addr[5] << 8));146146+ /* Stop the MAC Address of index. */147147+ adrmask = ioread32(&hw->reg->ADDR_MASK);148148+ iowrite32((adrmask | (0x0001 << index)), &hw->reg->ADDR_MASK);149149+ /* wait busy */150150+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);151151+ /* Set the MAC address to the MAC address 1A/1B register */152152+ iowrite32(mar_high, &hw->reg->mac_adr[index].high);153153+ iowrite32(mar_low, &hw->reg->mac_adr[index].low);154154+ /* Start the MAC address of index */155155+ iowrite32((adrmask & ~(0x0001 << index)), &hw->reg->ADDR_MASK);156156+ /* wait busy */157157+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);158158+}159159+160160+/**161161+ * pch_gbe_mac_reset_hw - Reset hardware162162+ * @hw: Pointer to the HW structure163163+ */164164+void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw)165165+{166166+ /* Read the MAC address. and store to the private data */167167+ pch_gbe_mac_read_mac_addr(hw);168168+ iowrite32(PCH_GBE_ALL_RST, &hw->reg->RESET);169169+#ifdef PCH_GBE_MAC_IFOP_RGMII170170+ iowrite32(PCH_GBE_MODE_GMII_ETHER, &hw->reg->MODE);171171+#endif172172+ pch_gbe_wait_clr_bit(&hw->reg->RESET, PCH_GBE_ALL_RST);173173+ /* Setup the receive address */174174+ pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);175175+ return;176176+}177177+178178+/**179179+ * pch_gbe_mac_init_rx_addrs - Initialize receive address's180180+ * @hw: Pointer to the HW structure181181+ * @mar_count: Receive address registers182182+ */183183+void pch_gbe_mac_init_rx_addrs(struct pch_gbe_hw *hw, u16 mar_count)184184+{185185+ u32 i;186186+187187+ /* Setup the receive address */188188+ pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);189189+190190+ /* Zero out the other receive addresses */191191+ for (i = 1; i < mar_count; i++) {192192+ iowrite32(0, &hw->reg->mac_adr[i].high);193193+ iowrite32(0, &hw->reg->mac_adr[i].low);194194+ }195195+ iowrite32(0xFFFE, &hw->reg->ADDR_MASK);196196+ /* wait busy */197197+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);198198+}199199+200200+201201+/**202202+ * pch_gbe_mac_mc_addr_list_update - Update Multicast addresses203203+ * @hw: Pointer to the HW structure204204+ * @mc_addr_list: Array of multicast addresses to program205205+ * @mc_addr_count: Number of multicast addresses to program206206+ * @mar_used_count: The first MAC Address register free to program207207+ * @mar_total_num: Total number of supported MAC Address Registers208208+ */209209+void pch_gbe_mac_mc_addr_list_update(struct pch_gbe_hw *hw,210210+ u8 *mc_addr_list, u32 mc_addr_count,211211+ u32 mar_used_count, u32 mar_total_num)212212+{213213+ u32 i, adrmask;214214+215215+ /* Load the first set of multicast addresses into the exact216216+ * filters (RAR). If there are not enough to fill the RAR217217+ * array, clear the filters.218218+ */219219+ for (i = mar_used_count; i < mar_total_num; i++) {220220+ if (mc_addr_count) {221221+ pch_gbe_mac_mar_set(hw, mc_addr_list, i);222222+ mc_addr_count--;223223+ mc_addr_list += PCH_GBE_ETH_ALEN;224224+ } else {225225+ /* Clear MAC address mask */226226+ adrmask = ioread32(&hw->reg->ADDR_MASK);227227+ iowrite32((adrmask | (0x0001 << i)),228228+ &hw->reg->ADDR_MASK);229229+ /* wait busy */230230+ pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY);231231+ /* Clear MAC address */232232+ iowrite32(0, &hw->reg->mac_adr[i].high);233233+ iowrite32(0, &hw->reg->mac_adr[i].low);234234+ }235235+ }236236+}237237+238238+/**239239+ * pch_gbe_mac_force_mac_fc - Force the MAC's flow control settings240240+ * @hw: Pointer to the HW structure241241+ * Returns242242+ * 0: Successful.243243+ * Negative value: Failed.244244+ */245245+s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw)246246+{247247+ struct pch_gbe_mac_info *mac = &hw->mac;248248+ u32 rx_fctrl;249249+250250+ pr_debug("mac->fc = %u\n", mac->fc);251251+252252+ rx_fctrl = ioread32(&hw->reg->RX_FCTRL);253253+254254+ switch (mac->fc) {255255+ case PCH_GBE_FC_NONE:256256+ rx_fctrl &= ~PCH_GBE_FL_CTRL_EN;257257+ mac->tx_fc_enable = false;258258+ break;259259+ case PCH_GBE_FC_RX_PAUSE:260260+ rx_fctrl |= PCH_GBE_FL_CTRL_EN;261261+ mac->tx_fc_enable = false;262262+ break;263263+ case PCH_GBE_FC_TX_PAUSE:264264+ rx_fctrl &= ~PCH_GBE_FL_CTRL_EN;265265+ mac->tx_fc_enable = true;266266+ break;267267+ case PCH_GBE_FC_FULL:268268+ rx_fctrl |= PCH_GBE_FL_CTRL_EN;269269+ mac->tx_fc_enable = true;270270+ break;271271+ default:272272+ pr_err("Flow control param set incorrectly\n");273273+ return -EINVAL;274274+ }275275+ if (mac->link_duplex == DUPLEX_HALF)276276+ rx_fctrl &= ~PCH_GBE_FL_CTRL_EN;277277+ iowrite32(rx_fctrl, &hw->reg->RX_FCTRL);278278+ pr_debug("RX_FCTRL reg : 0x%08x mac->tx_fc_enable : %d\n",279279+ ioread32(&hw->reg->RX_FCTRL), mac->tx_fc_enable);280280+ return 0;281281+}282282+283283+/**284284+ * pch_gbe_mac_set_wol_event - Set wake-on-lan event285285+ * @hw: Pointer to the HW structure286286+ * @wu_evt: Wake up event287287+ */288288+void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt)289289+{290290+ u32 addr_mask;291291+292292+ pr_debug("wu_evt : 0x%08x ADDR_MASK reg : 0x%08x\n",293293+ wu_evt, ioread32(&hw->reg->ADDR_MASK));294294+295295+ if (wu_evt) {296296+ /* Set Wake-On-Lan address mask */297297+ addr_mask = ioread32(&hw->reg->ADDR_MASK);298298+ iowrite32(addr_mask, &hw->reg->WOL_ADDR_MASK);299299+ /* wait busy */300300+ pch_gbe_wait_clr_bit(&hw->reg->WOL_ADDR_MASK, PCH_GBE_WLA_BUSY);301301+ iowrite32(0, &hw->reg->WOL_ST);302302+ iowrite32((wu_evt | PCH_GBE_WLC_WOL_MODE), &hw->reg->WOL_CTRL);303303+ iowrite32(0x02, &hw->reg->TCPIP_ACC);304304+ iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN);305305+ } else {306306+ iowrite32(0, &hw->reg->WOL_CTRL);307307+ iowrite32(0, &hw->reg->WOL_ST);308308+ }309309+ return;310310+}311311+312312+/**313313+ * pch_gbe_mac_ctrl_miim - Control MIIM interface314314+ * @hw: Pointer to the HW structure315315+ * @addr: Address of PHY316316+ * @dir: Operetion. (Write or Read)317317+ * @reg: Access register of PHY318318+ * @data: Write data.319319+ *320320+ * Returns: Read date.321321+ */322322+u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,323323+ u16 data)324324+{325325+ u32 data_out = 0;326326+ unsigned int i;327327+ unsigned long flags;328328+329329+ spin_lock_irqsave(&hw->miim_lock, flags);330330+331331+ for (i = 100; i; --i) {332332+ if ((ioread32(&hw->reg->MIIM) & PCH_GBE_MIIM_OPER_READY))333333+ break;334334+ udelay(20);335335+ }336336+ if (i == 0) {337337+ pr_err("pch-gbe.miim won't go Ready\n");338338+ spin_unlock_irqrestore(&hw->miim_lock, flags);339339+ return 0; /* No way to indicate timeout error */340340+ }341341+ iowrite32(((reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) |342342+ (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) |343343+ dir | data), &hw->reg->MIIM);344344+ for (i = 0; i < 100; i++) {345345+ udelay(20);346346+ data_out = ioread32(&hw->reg->MIIM);347347+ if ((data_out & PCH_GBE_MIIM_OPER_READY))348348+ break;349349+ }350350+ spin_unlock_irqrestore(&hw->miim_lock, flags);351351+352352+ pr_debug("PHY %s: reg=%d, data=0x%04X\n",353353+ dir == PCH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", reg,354354+ dir == PCH_GBE_MIIM_OPER_READ ? data_out : data);355355+ return (u16) data_out;356356+}357357+358358+/**359359+ * pch_gbe_mac_set_pause_packet - Set pause packet360360+ * @hw: Pointer to the HW structure361361+ */362362+void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw)363363+{364364+ unsigned long tmp2, tmp3;365365+366366+ /* Set Pause packet */367367+ tmp2 = hw->mac.addr[1];368368+ tmp2 = (tmp2 << 8) | hw->mac.addr[0];369369+ tmp2 = PCH_GBE_PAUSE_PKT2_VALUE | (tmp2 << 16);370370+371371+ tmp3 = hw->mac.addr[5];372372+ tmp3 = (tmp3 << 8) | hw->mac.addr[4];373373+ tmp3 = (tmp3 << 8) | hw->mac.addr[3];374374+ tmp3 = (tmp3 << 8) | hw->mac.addr[2];375375+376376+ iowrite32(PCH_GBE_PAUSE_PKT1_VALUE, &hw->reg->PAUSE_PKT1);377377+ iowrite32(tmp2, &hw->reg->PAUSE_PKT2);378378+ iowrite32(tmp3, &hw->reg->PAUSE_PKT3);379379+ iowrite32(PCH_GBE_PAUSE_PKT4_VALUE, &hw->reg->PAUSE_PKT4);380380+ iowrite32(PCH_GBE_PAUSE_PKT5_VALUE, &hw->reg->PAUSE_PKT5);381381+382382+ /* Transmit Pause Packet */383383+ iowrite32(PCH_GBE_PS_PKT_RQ, &hw->reg->PAUSE_REQ);384384+385385+ pr_debug("PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",386386+ ioread32(&hw->reg->PAUSE_PKT1), ioread32(&hw->reg->PAUSE_PKT2),387387+ ioread32(&hw->reg->PAUSE_PKT3), ioread32(&hw->reg->PAUSE_PKT4),388388+ ioread32(&hw->reg->PAUSE_PKT5));389389+390390+ return;391391+}392392+393393+394394+/**395395+ * pch_gbe_alloc_queues - Allocate memory for all rings396396+ * @adapter: Board private structure to initialize397397+ * Returns398398+ * 0: Successfully399399+ * Negative value: Failed400400+ */401401+static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter)402402+{403403+ int size;404404+405405+ size = (int)sizeof(struct pch_gbe_tx_ring);406406+ adapter->tx_ring = kzalloc(size, GFP_KERNEL);407407+ if (!adapter->tx_ring)408408+ return -ENOMEM;409409+ size = (int)sizeof(struct pch_gbe_rx_ring);410410+ adapter->rx_ring = kzalloc(size, GFP_KERNEL);411411+ if (!adapter->rx_ring) {412412+ kfree(adapter->tx_ring);413413+ return -ENOMEM;414414+ }415415+ return 0;416416+}417417+418418+/**419419+ * pch_gbe_init_stats - Initialize status420420+ * @adapter: Board private structure to initialize421421+ */422422+static void pch_gbe_init_stats(struct pch_gbe_adapter *adapter)423423+{424424+ memset(&adapter->stats, 0, sizeof(adapter->stats));425425+ return;426426+}427427+428428+/**429429+ * pch_gbe_init_phy - Initialize PHY430430+ * @adapter: Board private structure to initialize431431+ * Returns432432+ * 0: Successfully433433+ * Negative value: Failed434434+ */435435+static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter)436436+{437437+ struct net_device *netdev = adapter->netdev;438438+ u32 addr;439439+ u16 bmcr, stat;440440+441441+ /* Discover phy addr by searching addrs in order {1,0,2,..., 31} */442442+ for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) {443443+ adapter->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr;444444+ bmcr = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMCR);445445+ stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);446446+ stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);447447+ if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))448448+ break;449449+ }450450+ adapter->hw.phy.addr = adapter->mii.phy_id;451451+ pr_debug("phy_addr = %d\n", adapter->mii.phy_id);452452+ if (addr == 32)453453+ return -EAGAIN;454454+ /* Selected the phy and isolate the rest */455455+ for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) {456456+ if (addr != adapter->mii.phy_id) {457457+ pch_gbe_mdio_write(netdev, addr, MII_BMCR,458458+ BMCR_ISOLATE);459459+ } else {460460+ bmcr = pch_gbe_mdio_read(netdev, addr, MII_BMCR);461461+ pch_gbe_mdio_write(netdev, addr, MII_BMCR,462462+ bmcr & ~BMCR_ISOLATE);463463+ }464464+ }465465+466466+ /* MII setup */467467+ adapter->mii.phy_id_mask = 0x1F;468468+ adapter->mii.reg_num_mask = 0x1F;469469+ adapter->mii.dev = adapter->netdev;470470+ adapter->mii.mdio_read = pch_gbe_mdio_read;471471+ adapter->mii.mdio_write = pch_gbe_mdio_write;472472+ adapter->mii.supports_gmii = mii_check_gmii_support(&adapter->mii);473473+ return 0;474474+}475475+476476+/**477477+ * pch_gbe_mdio_read - The read function for mii478478+ * @netdev: Network interface device structure479479+ * @addr: Phy ID480480+ * @reg: Access location481481+ * Returns482482+ * 0: Successfully483483+ * Negative value: Failed484484+ */485485+int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg)486486+{487487+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);488488+ struct pch_gbe_hw *hw = &adapter->hw;489489+490490+ return pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_READ, reg,491491+ (u16) 0);492492+}493493+494494+/**495495+ * pch_gbe_mdio_write - The write function for mii496496+ * @netdev: Network interface device structure497497+ * @addr: Phy ID (not used)498498+ * @reg: Access location499499+ * @data: Write data500500+ */501501+void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data)502502+{503503+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);504504+ struct pch_gbe_hw *hw = &adapter->hw;505505+506506+ pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_WRITE, reg, data);507507+}508508+509509+/**510510+ * pch_gbe_reset_task - Reset processing at the time of transmission timeout511511+ * @work: Pointer of board private structure512512+ */513513+static void pch_gbe_reset_task(struct work_struct *work)514514+{515515+ struct pch_gbe_adapter *adapter;516516+ adapter = container_of(work, struct pch_gbe_adapter, reset_task);517517+518518+ pch_gbe_reinit_locked(adapter);519519+}520520+521521+/**522522+ * pch_gbe_reinit_locked- Re-initialization523523+ * @adapter: Board private structure524524+ */525525+void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter)526526+{527527+ struct net_device *netdev = adapter->netdev;528528+529529+ rtnl_lock();530530+ if (netif_running(netdev)) {531531+ pch_gbe_down(adapter);532532+ pch_gbe_up(adapter);533533+ }534534+ rtnl_unlock();535535+}536536+537537+/**538538+ * pch_gbe_reset - Reset GbE539539+ * @adapter: Board private structure540540+ */541541+void pch_gbe_reset(struct pch_gbe_adapter *adapter)542542+{543543+ pch_gbe_mac_reset_hw(&adapter->hw);544544+ /* Setup the receive address. */545545+ pch_gbe_mac_init_rx_addrs(&adapter->hw, PCH_GBE_MAR_ENTRIES);546546+ if (pch_gbe_hal_init_hw(&adapter->hw))547547+ pr_err("Hardware Error\n");548548+}549549+550550+/**551551+ * pch_gbe_free_irq - Free an interrupt552552+ * @adapter: Board private structure553553+ */554554+static void pch_gbe_free_irq(struct pch_gbe_adapter *adapter)555555+{556556+ struct net_device *netdev = adapter->netdev;557557+558558+ free_irq(adapter->pdev->irq, netdev);559559+ if (adapter->have_msi) {560560+ pci_disable_msi(adapter->pdev);561561+ pr_debug("call pci_disable_msi\n");562562+ }563563+}564564+565565+/**566566+ * pch_gbe_irq_disable - Mask off interrupt generation on the NIC567567+ * @adapter: Board private structure568568+ */569569+static void pch_gbe_irq_disable(struct pch_gbe_adapter *adapter)570570+{571571+ struct pch_gbe_hw *hw = &adapter->hw;572572+573573+ atomic_inc(&adapter->irq_sem);574574+ iowrite32(0, &hw->reg->INT_EN);575575+ ioread32(&hw->reg->INT_ST);576576+ synchronize_irq(adapter->pdev->irq);577577+578578+ pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN));579579+}580580+581581+/**582582+ * pch_gbe_irq_enable - Enable default interrupt generation settings583583+ * @adapter: Board private structure584584+ */585585+static void pch_gbe_irq_enable(struct pch_gbe_adapter *adapter)586586+{587587+ struct pch_gbe_hw *hw = &adapter->hw;588588+589589+ if (likely(atomic_dec_and_test(&adapter->irq_sem)))590590+ iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN);591591+ ioread32(&hw->reg->INT_ST);592592+ pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN));593593+}594594+595595+596596+597597+/**598598+ * pch_gbe_setup_tctl - configure the Transmit control registers599599+ * @adapter: Board private structure600600+ */601601+static void pch_gbe_setup_tctl(struct pch_gbe_adapter *adapter)602602+{603603+ struct pch_gbe_hw *hw = &adapter->hw;604604+ u32 tx_mode, tcpip;605605+606606+ tx_mode = PCH_GBE_TM_LONG_PKT |607607+ PCH_GBE_TM_ST_AND_FD |608608+ PCH_GBE_TM_SHORT_PKT |609609+ PCH_GBE_TM_TH_TX_STRT_8 |610610+ PCH_GBE_TM_TH_ALM_EMP_4 | PCH_GBE_TM_TH_ALM_FULL_8;611611+612612+ iowrite32(tx_mode, &hw->reg->TX_MODE);613613+614614+ tcpip = ioread32(&hw->reg->TCPIP_ACC);615615+ tcpip |= PCH_GBE_TX_TCPIPACC_EN;616616+ iowrite32(tcpip, &hw->reg->TCPIP_ACC);617617+ return;618618+}619619+620620+/**621621+ * pch_gbe_configure_tx - Configure Transmit Unit after Reset622622+ * @adapter: Board private structure623623+ */624624+static void pch_gbe_configure_tx(struct pch_gbe_adapter *adapter)625625+{626626+ struct pch_gbe_hw *hw = &adapter->hw;627627+ u32 tdba, tdlen, dctrl;628628+629629+ pr_debug("dma addr = 0x%08llx size = 0x%08x\n",630630+ (unsigned long long)adapter->tx_ring->dma,631631+ adapter->tx_ring->size);632632+633633+ /* Setup the HW Tx Head and Tail descriptor pointers */634634+ tdba = adapter->tx_ring->dma;635635+ tdlen = adapter->tx_ring->size - 0x10;636636+ iowrite32(tdba, &hw->reg->TX_DSC_BASE);637637+ iowrite32(tdlen, &hw->reg->TX_DSC_SIZE);638638+ iowrite32(tdba, &hw->reg->TX_DSC_SW_P);639639+640640+ /* Enables Transmission DMA */641641+ dctrl = ioread32(&hw->reg->DMA_CTRL);642642+ dctrl |= PCH_GBE_TX_DMA_EN;643643+ iowrite32(dctrl, &hw->reg->DMA_CTRL);644644+}645645+646646+/**647647+ * pch_gbe_setup_rctl - Configure the receive control registers648648+ * @adapter: Board private structure649649+ */650650+static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)651651+{652652+ struct pch_gbe_hw *hw = &adapter->hw;653653+ u32 rx_mode, tcpip;654654+655655+ rx_mode = PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN |656656+ PCH_GBE_RH_ALM_EMP_4 | PCH_GBE_RH_ALM_FULL_4 | PCH_GBE_RH_RD_TRG_8;657657+658658+ iowrite32(rx_mode, &hw->reg->RX_MODE);659659+660660+ tcpip = ioread32(&hw->reg->TCPIP_ACC);661661+662662+ if (adapter->rx_csum) {663663+ tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF;664664+ tcpip |= PCH_GBE_RX_TCPIPACC_EN;665665+ } else {666666+ tcpip |= PCH_GBE_RX_TCPIPACC_OFF;667667+ tcpip &= ~PCH_GBE_RX_TCPIPACC_EN;668668+ }669669+ iowrite32(tcpip, &hw->reg->TCPIP_ACC);670670+ return;671671+}672672+673673+/**674674+ * pch_gbe_configure_rx - Configure Receive Unit after Reset675675+ * @adapter: Board private structure676676+ */677677+static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter)678678+{679679+ struct pch_gbe_hw *hw = &adapter->hw;680680+ u32 rdba, rdlen, rctl, rxdma;681681+682682+ pr_debug("dma adr = 0x%08llx size = 0x%08x\n",683683+ (unsigned long long)adapter->rx_ring->dma,684684+ adapter->rx_ring->size);685685+686686+ pch_gbe_mac_force_mac_fc(hw);687687+688688+ /* Disables Receive MAC */689689+ rctl = ioread32(&hw->reg->MAC_RX_EN);690690+ iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);691691+692692+ /* Disables Receive DMA */693693+ rxdma = ioread32(&hw->reg->DMA_CTRL);694694+ rxdma &= ~PCH_GBE_RX_DMA_EN;695695+ iowrite32(rxdma, &hw->reg->DMA_CTRL);696696+697697+ pr_debug("MAC_RX_EN reg = 0x%08x DMA_CTRL reg = 0x%08x\n",698698+ ioread32(&hw->reg->MAC_RX_EN),699699+ ioread32(&hw->reg->DMA_CTRL));700700+701701+ /* Setup the HW Rx Head and Tail Descriptor Pointers and702702+ * the Base and Length of the Rx Descriptor Ring */703703+ rdba = adapter->rx_ring->dma;704704+ rdlen = adapter->rx_ring->size - 0x10;705705+ iowrite32(rdba, &hw->reg->RX_DSC_BASE);706706+ iowrite32(rdlen, &hw->reg->RX_DSC_SIZE);707707+ iowrite32((rdba + rdlen), &hw->reg->RX_DSC_SW_P);708708+709709+ /* Enables Receive DMA */710710+ rxdma = ioread32(&hw->reg->DMA_CTRL);711711+ rxdma |= PCH_GBE_RX_DMA_EN;712712+ iowrite32(rxdma, &hw->reg->DMA_CTRL);713713+ /* Enables Receive */714714+ iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN);715715+}716716+717717+/**718718+ * pch_gbe_unmap_and_free_tx_resource - Unmap and free tx socket buffer719719+ * @adapter: Board private structure720720+ * @buffer_info: Buffer information structure721721+ */722722+static void pch_gbe_unmap_and_free_tx_resource(723723+ struct pch_gbe_adapter *adapter, struct pch_gbe_buffer *buffer_info)724724+{725725+ if (buffer_info->mapped) {726726+ dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,727727+ buffer_info->length, DMA_TO_DEVICE);728728+ buffer_info->mapped = false;729729+ }730730+ if (buffer_info->skb) {731731+ dev_kfree_skb_any(buffer_info->skb);732732+ buffer_info->skb = NULL;733733+ }734734+}735735+736736+/**737737+ * pch_gbe_unmap_and_free_rx_resource - Unmap and free rx socket buffer738738+ * @adapter: Board private structure739739+ * @buffer_info: Buffer information structure740740+ */741741+static void pch_gbe_unmap_and_free_rx_resource(742742+ struct pch_gbe_adapter *adapter,743743+ struct pch_gbe_buffer *buffer_info)744744+{745745+ if (buffer_info->mapped) {746746+ dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,747747+ buffer_info->length, DMA_FROM_DEVICE);748748+ buffer_info->mapped = false;749749+ }750750+ if (buffer_info->skb) {751751+ dev_kfree_skb_any(buffer_info->skb);752752+ buffer_info->skb = NULL;753753+ }754754+}755755+756756+/**757757+ * pch_gbe_clean_tx_ring - Free Tx Buffers758758+ * @adapter: Board private structure759759+ * @tx_ring: Ring to be cleaned760760+ */761761+static void pch_gbe_clean_tx_ring(struct pch_gbe_adapter *adapter,762762+ struct pch_gbe_tx_ring *tx_ring)763763+{764764+ struct pch_gbe_hw *hw = &adapter->hw;765765+ struct pch_gbe_buffer *buffer_info;766766+ unsigned long size;767767+ unsigned int i;768768+769769+ /* Free all the Tx ring sk_buffs */770770+ for (i = 0; i < tx_ring->count; i++) {771771+ buffer_info = &tx_ring->buffer_info[i];772772+ pch_gbe_unmap_and_free_tx_resource(adapter, buffer_info);773773+ }774774+ pr_debug("call pch_gbe_unmap_and_free_tx_resource() %d count\n", i);775775+776776+ size = (unsigned long)sizeof(struct pch_gbe_buffer) * tx_ring->count;777777+ memset(tx_ring->buffer_info, 0, size);778778+779779+ /* Zero out the descriptor ring */780780+ memset(tx_ring->desc, 0, tx_ring->size);781781+ tx_ring->next_to_use = 0;782782+ tx_ring->next_to_clean = 0;783783+ iowrite32(tx_ring->dma, &hw->reg->TX_DSC_HW_P);784784+ iowrite32((tx_ring->size - 0x10), &hw->reg->TX_DSC_SIZE);785785+}786786+787787+/**788788+ * pch_gbe_clean_rx_ring - Free Rx Buffers789789+ * @adapter: Board private structure790790+ * @rx_ring: Ring to free buffers from791791+ */792792+static void793793+pch_gbe_clean_rx_ring(struct pch_gbe_adapter *adapter,794794+ struct pch_gbe_rx_ring *rx_ring)795795+{796796+ struct pch_gbe_hw *hw = &adapter->hw;797797+ struct pch_gbe_buffer *buffer_info;798798+ unsigned long size;799799+ unsigned int i;800800+801801+ /* Free all the Rx ring sk_buffs */802802+ for (i = 0; i < rx_ring->count; i++) {803803+ buffer_info = &rx_ring->buffer_info[i];804804+ pch_gbe_unmap_and_free_rx_resource(adapter, buffer_info);805805+ }806806+ pr_debug("call pch_gbe_unmap_and_free_rx_resource() %d count\n", i);807807+ size = (unsigned long)sizeof(struct pch_gbe_buffer) * rx_ring->count;808808+ memset(rx_ring->buffer_info, 0, size);809809+810810+ /* Zero out the descriptor ring */811811+ memset(rx_ring->desc, 0, rx_ring->size);812812+ rx_ring->next_to_clean = 0;813813+ rx_ring->next_to_use = 0;814814+ iowrite32(rx_ring->dma, &hw->reg->RX_DSC_HW_P);815815+ iowrite32((rx_ring->size - 0x10), &hw->reg->RX_DSC_SIZE);816816+}817817+818818+static void pch_gbe_set_rgmii_ctrl(struct pch_gbe_adapter *adapter, u16 speed,819819+ u16 duplex)820820+{821821+ struct pch_gbe_hw *hw = &adapter->hw;822822+ unsigned long rgmii = 0;823823+824824+ /* Set the RGMII control. */825825+#ifdef PCH_GBE_MAC_IFOP_RGMII826826+ switch (speed) {827827+ case SPEED_10:828828+ rgmii = (PCH_GBE_RGMII_RATE_2_5M |829829+ PCH_GBE_MAC_RGMII_CTRL_SETTING);830830+ break;831831+ case SPEED_100:832832+ rgmii = (PCH_GBE_RGMII_RATE_25M |833833+ PCH_GBE_MAC_RGMII_CTRL_SETTING);834834+ break;835835+ case SPEED_1000:836836+ rgmii = (PCH_GBE_RGMII_RATE_125M |837837+ PCH_GBE_MAC_RGMII_CTRL_SETTING);838838+ break;839839+ }840840+ iowrite32(rgmii, &hw->reg->RGMII_CTRL);841841+#else /* GMII */842842+ rgmii = 0;843843+ iowrite32(rgmii, &hw->reg->RGMII_CTRL);844844+#endif845845+}846846+static void pch_gbe_set_mode(struct pch_gbe_adapter *adapter, u16 speed,847847+ u16 duplex)848848+{849849+ struct net_device *netdev = adapter->netdev;850850+ struct pch_gbe_hw *hw = &adapter->hw;851851+ unsigned long mode = 0;852852+853853+ /* Set the communication mode */854854+ switch (speed) {855855+ case SPEED_10:856856+ mode = PCH_GBE_MODE_MII_ETHER;857857+ netdev->tx_queue_len = 10;858858+ break;859859+ case SPEED_100:860860+ mode = PCH_GBE_MODE_MII_ETHER;861861+ netdev->tx_queue_len = 100;862862+ break;863863+ case SPEED_1000:864864+ mode = PCH_GBE_MODE_GMII_ETHER;865865+ break;866866+ }867867+ if (duplex == DUPLEX_FULL)868868+ mode |= PCH_GBE_MODE_FULL_DUPLEX;869869+ else870870+ mode |= PCH_GBE_MODE_HALF_DUPLEX;871871+ iowrite32(mode, &hw->reg->MODE);872872+}873873+874874+/**875875+ * pch_gbe_watchdog - Watchdog process876876+ * @data: Board private structure877877+ */878878+static void pch_gbe_watchdog(unsigned long data)879879+{880880+ struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data;881881+ struct net_device *netdev = adapter->netdev;882882+ struct pch_gbe_hw *hw = &adapter->hw;883883+ struct ethtool_cmd cmd;884884+885885+ pr_debug("right now = %ld\n", jiffies);886886+887887+ pch_gbe_update_stats(adapter);888888+ if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {889889+ netdev->tx_queue_len = adapter->tx_queue_len;890890+ /* mii library handles link maintenance tasks */891891+ if (mii_ethtool_gset(&adapter->mii, &cmd)) {892892+ pr_err("ethtool get setting Error\n");893893+ mod_timer(&adapter->watchdog_timer,894894+ round_jiffies(jiffies +895895+ PCH_GBE_WATCHDOG_PERIOD));896896+ return;897897+ }898898+ hw->mac.link_speed = cmd.speed;899899+ hw->mac.link_duplex = cmd.duplex;900900+ /* Set the RGMII control. */901901+ pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,902902+ hw->mac.link_duplex);903903+ /* Set the communication mode */904904+ pch_gbe_set_mode(adapter, hw->mac.link_speed,905905+ hw->mac.link_duplex);906906+ netdev_dbg(netdev,907907+ "Link is Up %d Mbps %s-Duplex\n",908908+ cmd.speed,909909+ cmd.duplex == DUPLEX_FULL ? "Full" : "Half");910910+ netif_carrier_on(netdev);911911+ netif_wake_queue(netdev);912912+ } else if ((!mii_link_ok(&adapter->mii)) &&913913+ (netif_carrier_ok(netdev))) {914914+ netdev_dbg(netdev, "NIC Link is Down\n");915915+ hw->mac.link_speed = SPEED_10;916916+ hw->mac.link_duplex = DUPLEX_HALF;917917+ netif_carrier_off(netdev);918918+ netif_stop_queue(netdev);919919+ }920920+ mod_timer(&adapter->watchdog_timer,921921+ round_jiffies(jiffies + PCH_GBE_WATCHDOG_PERIOD));922922+}923923+924924+/**925925+ * pch_gbe_tx_queue - Carry out queuing of the transmission data926926+ * @adapter: Board private structure927927+ * @tx_ring: Tx descriptor ring structure928928+ * @skb: Sockt buffer structure929929+ */930930+static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,931931+ struct pch_gbe_tx_ring *tx_ring,932932+ struct sk_buff *skb)933933+{934934+ struct pch_gbe_hw *hw = &adapter->hw;935935+ struct pch_gbe_tx_desc *tx_desc;936936+ struct pch_gbe_buffer *buffer_info;937937+ struct sk_buff *tmp_skb;938938+ unsigned int frame_ctrl;939939+ unsigned int ring_num;940940+ unsigned long flags;941941+942942+ /*-- Set frame control --*/943943+ frame_ctrl = 0;944944+ if (unlikely(skb->len < PCH_GBE_SHORT_PKT))945945+ frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;946946+ if (unlikely(!adapter->tx_csum))947947+ frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;948948+949949+ /* Performs checksum processing */950950+ /*951951+ * It is because the hardware accelerator does not support a checksum,952952+ * when the received data size is less than 64 bytes.953953+ */954954+ if ((skb->len < PCH_GBE_SHORT_PKT) && (adapter->tx_csum)) {955955+ frame_ctrl |= PCH_GBE_TXD_CTRL_APAD |956956+ PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;957957+ if (skb->protocol == htons(ETH_P_IP)) {958958+ struct iphdr *iph = ip_hdr(skb);959959+ unsigned int offset;960960+ iph->check = 0;961961+ iph->check = ip_fast_csum((u8 *) iph, iph->ihl);962962+ offset = skb_transport_offset(skb);963963+ if (iph->protocol == IPPROTO_TCP) {964964+ skb->csum = 0;965965+ tcp_hdr(skb)->check = 0;966966+ skb->csum = skb_checksum(skb, offset,967967+ skb->len - offset, 0);968968+ tcp_hdr(skb)->check =969969+ csum_tcpudp_magic(iph->saddr,970970+ iph->daddr,971971+ skb->len - offset,972972+ IPPROTO_TCP,973973+ skb->csum);974974+ } else if (iph->protocol == IPPROTO_UDP) {975975+ skb->csum = 0;976976+ udp_hdr(skb)->check = 0;977977+ skb->csum =978978+ skb_checksum(skb, offset,979979+ skb->len - offset, 0);980980+ udp_hdr(skb)->check =981981+ csum_tcpudp_magic(iph->saddr,982982+ iph->daddr,983983+ skb->len - offset,984984+ IPPROTO_UDP,985985+ skb->csum);986986+ }987987+ }988988+ }989989+ spin_lock_irqsave(&tx_ring->tx_lock, flags);990990+ ring_num = tx_ring->next_to_use;991991+ if (unlikely((ring_num + 1) == tx_ring->count))992992+ tx_ring->next_to_use = 0;993993+ else994994+ tx_ring->next_to_use = ring_num + 1;995995+996996+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);997997+ buffer_info = &tx_ring->buffer_info[ring_num];998998+ tmp_skb = buffer_info->skb;999999+10001000+ /* [Header:14][payload] ---> [Header:14][paddong:2][payload] */10011001+ memcpy(tmp_skb->data, skb->data, ETH_HLEN);10021002+ tmp_skb->data[ETH_HLEN] = 0x00;10031003+ tmp_skb->data[ETH_HLEN + 1] = 0x00;10041004+ tmp_skb->len = skb->len;10051005+ memcpy(&tmp_skb->data[ETH_HLEN + 2], &skb->data[ETH_HLEN],10061006+ (skb->len - ETH_HLEN));10071007+ /*-- Set Buffer infomation --*/10081008+ buffer_info->length = tmp_skb->len;10091009+ buffer_info->dma = dma_map_single(&adapter->pdev->dev, tmp_skb->data,10101010+ buffer_info->length,10111011+ DMA_TO_DEVICE);10121012+ if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {10131013+ pr_err("TX DMA map failed\n");10141014+ buffer_info->dma = 0;10151015+ buffer_info->time_stamp = 0;10161016+ tx_ring->next_to_use = ring_num;10171017+ return;10181018+ }10191019+ buffer_info->mapped = true;10201020+ buffer_info->time_stamp = jiffies;10211021+10221022+ /*-- Set Tx descriptor --*/10231023+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, ring_num);10241024+ tx_desc->buffer_addr = (buffer_info->dma);10251025+ tx_desc->length = (tmp_skb->len);10261026+ tx_desc->tx_words_eob = ((tmp_skb->len + 3));10271027+ tx_desc->tx_frame_ctrl = (frame_ctrl);10281028+ tx_desc->gbec_status = (DSC_INIT16);10291029+10301030+ if (unlikely(++ring_num == tx_ring->count))10311031+ ring_num = 0;10321032+10331033+ /* Update software pointer of TX descriptor */10341034+ iowrite32(tx_ring->dma +10351035+ (int)sizeof(struct pch_gbe_tx_desc) * ring_num,10361036+ &hw->reg->TX_DSC_SW_P);10371037+ dev_kfree_skb_any(skb);10381038+}10391039+10401040+/**10411041+ * pch_gbe_update_stats - Update the board statistics counters10421042+ * @adapter: Board private structure10431043+ */10441044+void pch_gbe_update_stats(struct pch_gbe_adapter *adapter)10451045+{10461046+ struct net_device *netdev = adapter->netdev;10471047+ struct pci_dev *pdev = adapter->pdev;10481048+ struct pch_gbe_hw_stats *stats = &adapter->stats;10491049+ unsigned long flags;10501050+10511051+ /*10521052+ * Prevent stats update while adapter is being reset, or if the pci10531053+ * connection is down.10541054+ */10551055+ if ((pdev->error_state) && (pdev->error_state != pci_channel_io_normal))10561056+ return;10571057+10581058+ spin_lock_irqsave(&adapter->stats_lock, flags);10591059+10601060+ /* Update device status "adapter->stats" */10611061+ stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors;10621062+ stats->tx_errors = stats->tx_length_errors +10631063+ stats->tx_aborted_errors +10641064+ stats->tx_carrier_errors + stats->tx_timeout_count;10651065+10661066+ /* Update network device status "adapter->net_stats" */10671067+ netdev->stats.rx_packets = stats->rx_packets;10681068+ netdev->stats.rx_bytes = stats->rx_bytes;10691069+ netdev->stats.rx_dropped = stats->rx_dropped;10701070+ netdev->stats.tx_packets = stats->tx_packets;10711071+ netdev->stats.tx_bytes = stats->tx_bytes;10721072+ netdev->stats.tx_dropped = stats->tx_dropped;10731073+ /* Fill out the OS statistics structure */10741074+ netdev->stats.multicast = stats->multicast;10751075+ netdev->stats.collisions = stats->collisions;10761076+ /* Rx Errors */10771077+ netdev->stats.rx_errors = stats->rx_errors;10781078+ netdev->stats.rx_crc_errors = stats->rx_crc_errors;10791079+ netdev->stats.rx_frame_errors = stats->rx_frame_errors;10801080+ /* Tx Errors */10811081+ netdev->stats.tx_errors = stats->tx_errors;10821082+ netdev->stats.tx_aborted_errors = stats->tx_aborted_errors;10831083+ netdev->stats.tx_carrier_errors = stats->tx_carrier_errors;10841084+10851085+ spin_unlock_irqrestore(&adapter->stats_lock, flags);10861086+}10871087+10881088+/**10891089+ * pch_gbe_intr - Interrupt Handler10901090+ * @irq: Interrupt number10911091+ * @data: Pointer to a network interface device structure10921092+ * Returns10931093+ * - IRQ_HANDLED: Our interrupt10941094+ * - IRQ_NONE: Not our interrupt10951095+ */10961096+static irqreturn_t pch_gbe_intr(int irq, void *data)10971097+{10981098+ struct net_device *netdev = data;10991099+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);11001100+ struct pch_gbe_hw *hw = &adapter->hw;11011101+ u32 int_st;11021102+ u32 int_en;11031103+11041104+ /* Check request status */11051105+ int_st = ioread32(&hw->reg->INT_ST);11061106+ int_st = int_st & ioread32(&hw->reg->INT_EN);11071107+ /* When request status is no interruption factor */11081108+ if (unlikely(!int_st))11091109+ return IRQ_NONE; /* Not our interrupt. End processing. */11101110+ pr_debug("%s occur int_st = 0x%08x\n", __func__, int_st);11111111+ if (int_st & PCH_GBE_INT_RX_FRAME_ERR)11121112+ adapter->stats.intr_rx_frame_err_count++;11131113+ if (int_st & PCH_GBE_INT_RX_FIFO_ERR)11141114+ adapter->stats.intr_rx_fifo_err_count++;11151115+ if (int_st & PCH_GBE_INT_RX_DMA_ERR)11161116+ adapter->stats.intr_rx_dma_err_count++;11171117+ if (int_st & PCH_GBE_INT_TX_FIFO_ERR)11181118+ adapter->stats.intr_tx_fifo_err_count++;11191119+ if (int_st & PCH_GBE_INT_TX_DMA_ERR)11201120+ adapter->stats.intr_tx_dma_err_count++;11211121+ if (int_st & PCH_GBE_INT_TCPIP_ERR)11221122+ adapter->stats.intr_tcpip_err_count++;11231123+ /* When Rx descriptor is empty */11241124+ if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) {11251125+ adapter->stats.intr_rx_dsc_empty_count++;11261126+ pr_err("Rx descriptor is empty\n");11271127+ int_en = ioread32(&hw->reg->INT_EN);11281128+ iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN);11291129+ if (hw->mac.tx_fc_enable) {11301130+ /* Set Pause packet */11311131+ pch_gbe_mac_set_pause_packet(hw);11321132+ }11331133+ if ((int_en & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))11341134+ == 0) {11351135+ return IRQ_HANDLED;11361136+ }11371137+ }11381138+11391139+ /* When request status is Receive interruption */11401140+ if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))) {11411141+ if (likely(napi_schedule_prep(&adapter->napi))) {11421142+ /* Enable only Rx Descriptor empty */11431143+ atomic_inc(&adapter->irq_sem);11441144+ int_en = ioread32(&hw->reg->INT_EN);11451145+ int_en &=11461146+ ~(PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT);11471147+ iowrite32(int_en, &hw->reg->INT_EN);11481148+ /* Start polling for NAPI */11491149+ __napi_schedule(&adapter->napi);11501150+ }11511151+ }11521152+ pr_debug("return = 0x%08x INT_EN reg = 0x%08x\n",11531153+ IRQ_HANDLED, ioread32(&hw->reg->INT_EN));11541154+ return IRQ_HANDLED;11551155+}11561156+11571157+/**11581158+ * pch_gbe_alloc_rx_buffers - Replace used receive buffers; legacy & extended11591159+ * @adapter: Board private structure11601160+ * @rx_ring: Rx descriptor ring11611161+ * @cleaned_count: Cleaned count11621162+ */11631163+static void11641164+pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter,11651165+ struct pch_gbe_rx_ring *rx_ring, int cleaned_count)11661166+{11671167+ struct net_device *netdev = adapter->netdev;11681168+ struct pci_dev *pdev = adapter->pdev;11691169+ struct pch_gbe_hw *hw = &adapter->hw;11701170+ struct pch_gbe_rx_desc *rx_desc;11711171+ struct pch_gbe_buffer *buffer_info;11721172+ struct sk_buff *skb;11731173+ unsigned int i;11741174+ unsigned int bufsz;11751175+11761176+ bufsz = adapter->rx_buffer_len + PCH_GBE_DMA_ALIGN;11771177+ i = rx_ring->next_to_use;11781178+11791179+ while ((cleaned_count--)) {11801180+ buffer_info = &rx_ring->buffer_info[i];11811181+ skb = buffer_info->skb;11821182+ if (skb) {11831183+ skb_trim(skb, 0);11841184+ } else {11851185+ skb = netdev_alloc_skb(netdev, bufsz);11861186+ if (unlikely(!skb)) {11871187+ /* Better luck next round */11881188+ adapter->stats.rx_alloc_buff_failed++;11891189+ break;11901190+ }11911191+ /* 64byte align */11921192+ skb_reserve(skb, PCH_GBE_DMA_ALIGN);11931193+11941194+ buffer_info->skb = skb;11951195+ buffer_info->length = adapter->rx_buffer_len;11961196+ }11971197+ buffer_info->dma = dma_map_single(&pdev->dev,11981198+ skb->data,11991199+ buffer_info->length,12001200+ DMA_FROM_DEVICE);12011201+ if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {12021202+ dev_kfree_skb(skb);12031203+ buffer_info->skb = NULL;12041204+ buffer_info->dma = 0;12051205+ adapter->stats.rx_alloc_buff_failed++;12061206+ break; /* while !buffer_info->skb */12071207+ }12081208+ buffer_info->mapped = true;12091209+ rx_desc = PCH_GBE_RX_DESC(*rx_ring, i);12101210+ rx_desc->buffer_addr = (buffer_info->dma);12111211+ rx_desc->gbec_status = DSC_INIT16;12121212+12131213+ pr_debug("i = %d buffer_info->dma = 0x08%llx buffer_info->length = 0x%x\n",12141214+ i, (unsigned long long)buffer_info->dma,12151215+ buffer_info->length);12161216+12171217+ if (unlikely(++i == rx_ring->count))12181218+ i = 0;12191219+ }12201220+ if (likely(rx_ring->next_to_use != i)) {12211221+ rx_ring->next_to_use = i;12221222+ if (unlikely(i-- == 0))12231223+ i = (rx_ring->count - 1);12241224+ iowrite32(rx_ring->dma +12251225+ (int)sizeof(struct pch_gbe_rx_desc) * i,12261226+ &hw->reg->RX_DSC_SW_P);12271227+ }12281228+ return;12291229+}12301230+12311231+/**12321232+ * pch_gbe_alloc_tx_buffers - Allocate transmit buffers12331233+ * @adapter: Board private structure12341234+ * @tx_ring: Tx descriptor ring12351235+ */12361236+static void pch_gbe_alloc_tx_buffers(struct pch_gbe_adapter *adapter,12371237+ struct pch_gbe_tx_ring *tx_ring)12381238+{12391239+ struct pch_gbe_buffer *buffer_info;12401240+ struct sk_buff *skb;12411241+ unsigned int i;12421242+ unsigned int bufsz;12431243+ struct pch_gbe_tx_desc *tx_desc;12441244+12451245+ bufsz =12461246+ adapter->hw.mac.max_frame_size + PCH_GBE_DMA_ALIGN + NET_IP_ALIGN;12471247+12481248+ for (i = 0; i < tx_ring->count; i++) {12491249+ buffer_info = &tx_ring->buffer_info[i];12501250+ skb = netdev_alloc_skb(adapter->netdev, bufsz);12511251+ skb_reserve(skb, PCH_GBE_DMA_ALIGN);12521252+ buffer_info->skb = skb;12531253+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);12541254+ tx_desc->gbec_status = (DSC_INIT16);12551255+ }12561256+ return;12571257+}12581258+12591259+/**12601260+ * pch_gbe_clean_tx - Reclaim resources after transmit completes12611261+ * @adapter: Board private structure12621262+ * @tx_ring: Tx descriptor ring12631263+ * Returns12641264+ * true: Cleaned the descriptor12651265+ * false: Not cleaned the descriptor12661266+ */12671267+static bool12681268+pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,12691269+ struct pch_gbe_tx_ring *tx_ring)12701270+{12711271+ struct pch_gbe_tx_desc *tx_desc;12721272+ struct pch_gbe_buffer *buffer_info;12731273+ struct sk_buff *skb;12741274+ unsigned int i;12751275+ unsigned int cleaned_count = 0;12761276+ bool cleaned = false;12771277+12781278+ pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);12791279+12801280+ i = tx_ring->next_to_clean;12811281+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);12821282+ pr_debug("gbec_status:0x%04x dma_status:0x%04x\n",12831283+ tx_desc->gbec_status, tx_desc->dma_status);12841284+12851285+ while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {12861286+ pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status);12871287+ cleaned = true;12881288+ buffer_info = &tx_ring->buffer_info[i];12891289+ skb = buffer_info->skb;12901290+12911291+ if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) {12921292+ adapter->stats.tx_aborted_errors++;12931293+ pr_err("Transfer Abort Error\n");12941294+ } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CRSER)12951295+ ) {12961296+ adapter->stats.tx_carrier_errors++;12971297+ pr_err("Transfer Carrier Sense Error\n");12981298+ } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_EXCOL)12991299+ ) {13001300+ adapter->stats.tx_aborted_errors++;13011301+ pr_err("Transfer Collision Abort Error\n");13021302+ } else if ((tx_desc->gbec_status &13031303+ (PCH_GBE_TXD_GMAC_STAT_SNGCOL |13041304+ PCH_GBE_TXD_GMAC_STAT_MLTCOL))) {13051305+ adapter->stats.collisions++;13061306+ adapter->stats.tx_packets++;13071307+ adapter->stats.tx_bytes += skb->len;13081308+ pr_debug("Transfer Collision\n");13091309+ } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CMPLT)13101310+ ) {13111311+ adapter->stats.tx_packets++;13121312+ adapter->stats.tx_bytes += skb->len;13131313+ }13141314+ if (buffer_info->mapped) {13151315+ pr_debug("unmap buffer_info->dma : %d\n", i);13161316+ dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,13171317+ buffer_info->length, DMA_TO_DEVICE);13181318+ buffer_info->mapped = false;13191319+ }13201320+ if (buffer_info->skb) {13211321+ pr_debug("trim buffer_info->skb : %d\n", i);13221322+ skb_trim(buffer_info->skb, 0);13231323+ }13241324+ tx_desc->gbec_status = DSC_INIT16;13251325+ if (unlikely(++i == tx_ring->count))13261326+ i = 0;13271327+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);13281328+13291329+ /* weight of a sort for tx, to avoid endless transmit cleanup */13301330+ if (cleaned_count++ == PCH_GBE_TX_WEIGHT)13311331+ break;13321332+ }13331333+ pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",13341334+ cleaned_count);13351335+ /* Recover from running out of Tx resources in xmit_frame */13361336+ if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) {13371337+ netif_wake_queue(adapter->netdev);13381338+ adapter->stats.tx_restart_count++;13391339+ pr_debug("Tx wake queue\n");13401340+ }13411341+ spin_lock(&adapter->tx_queue_lock);13421342+ tx_ring->next_to_clean = i;13431343+ spin_unlock(&adapter->tx_queue_lock);13441344+ pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);13451345+ return cleaned;13461346+}13471347+13481348+/**13491349+ * pch_gbe_clean_rx - Send received data up the network stack; legacy13501350+ * @adapter: Board private structure13511351+ * @rx_ring: Rx descriptor ring13521352+ * @work_done: Completed count13531353+ * @work_to_do: Request count13541354+ * Returns13551355+ * true: Cleaned the descriptor13561356+ * false: Not cleaned the descriptor13571357+ */13581358+static bool13591359+pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,13601360+ struct pch_gbe_rx_ring *rx_ring,13611361+ int *work_done, int work_to_do)13621362+{13631363+ struct net_device *netdev = adapter->netdev;13641364+ struct pci_dev *pdev = adapter->pdev;13651365+ struct pch_gbe_buffer *buffer_info;13661366+ struct pch_gbe_rx_desc *rx_desc;13671367+ u32 length;13681368+ unsigned char tmp_packet[ETH_HLEN];13691369+ unsigned int i;13701370+ unsigned int cleaned_count = 0;13711371+ bool cleaned = false;13721372+ struct sk_buff *skb;13731373+ u8 dma_status;13741374+ u16 gbec_status;13751375+ u32 tcp_ip_status;13761376+ u8 skb_copy_flag = 0;13771377+ u8 skb_padding_flag = 0;13781378+13791379+ i = rx_ring->next_to_clean;13801380+13811381+ while (*work_done < work_to_do) {13821382+ /* Check Rx descriptor status */13831383+ rx_desc = PCH_GBE_RX_DESC(*rx_ring, i);13841384+ if (rx_desc->gbec_status == DSC_INIT16)13851385+ break;13861386+ cleaned = true;13871387+ cleaned_count++;13881388+13891389+ dma_status = rx_desc->dma_status;13901390+ gbec_status = rx_desc->gbec_status;13911391+ tcp_ip_status = rx_desc->tcp_ip_status;13921392+ rx_desc->gbec_status = DSC_INIT16;13931393+ buffer_info = &rx_ring->buffer_info[i];13941394+ skb = buffer_info->skb;13951395+13961396+ /* unmap dma */13971397+ dma_unmap_single(&pdev->dev, buffer_info->dma,13981398+ buffer_info->length, DMA_FROM_DEVICE);13991399+ buffer_info->mapped = false;14001400+ /* Prefetch the packet */14011401+ prefetch(skb->data);14021402+14031403+ pr_debug("RxDecNo = 0x%04x Status[DMA:0x%02x GBE:0x%04x "14041404+ "TCP:0x%08x] BufInf = 0x%p\n",14051405+ i, dma_status, gbec_status, tcp_ip_status,14061406+ buffer_info);14071407+ /* Error check */14081408+ if (unlikely(gbec_status & PCH_GBE_RXD_GMAC_STAT_NOTOCTAL)) {14091409+ adapter->stats.rx_frame_errors++;14101410+ pr_err("Receive Not Octal Error\n");14111411+ } else if (unlikely(gbec_status &14121412+ PCH_GBE_RXD_GMAC_STAT_NBLERR)) {14131413+ adapter->stats.rx_frame_errors++;14141414+ pr_err("Receive Nibble Error\n");14151415+ } else if (unlikely(gbec_status &14161416+ PCH_GBE_RXD_GMAC_STAT_CRCERR)) {14171417+ adapter->stats.rx_crc_errors++;14181418+ pr_err("Receive CRC Error\n");14191419+ } else {14201420+ /* get receive length */14211421+ /* length convert[-3], padding[-2] */14221422+ length = (rx_desc->rx_words_eob) - 3 - 2;14231423+14241424+ /* Decide the data conversion method */14251425+ if (!adapter->rx_csum) {14261426+ /* [Header:14][payload] */14271427+ skb_padding_flag = 0;14281428+ skb_copy_flag = 1;14291429+ } else {14301430+ /* [Header:14][padding:2][payload] */14311431+ skb_padding_flag = 1;14321432+ if (length < copybreak)14331433+ skb_copy_flag = 1;14341434+ else14351435+ skb_copy_flag = 0;14361436+ }14371437+14381438+ /* Data conversion */14391439+ if (skb_copy_flag) { /* recycle skb */14401440+ struct sk_buff *new_skb;14411441+ new_skb =14421442+ netdev_alloc_skb(netdev,14431443+ length + NET_IP_ALIGN);14441444+ if (new_skb) {14451445+ if (!skb_padding_flag) {14461446+ skb_reserve(new_skb,14471447+ NET_IP_ALIGN);14481448+ }14491449+ memcpy(new_skb->data, skb->data,14501450+ length);14511451+ /* save the skb14521452+ * in buffer_info as good */14531453+ skb = new_skb;14541454+ } else if (!skb_padding_flag) {14551455+ /* dorrop error */14561456+ pr_err("New skb allocation Error\n");14571457+ goto dorrop;14581458+ }14591459+ } else {14601460+ buffer_info->skb = NULL;14611461+ }14621462+ if (skb_padding_flag) {14631463+ memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN);14641464+ memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0],14651465+ ETH_HLEN);14661466+ skb_reserve(skb, NET_IP_ALIGN);14671467+14681468+ }14691469+14701470+ /* update status of driver */14711471+ adapter->stats.rx_bytes += length;14721472+ adapter->stats.rx_packets++;14731473+ if ((gbec_status & PCH_GBE_RXD_GMAC_STAT_MARMLT))14741474+ adapter->stats.multicast++;14751475+ /* Write meta date of skb */14761476+ skb_put(skb, length);14771477+ skb->protocol = eth_type_trans(skb, netdev);14781478+ if ((tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) ==14791479+ PCH_GBE_RXD_ACC_STAT_TCPIPOK) {14801480+ skb->ip_summed = CHECKSUM_UNNECESSARY;14811481+ } else {14821482+ skb->ip_summed = CHECKSUM_NONE;14831483+ }14841484+ napi_gro_receive(&adapter->napi, skb);14851485+ (*work_done)++;14861486+ pr_debug("Receive skb->ip_summed: %d length: %d\n",14871487+ skb->ip_summed, length);14881488+ }14891489+dorrop:14901490+ /* return some buffers to hardware, one at a time is too slow */14911491+ if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) {14921492+ pch_gbe_alloc_rx_buffers(adapter, rx_ring,14931493+ cleaned_count);14941494+ cleaned_count = 0;14951495+ }14961496+ if (++i == rx_ring->count)14971497+ i = 0;14981498+ }14991499+ rx_ring->next_to_clean = i;15001500+ if (cleaned_count)15011501+ pch_gbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);15021502+ return cleaned;15031503+}15041504+15051505+/**15061506+ * pch_gbe_setup_tx_resources - Allocate Tx resources (Descriptors)15071507+ * @adapter: Board private structure15081508+ * @tx_ring: Tx descriptor ring (for a specific queue) to setup15091509+ * Returns15101510+ * 0: Successfully15111511+ * Negative value: Failed15121512+ */15131513+int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,15141514+ struct pch_gbe_tx_ring *tx_ring)15151515+{15161516+ struct pci_dev *pdev = adapter->pdev;15171517+ struct pch_gbe_tx_desc *tx_desc;15181518+ int size;15191519+ int desNo;15201520+15211521+ size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count;15221522+ tx_ring->buffer_info = vmalloc(size);15231523+ if (!tx_ring->buffer_info) {15241524+ pr_err("Unable to allocate memory for the buffer infomation\n");15251525+ return -ENOMEM;15261526+ }15271527+ memset(tx_ring->buffer_info, 0, size);15281528+15291529+ tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc);15301530+15311531+ tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,15321532+ &tx_ring->dma, GFP_KERNEL);15331533+ if (!tx_ring->desc) {15341534+ vfree(tx_ring->buffer_info);15351535+ pr_err("Unable to allocate memory for the transmit descriptor ring\n");15361536+ return -ENOMEM;15371537+ }15381538+ memset(tx_ring->desc, 0, tx_ring->size);15391539+15401540+ tx_ring->next_to_use = 0;15411541+ tx_ring->next_to_clean = 0;15421542+ spin_lock_init(&tx_ring->tx_lock);15431543+15441544+ for (desNo = 0; desNo < tx_ring->count; desNo++) {15451545+ tx_desc = PCH_GBE_TX_DESC(*tx_ring, desNo);15461546+ tx_desc->gbec_status = DSC_INIT16;15471547+ }15481548+ pr_debug("tx_ring->desc = 0x%p tx_ring->dma = 0x%08llx\n"15491549+ "next_to_clean = 0x%08x next_to_use = 0x%08x\n",15501550+ tx_ring->desc, (unsigned long long)tx_ring->dma,15511551+ tx_ring->next_to_clean, tx_ring->next_to_use);15521552+ return 0;15531553+}15541554+15551555+/**15561556+ * pch_gbe_setup_rx_resources - Allocate Rx resources (Descriptors)15571557+ * @adapter: Board private structure15581558+ * @rx_ring: Rx descriptor ring (for a specific queue) to setup15591559+ * Returns15601560+ * 0: Successfully15611561+ * Negative value: Failed15621562+ */15631563+int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter,15641564+ struct pch_gbe_rx_ring *rx_ring)15651565+{15661566+ struct pci_dev *pdev = adapter->pdev;15671567+ struct pch_gbe_rx_desc *rx_desc;15681568+ int size;15691569+ int desNo;15701570+15711571+ size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count;15721572+ rx_ring->buffer_info = vmalloc(size);15731573+ if (!rx_ring->buffer_info) {15741574+ pr_err("Unable to allocate memory for the receive descriptor ring\n");15751575+ return -ENOMEM;15761576+ }15771577+ memset(rx_ring->buffer_info, 0, size);15781578+ rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc);15791579+ rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,15801580+ &rx_ring->dma, GFP_KERNEL);15811581+15821582+ if (!rx_ring->desc) {15831583+ pr_err("Unable to allocate memory for the receive descriptor ring\n");15841584+ vfree(rx_ring->buffer_info);15851585+ return -ENOMEM;15861586+ }15871587+ memset(rx_ring->desc, 0, rx_ring->size);15881588+ rx_ring->next_to_clean = 0;15891589+ rx_ring->next_to_use = 0;15901590+ for (desNo = 0; desNo < rx_ring->count; desNo++) {15911591+ rx_desc = PCH_GBE_RX_DESC(*rx_ring, desNo);15921592+ rx_desc->gbec_status = DSC_INIT16;15931593+ }15941594+ pr_debug("rx_ring->desc = 0x%p rx_ring->dma = 0x%08llx "15951595+ "next_to_clean = 0x%08x next_to_use = 0x%08x\n",15961596+ rx_ring->desc, (unsigned long long)rx_ring->dma,15971597+ rx_ring->next_to_clean, rx_ring->next_to_use);15981598+ return 0;15991599+}16001600+16011601+/**16021602+ * pch_gbe_free_tx_resources - Free Tx Resources16031603+ * @adapter: Board private structure16041604+ * @tx_ring: Tx descriptor ring for a specific queue16051605+ */16061606+void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter,16071607+ struct pch_gbe_tx_ring *tx_ring)16081608+{16091609+ struct pci_dev *pdev = adapter->pdev;16101610+16111611+ pch_gbe_clean_tx_ring(adapter, tx_ring);16121612+ vfree(tx_ring->buffer_info);16131613+ tx_ring->buffer_info = NULL;16141614+ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);16151615+ tx_ring->desc = NULL;16161616+}16171617+16181618+/**16191619+ * pch_gbe_free_rx_resources - Free Rx Resources16201620+ * @adapter: Board private structure16211621+ * @rx_ring: Ring to clean the resources from16221622+ */16231623+void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter,16241624+ struct pch_gbe_rx_ring *rx_ring)16251625+{16261626+ struct pci_dev *pdev = adapter->pdev;16271627+16281628+ pch_gbe_clean_rx_ring(adapter, rx_ring);16291629+ vfree(rx_ring->buffer_info);16301630+ rx_ring->buffer_info = NULL;16311631+ pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);16321632+ rx_ring->desc = NULL;16331633+}16341634+16351635+/**16361636+ * pch_gbe_request_irq - Allocate an interrupt line16371637+ * @adapter: Board private structure16381638+ * Returns16391639+ * 0: Successfully16401640+ * Negative value: Failed16411641+ */16421642+static int pch_gbe_request_irq(struct pch_gbe_adapter *adapter)16431643+{16441644+ struct net_device *netdev = adapter->netdev;16451645+ int err;16461646+ int flags;16471647+16481648+ flags = IRQF_SHARED;16491649+ adapter->have_msi = false;16501650+ err = pci_enable_msi(adapter->pdev);16511651+ pr_debug("call pci_enable_msi\n");16521652+ if (err) {16531653+ pr_debug("call pci_enable_msi - Error: %d\n", err);16541654+ } else {16551655+ flags = 0;16561656+ adapter->have_msi = true;16571657+ }16581658+ err = request_irq(adapter->pdev->irq, &pch_gbe_intr,16591659+ flags, netdev->name, netdev);16601660+ if (err)16611661+ pr_err("Unable to allocate interrupt Error: %d\n", err);16621662+ pr_debug("adapter->have_msi : %d flags : 0x%04x return : 0x%04x\n",16631663+ adapter->have_msi, flags, err);16641664+ return err;16651665+}16661666+16671667+16681668+static void pch_gbe_set_multi(struct net_device *netdev);16691669+/**16701670+ * pch_gbe_up - Up GbE network device16711671+ * @adapter: Board private structure16721672+ * Returns16731673+ * 0: Successfully16741674+ * Negative value: Failed16751675+ */16761676+int pch_gbe_up(struct pch_gbe_adapter *adapter)16771677+{16781678+ struct net_device *netdev = adapter->netdev;16791679+ struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;16801680+ struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;16811681+ int err;16821682+16831683+ /* hardware has been reset, we need to reload some things */16841684+ pch_gbe_set_multi(netdev);16851685+16861686+ pch_gbe_setup_tctl(adapter);16871687+ pch_gbe_configure_tx(adapter);16881688+ pch_gbe_setup_rctl(adapter);16891689+ pch_gbe_configure_rx(adapter);16901690+16911691+ err = pch_gbe_request_irq(adapter);16921692+ if (err) {16931693+ pr_err("Error: can't bring device up\n");16941694+ return err;16951695+ }16961696+ pch_gbe_alloc_tx_buffers(adapter, tx_ring);16971697+ pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);16981698+ adapter->tx_queue_len = netdev->tx_queue_len;16991699+17001700+ mod_timer(&adapter->watchdog_timer, jiffies);17011701+17021702+ napi_enable(&adapter->napi);17031703+ pch_gbe_irq_enable(adapter);17041704+ netif_start_queue(adapter->netdev);17051705+17061706+ return 0;17071707+}17081708+17091709+/**17101710+ * pch_gbe_down - Down GbE network device17111711+ * @adapter: Board private structure17121712+ */17131713+void pch_gbe_down(struct pch_gbe_adapter *adapter)17141714+{17151715+ struct net_device *netdev = adapter->netdev;17161716+17171717+ /* signal that we're down so the interrupt handler does not17181718+ * reschedule our watchdog timer */17191719+ napi_disable(&adapter->napi);17201720+ atomic_set(&adapter->irq_sem, 0);17211721+17221722+ pch_gbe_irq_disable(adapter);17231723+ pch_gbe_free_irq(adapter);17241724+17251725+ del_timer_sync(&adapter->watchdog_timer);17261726+17271727+ netdev->tx_queue_len = adapter->tx_queue_len;17281728+ netif_carrier_off(netdev);17291729+ netif_stop_queue(netdev);17301730+17311731+ pch_gbe_reset(adapter);17321732+ pch_gbe_clean_tx_ring(adapter, adapter->tx_ring);17331733+ pch_gbe_clean_rx_ring(adapter, adapter->rx_ring);17341734+}17351735+17361736+/**17371737+ * pch_gbe_sw_init - Initialize general software structures (struct pch_gbe_adapter)17381738+ * @adapter: Board private structure to initialize17391739+ * Returns17401740+ * 0: Successfully17411741+ * Negative value: Failed17421742+ */17431743+static int pch_gbe_sw_init(struct pch_gbe_adapter *adapter)17441744+{17451745+ struct pch_gbe_hw *hw = &adapter->hw;17461746+ struct net_device *netdev = adapter->netdev;17471747+17481748+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048;17491749+ hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;17501750+ hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN;17511751+17521752+ /* Initialize the hardware-specific values */17531753+ if (pch_gbe_hal_setup_init_funcs(hw)) {17541754+ pr_err("Hardware Initialization Failure\n");17551755+ return -EIO;17561756+ }17571757+ if (pch_gbe_alloc_queues(adapter)) {17581758+ pr_err("Unable to allocate memory for queues\n");17591759+ return -ENOMEM;17601760+ }17611761+ spin_lock_init(&adapter->hw.miim_lock);17621762+ spin_lock_init(&adapter->tx_queue_lock);17631763+ spin_lock_init(&adapter->stats_lock);17641764+ spin_lock_init(&adapter->ethtool_lock);17651765+ atomic_set(&adapter->irq_sem, 0);17661766+ pch_gbe_irq_disable(adapter);17671767+17681768+ pch_gbe_init_stats(adapter);17691769+17701770+ pr_debug("rx_buffer_len : %d mac.min_frame_size : %d mac.max_frame_size : %d\n",17711771+ (u32) adapter->rx_buffer_len,17721772+ hw->mac.min_frame_size, hw->mac.max_frame_size);17731773+ return 0;17741774+}17751775+17761776+/**17771777+ * pch_gbe_open - Called when a network interface is made active17781778+ * @netdev: Network interface device structure17791779+ * Returns17801780+ * 0: Successfully17811781+ * Negative value: Failed17821782+ */17831783+static int pch_gbe_open(struct net_device *netdev)17841784+{17851785+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);17861786+ struct pch_gbe_hw *hw = &adapter->hw;17871787+ int err;17881788+17891789+ /* allocate transmit descriptors */17901790+ err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);17911791+ if (err)17921792+ goto err_setup_tx;17931793+ /* allocate receive descriptors */17941794+ err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);17951795+ if (err)17961796+ goto err_setup_rx;17971797+ pch_gbe_hal_power_up_phy(hw);17981798+ err = pch_gbe_up(adapter);17991799+ if (err)18001800+ goto err_up;18011801+ pr_debug("Success End\n");18021802+ return 0;18031803+18041804+err_up:18051805+ if (!adapter->wake_up_evt)18061806+ pch_gbe_hal_power_down_phy(hw);18071807+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);18081808+err_setup_rx:18091809+ pch_gbe_free_tx_resources(adapter, adapter->tx_ring);18101810+err_setup_tx:18111811+ pch_gbe_reset(adapter);18121812+ pr_err("Error End\n");18131813+ return err;18141814+}18151815+18161816+/**18171817+ * pch_gbe_stop - Disables a network interface18181818+ * @netdev: Network interface device structure18191819+ * Returns18201820+ * 0: Successfully18211821+ */18221822+static int pch_gbe_stop(struct net_device *netdev)18231823+{18241824+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);18251825+ struct pch_gbe_hw *hw = &adapter->hw;18261826+18271827+ pch_gbe_down(adapter);18281828+ if (!adapter->wake_up_evt)18291829+ pch_gbe_hal_power_down_phy(hw);18301830+ pch_gbe_free_tx_resources(adapter, adapter->tx_ring);18311831+ pch_gbe_free_rx_resources(adapter, adapter->rx_ring);18321832+ return 0;18331833+}18341834+18351835+/**18361836+ * pch_gbe_xmit_frame - Packet transmitting start18371837+ * @skb: Socket buffer structure18381838+ * @netdev: Network interface device structure18391839+ * Returns18401840+ * - NETDEV_TX_OK: Normal end18411841+ * - NETDEV_TX_BUSY: Error end18421842+ */18431843+static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)18441844+{18451845+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);18461846+ struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;18471847+ unsigned long flags;18481848+18491849+ if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) {18501850+ dev_kfree_skb_any(skb);18511851+ pr_err("Transfer length Error: skb len: %d > max: %d\n",18521852+ skb->len, adapter->hw.mac.max_frame_size);18531853+ adapter->stats.tx_length_errors++;18541854+ return NETDEV_TX_OK;18551855+ }18561856+ if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {18571857+ /* Collision - tell upper layer to requeue */18581858+ return NETDEV_TX_LOCKED;18591859+ }18601860+ if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) {18611861+ netif_stop_queue(netdev);18621862+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);18631863+ pr_debug("Return : BUSY next_to use : 0x%08x next_to clean : 0x%08x\n",18641864+ tx_ring->next_to_use, tx_ring->next_to_clean);18651865+ return NETDEV_TX_BUSY;18661866+ }18671867+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);18681868+18691869+ /* CRC,ITAG no support */18701870+ pch_gbe_tx_queue(adapter, tx_ring, skb);18711871+ return NETDEV_TX_OK;18721872+}18731873+18741874+/**18751875+ * pch_gbe_get_stats - Get System Network Statistics18761876+ * @netdev: Network interface device structure18771877+ * Returns: The current stats18781878+ */18791879+static struct net_device_stats *pch_gbe_get_stats(struct net_device *netdev)18801880+{18811881+ /* only return the current stats */18821882+ return &netdev->stats;18831883+}18841884+18851885+/**18861886+ * pch_gbe_set_multi - Multicast and Promiscuous mode set18871887+ * @netdev: Network interface device structure18881888+ */18891889+static void pch_gbe_set_multi(struct net_device *netdev)18901890+{18911891+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);18921892+ struct pch_gbe_hw *hw = &adapter->hw;18931893+ struct netdev_hw_addr *ha;18941894+ u8 *mta_list;18951895+ u32 rctl;18961896+ int i;18971897+ int mc_count;18981898+18991899+ pr_debug("netdev->flags : 0x%08x\n", netdev->flags);19001900+19011901+ /* Check for Promiscuous and All Multicast modes */19021902+ rctl = ioread32(&hw->reg->RX_MODE);19031903+ mc_count = netdev_mc_count(netdev);19041904+ if ((netdev->flags & IFF_PROMISC)) {19051905+ rctl &= ~PCH_GBE_ADD_FIL_EN;19061906+ rctl &= ~PCH_GBE_MLT_FIL_EN;19071907+ } else if ((netdev->flags & IFF_ALLMULTI)) {19081908+ /* all the multicasting receive permissions */19091909+ rctl |= PCH_GBE_ADD_FIL_EN;19101910+ rctl &= ~PCH_GBE_MLT_FIL_EN;19111911+ } else {19121912+ if (mc_count >= PCH_GBE_MAR_ENTRIES) {19131913+ /* all the multicasting receive permissions */19141914+ rctl |= PCH_GBE_ADD_FIL_EN;19151915+ rctl &= ~PCH_GBE_MLT_FIL_EN;19161916+ } else {19171917+ rctl |= (PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN);19181918+ }19191919+ }19201920+ iowrite32(rctl, &hw->reg->RX_MODE);19211921+19221922+ if (mc_count >= PCH_GBE_MAR_ENTRIES)19231923+ return;19241924+ mta_list = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);19251925+ if (!mta_list)19261926+ return;19271927+19281928+ /* The shared function expects a packed array of only addresses. */19291929+ i = 0;19301930+ netdev_for_each_mc_addr(ha, netdev) {19311931+ if (i == mc_count)19321932+ break;19331933+ memcpy(mta_list + (i++ * ETH_ALEN), &ha->addr, ETH_ALEN);19341934+ }19351935+ pch_gbe_mac_mc_addr_list_update(hw, mta_list, i, 1,19361936+ PCH_GBE_MAR_ENTRIES);19371937+ kfree(mta_list);19381938+19391939+ pr_debug("RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x netdev->mc_count : 0x%08x\n",19401940+ ioread32(&hw->reg->RX_MODE), mc_count);19411941+}19421942+19431943+/**19441944+ * pch_gbe_set_mac - Change the Ethernet Address of the NIC19451945+ * @netdev: Network interface device structure19461946+ * @addr: Pointer to an address structure19471947+ * Returns19481948+ * 0: Successfully19491949+ * -EADDRNOTAVAIL: Failed19501950+ */19511951+static int pch_gbe_set_mac(struct net_device *netdev, void *addr)19521952+{19531953+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);19541954+ struct sockaddr *skaddr = addr;19551955+ int ret_val;19561956+19571957+ if (!is_valid_ether_addr(skaddr->sa_data)) {19581958+ ret_val = -EADDRNOTAVAIL;19591959+ } else {19601960+ memcpy(netdev->dev_addr, skaddr->sa_data, netdev->addr_len);19611961+ memcpy(adapter->hw.mac.addr, skaddr->sa_data, netdev->addr_len);19621962+ pch_gbe_mac_mar_set(&adapter->hw, adapter->hw.mac.addr, 0);19631963+ ret_val = 0;19641964+ }19651965+ pr_debug("ret_val : 0x%08x\n", ret_val);19661966+ pr_debug("dev_addr : %pM\n", netdev->dev_addr);19671967+ pr_debug("mac_addr : %pM\n", adapter->hw.mac.addr);19681968+ pr_debug("MAC_ADR1AB reg : 0x%08x 0x%08x\n",19691969+ ioread32(&adapter->hw.reg->mac_adr[0].high),19701970+ ioread32(&adapter->hw.reg->mac_adr[0].low));19711971+ return ret_val;19721972+}19731973+19741974+/**19751975+ * pch_gbe_change_mtu - Change the Maximum Transfer Unit19761976+ * @netdev: Network interface device structure19771977+ * @new_mtu: New value for maximum frame size19781978+ * Returns19791979+ * 0: Successfully19801980+ * -EINVAL: Failed19811981+ */19821982+static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)19831983+{19841984+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);19851985+ int max_frame;19861986+19871987+ max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;19881988+ if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||19891989+ (max_frame > PCH_GBE_MAX_JUMBO_FRAME_SIZE)) {19901990+ pr_err("Invalid MTU setting\n");19911991+ return -EINVAL;19921992+ }19931993+ if (max_frame <= PCH_GBE_FRAME_SIZE_2048)19941994+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048;19951995+ else if (max_frame <= PCH_GBE_FRAME_SIZE_4096)19961996+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_4096;19971997+ else if (max_frame <= PCH_GBE_FRAME_SIZE_8192)19981998+ adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_8192;19991999+ else20002000+ adapter->rx_buffer_len = PCH_GBE_MAX_JUMBO_FRAME_SIZE;20012001+ netdev->mtu = new_mtu;20022002+ adapter->hw.mac.max_frame_size = max_frame;20032003+20042004+ if (netif_running(netdev))20052005+ pch_gbe_reinit_locked(adapter);20062006+ else20072007+ pch_gbe_reset(adapter);20082008+20092009+ pr_debug("max_frame : %d rx_buffer_len : %d mtu : %d max_frame_size : %d\n",20102010+ max_frame, (u32) adapter->rx_buffer_len, netdev->mtu,20112011+ adapter->hw.mac.max_frame_size);20122012+ return 0;20132013+}20142014+20152015+/**20162016+ * pch_gbe_ioctl - Controls register through a MII interface20172017+ * @netdev: Network interface device structure20182018+ * @ifr: Pointer to ifr structure20192019+ * @cmd: Control command20202020+ * Returns20212021+ * 0: Successfully20222022+ * Negative value: Failed20232023+ */20242024+static int pch_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)20252025+{20262026+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);20272027+20282028+ pr_debug("cmd : 0x%04x\n", cmd);20292029+20302030+ return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);20312031+}20322032+20332033+/**20342034+ * pch_gbe_tx_timeout - Respond to a Tx Hang20352035+ * @netdev: Network interface device structure20362036+ */20372037+static void pch_gbe_tx_timeout(struct net_device *netdev)20382038+{20392039+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);20402040+20412041+ /* Do the reset outside of interrupt context */20422042+ adapter->stats.tx_timeout_count++;20432043+ schedule_work(&adapter->reset_task);20442044+}20452045+20462046+/**20472047+ * pch_gbe_napi_poll - NAPI receive and transfer polling callback20482048+ * @napi: Pointer of polling device struct20492049+ * @budget: The maximum number of a packet20502050+ * Returns20512051+ * false: Exit the polling mode20522052+ * true: Continue the polling mode20532053+ */20542054+static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)20552055+{20562056+ struct pch_gbe_adapter *adapter =20572057+ container_of(napi, struct pch_gbe_adapter, napi);20582058+ struct net_device *netdev = adapter->netdev;20592059+ int work_done = 0;20602060+ bool poll_end_flag = false;20612061+ bool cleaned = false;20622062+20632063+ pr_debug("budget : %d\n", budget);20642064+20652065+ /* Keep link state information with original netdev */20662066+ if (!netif_carrier_ok(netdev)) {20672067+ poll_end_flag = true;20682068+ } else {20692069+ cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);20702070+ pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);20712071+20722072+ if (cleaned)20732073+ work_done = budget;20742074+ /* If no Tx and not enough Rx work done,20752075+ * exit the polling mode20762076+ */20772077+ if ((work_done < budget) || !netif_running(netdev))20782078+ poll_end_flag = true;20792079+ }20802080+20812081+ if (poll_end_flag) {20822082+ napi_complete(napi);20832083+ pch_gbe_irq_enable(adapter);20842084+ }20852085+20862086+ pr_debug("poll_end_flag : %d work_done : %d budget : %d\n",20872087+ poll_end_flag, work_done, budget);20882088+20892089+ return work_done;20902090+}20912091+20922092+#ifdef CONFIG_NET_POLL_CONTROLLER20932093+/**20942094+ * pch_gbe_netpoll - Used by things like netconsole to send skbs20952095+ * @netdev: Network interface device structure20962096+ */20972097+static void pch_gbe_netpoll(struct net_device *netdev)20982098+{20992099+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);21002100+21012101+ disable_irq(adapter->pdev->irq);21022102+ pch_gbe_intr(adapter->pdev->irq, netdev);21032103+ enable_irq(adapter->pdev->irq);21042104+}21052105+#endif21062106+21072107+static const struct net_device_ops pch_gbe_netdev_ops = {21082108+ .ndo_open = pch_gbe_open,21092109+ .ndo_stop = pch_gbe_stop,21102110+ .ndo_start_xmit = pch_gbe_xmit_frame,21112111+ .ndo_get_stats = pch_gbe_get_stats,21122112+ .ndo_set_mac_address = pch_gbe_set_mac,21132113+ .ndo_tx_timeout = pch_gbe_tx_timeout,21142114+ .ndo_change_mtu = pch_gbe_change_mtu,21152115+ .ndo_do_ioctl = pch_gbe_ioctl,21162116+ .ndo_set_multicast_list = &pch_gbe_set_multi,21172117+#ifdef CONFIG_NET_POLL_CONTROLLER21182118+ .ndo_poll_controller = pch_gbe_netpoll,21192119+#endif21202120+};21212121+21222122+static pci_ers_result_t pch_gbe_io_error_detected(struct pci_dev *pdev,21232123+ pci_channel_state_t state)21242124+{21252125+ struct net_device *netdev = pci_get_drvdata(pdev);21262126+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);21272127+21282128+ netif_device_detach(netdev);21292129+ if (netif_running(netdev))21302130+ pch_gbe_down(adapter);21312131+ pci_disable_device(pdev);21322132+ /* Request a slot slot reset. */21332133+ return PCI_ERS_RESULT_NEED_RESET;21342134+}21352135+21362136+static pci_ers_result_t pch_gbe_io_slot_reset(struct pci_dev *pdev)21372137+{21382138+ struct net_device *netdev = pci_get_drvdata(pdev);21392139+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);21402140+ struct pch_gbe_hw *hw = &adapter->hw;21412141+21422142+ if (pci_enable_device(pdev)) {21432143+ pr_err("Cannot re-enable PCI device after reset\n");21442144+ return PCI_ERS_RESULT_DISCONNECT;21452145+ }21462146+ pci_set_master(pdev);21472147+ pci_enable_wake(pdev, PCI_D0, 0);21482148+ pch_gbe_hal_power_up_phy(hw);21492149+ pch_gbe_reset(adapter);21502150+ /* Clear wake up status */21512151+ pch_gbe_mac_set_wol_event(hw, 0);21522152+21532153+ return PCI_ERS_RESULT_RECOVERED;21542154+}21552155+21562156+static void pch_gbe_io_resume(struct pci_dev *pdev)21572157+{21582158+ struct net_device *netdev = pci_get_drvdata(pdev);21592159+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);21602160+21612161+ if (netif_running(netdev)) {21622162+ if (pch_gbe_up(adapter)) {21632163+ pr_debug("can't bring device back up after reset\n");21642164+ return;21652165+ }21662166+ }21672167+ netif_device_attach(netdev);21682168+}21692169+21702170+static int __pch_gbe_suspend(struct pci_dev *pdev)21712171+{21722172+ struct net_device *netdev = pci_get_drvdata(pdev);21732173+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);21742174+ struct pch_gbe_hw *hw = &adapter->hw;21752175+ u32 wufc = adapter->wake_up_evt;21762176+ int retval = 0;21772177+21782178+ netif_device_detach(netdev);21792179+ if (netif_running(netdev))21802180+ pch_gbe_down(adapter);21812181+ if (wufc) {21822182+ pch_gbe_set_multi(netdev);21832183+ pch_gbe_setup_rctl(adapter);21842184+ pch_gbe_configure_rx(adapter);21852185+ pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,21862186+ hw->mac.link_duplex);21872187+ pch_gbe_set_mode(adapter, hw->mac.link_speed,21882188+ hw->mac.link_duplex);21892189+ pch_gbe_mac_set_wol_event(hw, wufc);21902190+ pci_disable_device(pdev);21912191+ } else {21922192+ pch_gbe_hal_power_down_phy(hw);21932193+ pch_gbe_mac_set_wol_event(hw, wufc);21942194+ pci_disable_device(pdev);21952195+ }21962196+ return retval;21972197+}21982198+21992199+#ifdef CONFIG_PM22002200+static int pch_gbe_suspend(struct device *device)22012201+{22022202+ struct pci_dev *pdev = to_pci_dev(device);22032203+22042204+ return __pch_gbe_suspend(pdev);22052205+}22062206+22072207+static int pch_gbe_resume(struct device *device)22082208+{22092209+ struct pci_dev *pdev = to_pci_dev(device);22102210+ struct net_device *netdev = pci_get_drvdata(pdev);22112211+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);22122212+ struct pch_gbe_hw *hw = &adapter->hw;22132213+ u32 err;22142214+22152215+ err = pci_enable_device(pdev);22162216+ if (err) {22172217+ pr_err("Cannot enable PCI device from suspend\n");22182218+ return err;22192219+ }22202220+ pci_set_master(pdev);22212221+ pch_gbe_hal_power_up_phy(hw);22222222+ pch_gbe_reset(adapter);22232223+ /* Clear wake on lan control and status */22242224+ pch_gbe_mac_set_wol_event(hw, 0);22252225+22262226+ if (netif_running(netdev))22272227+ pch_gbe_up(adapter);22282228+ netif_device_attach(netdev);22292229+22302230+ return 0;22312231+}22322232+#endif /* CONFIG_PM */22332233+22342234+static void pch_gbe_shutdown(struct pci_dev *pdev)22352235+{22362236+ __pch_gbe_suspend(pdev);22372237+ if (system_state == SYSTEM_POWER_OFF) {22382238+ pci_wake_from_d3(pdev, true);22392239+ pci_set_power_state(pdev, PCI_D3hot);22402240+ }22412241+}22422242+22432243+static void pch_gbe_remove(struct pci_dev *pdev)22442244+{22452245+ struct net_device *netdev = pci_get_drvdata(pdev);22462246+ struct pch_gbe_adapter *adapter = netdev_priv(netdev);22472247+22482248+ flush_scheduled_work();22492249+ unregister_netdev(netdev);22502250+22512251+ pch_gbe_hal_phy_hw_reset(&adapter->hw);22522252+22532253+ kfree(adapter->tx_ring);22542254+ kfree(adapter->rx_ring);22552255+22562256+ iounmap(adapter->hw.reg);22572257+ pci_release_regions(pdev);22582258+ free_netdev(netdev);22592259+ pci_disable_device(pdev);22602260+}22612261+22622262+static int pch_gbe_probe(struct pci_dev *pdev,22632263+ const struct pci_device_id *pci_id)22642264+{22652265+ struct net_device *netdev;22662266+ struct pch_gbe_adapter *adapter;22672267+ int ret;22682268+22692269+ ret = pci_enable_device(pdev);22702270+ if (ret)22712271+ return ret;22722272+22732273+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))22742274+ || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {22752275+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));22762276+ if (ret) {22772277+ ret = pci_set_consistent_dma_mask(pdev,22782278+ DMA_BIT_MASK(32));22792279+ if (ret) {22802280+ dev_err(&pdev->dev, "ERR: No usable DMA "22812281+ "configuration, aborting\n");22822282+ goto err_disable_device;22832283+ }22842284+ }22852285+ }22862286+22872287+ ret = pci_request_regions(pdev, KBUILD_MODNAME);22882288+ if (ret) {22892289+ dev_err(&pdev->dev,22902290+ "ERR: Can't reserve PCI I/O and memory resources\n");22912291+ goto err_disable_device;22922292+ }22932293+ pci_set_master(pdev);22942294+22952295+ netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter));22962296+ if (!netdev) {22972297+ ret = -ENOMEM;22982298+ dev_err(&pdev->dev,22992299+ "ERR: Can't allocate and set up an Ethernet device\n");23002300+ goto err_release_pci;23012301+ }23022302+ SET_NETDEV_DEV(netdev, &pdev->dev);23032303+23042304+ pci_set_drvdata(pdev, netdev);23052305+ adapter = netdev_priv(netdev);23062306+ adapter->netdev = netdev;23072307+ adapter->pdev = pdev;23082308+ adapter->hw.back = adapter;23092309+ adapter->hw.reg = pci_iomap(pdev, PCH_GBE_PCI_BAR, 0);23102310+ if (!adapter->hw.reg) {23112311+ ret = -EIO;23122312+ dev_err(&pdev->dev, "Can't ioremap\n");23132313+ goto err_free_netdev;23142314+ }23152315+23162316+ netdev->netdev_ops = &pch_gbe_netdev_ops;23172317+ netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;23182318+ netif_napi_add(netdev, &adapter->napi,23192319+ pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT);23202320+ netdev->features = NETIF_F_HW_CSUM | NETIF_F_GRO;23212321+ pch_gbe_set_ethtool_ops(netdev);23222322+23232323+ pch_gbe_mac_reset_hw(&adapter->hw);23242324+23252325+ /* setup the private structure */23262326+ ret = pch_gbe_sw_init(adapter);23272327+ if (ret)23282328+ goto err_iounmap;23292329+23302330+ /* Initialize PHY */23312331+ ret = pch_gbe_init_phy(adapter);23322332+ if (ret) {23332333+ dev_err(&pdev->dev, "PHY initialize error\n");23342334+ goto err_free_adapter;23352335+ }23362336+ pch_gbe_hal_get_bus_info(&adapter->hw);23372337+23382338+ /* Read the MAC address. and store to the private data */23392339+ ret = pch_gbe_hal_read_mac_addr(&adapter->hw);23402340+ if (ret) {23412341+ dev_err(&pdev->dev, "MAC address Read Error\n");23422342+ goto err_free_adapter;23432343+ }23442344+23452345+ memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);23462346+ if (!is_valid_ether_addr(netdev->dev_addr)) {23472347+ dev_err(&pdev->dev, "Invalid MAC Address\n");23482348+ ret = -EIO;23492349+ goto err_free_adapter;23502350+ }23512351+ setup_timer(&adapter->watchdog_timer, pch_gbe_watchdog,23522352+ (unsigned long)adapter);23532353+23542354+ INIT_WORK(&adapter->reset_task, pch_gbe_reset_task);23552355+23562356+ pch_gbe_check_options(adapter);23572357+23582358+ if (adapter->tx_csum)23592359+ netdev->features |= NETIF_F_HW_CSUM;23602360+ else23612361+ netdev->features &= ~NETIF_F_HW_CSUM;23622362+23632363+ /* initialize the wol settings based on the eeprom settings */23642364+ adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;23652365+ dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr);23662366+23672367+ /* reset the hardware with the new settings */23682368+ pch_gbe_reset(adapter);23692369+23702370+ ret = register_netdev(netdev);23712371+ if (ret)23722372+ goto err_free_adapter;23732373+ /* tell the stack to leave us alone until pch_gbe_open() is called */23742374+ netif_carrier_off(netdev);23752375+ netif_stop_queue(netdev);23762376+23772377+ dev_dbg(&pdev->dev, "OKIsemi(R) PCH Network Connection\n");23782378+23792379+ device_set_wakeup_enable(&pdev->dev, 1);23802380+ return 0;23812381+23822382+err_free_adapter:23832383+ pch_gbe_hal_phy_hw_reset(&adapter->hw);23842384+ kfree(adapter->tx_ring);23852385+ kfree(adapter->rx_ring);23862386+err_iounmap:23872387+ iounmap(adapter->hw.reg);23882388+err_free_netdev:23892389+ free_netdev(netdev);23902390+err_release_pci:23912391+ pci_release_regions(pdev);23922392+err_disable_device:23932393+ pci_disable_device(pdev);23942394+ return ret;23952395+}23962396+23972397+static const struct pci_device_id pch_gbe_pcidev_id[] = {23982398+ {.vendor = PCI_VENDOR_ID_INTEL,23992399+ .device = PCI_DEVICE_ID_INTEL_IOH1_GBE,24002400+ .subvendor = PCI_ANY_ID,24012401+ .subdevice = PCI_ANY_ID,24022402+ .class = (PCI_CLASS_NETWORK_ETHERNET << 8),24032403+ .class_mask = (0xFFFF00)24042404+ },24052405+ /* required last entry */24062406+ {0}24072407+};24082408+24092409+#ifdef CONFIG_PM24102410+static const struct dev_pm_ops pch_gbe_pm_ops = {24112411+ .suspend = pch_gbe_suspend,24122412+ .resume = pch_gbe_resume,24132413+ .freeze = pch_gbe_suspend,24142414+ .thaw = pch_gbe_resume,24152415+ .poweroff = pch_gbe_suspend,24162416+ .restore = pch_gbe_resume,24172417+};24182418+#endif24192419+24202420+static struct pci_error_handlers pch_gbe_err_handler = {24212421+ .error_detected = pch_gbe_io_error_detected,24222422+ .slot_reset = pch_gbe_io_slot_reset,24232423+ .resume = pch_gbe_io_resume24242424+};24252425+24262426+static struct pci_driver pch_gbe_pcidev = {24272427+ .name = KBUILD_MODNAME,24282428+ .id_table = pch_gbe_pcidev_id,24292429+ .probe = pch_gbe_probe,24302430+ .remove = pch_gbe_remove,24312431+#ifdef CONFIG_PM_OPS24322432+ .driver.pm = &pch_gbe_pm_ops,24332433+#endif24342434+ .shutdown = pch_gbe_shutdown,24352435+ .err_handler = &pch_gbe_err_handler24362436+};24372437+24382438+24392439+static int __init pch_gbe_init_module(void)24402440+{24412441+ int ret;24422442+24432443+ ret = pci_register_driver(&pch_gbe_pcidev);24442444+ if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) {24452445+ if (copybreak == 0) {24462446+ pr_info("copybreak disabled\n");24472447+ } else {24482448+ pr_info("copybreak enabled for packets <= %u bytes\n",24492449+ copybreak);24502450+ }24512451+ }24522452+ return ret;24532453+}24542454+24552455+static void __exit pch_gbe_exit_module(void)24562456+{24572457+ pci_unregister_driver(&pch_gbe_pcidev);24582458+}24592459+24602460+module_init(pch_gbe_init_module);24612461+module_exit(pch_gbe_exit_module);24622462+24632463+MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver");24642464+MODULE_AUTHOR("OKI semiconductor, <masa-korg@dsn.okisemi.com>");24652465+MODULE_LICENSE("GPL");24662466+MODULE_VERSION(DRV_VERSION);24672467+MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id);24682468+24692469+module_param(copybreak, uint, 0644);24702470+MODULE_PARM_DESC(copybreak,24712471+ "Maximum size of packet that is copied to a new buffer on receive");24722472+24732473+/* pch_gbe_main.c */
+499
drivers/net/pch_gbe/pch_gbe_param.c
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+2121+#include "pch_gbe.h"2222+2323+#define OPTION_UNSET -12424+#define OPTION_DISABLED 02525+#define OPTION_ENABLED 12626+2727+/**2828+ * TxDescriptors - Transmit Descriptor Count2929+ * @Valid Range: PCH_GBE_MIN_TXD - PCH_GBE_MAX_TXD3030+ * @Default Value: PCH_GBE_DEFAULT_TXD3131+ */3232+static int TxDescriptors = OPTION_UNSET;3333+module_param(TxDescriptors, int, 0);3434+MODULE_PARM_DESC(TxDescriptors, "Number of transmit descriptors");3535+3636+/**3737+ * RxDescriptors -Receive Descriptor Count3838+ * @Valid Range: PCH_GBE_MIN_RXD - PCH_GBE_MAX_RXD3939+ * @Default Value: PCH_GBE_DEFAULT_RXD4040+ */4141+static int RxDescriptors = OPTION_UNSET;4242+module_param(RxDescriptors, int, 0);4343+MODULE_PARM_DESC(RxDescriptors, "Number of receive descriptors");4444+4545+/**4646+ * Speed - User Specified Speed Override4747+ * @Valid Range: 0, 10, 100, 10004848+ * - 0: auto-negotiate at all supported speeds4949+ * - 10: only link at 10 Mbps5050+ * - 100: only link at 100 Mbps5151+ * - 1000: only link at 1000 Mbps5252+ * @Default Value: 05353+ */5454+static int Speed = OPTION_UNSET;5555+module_param(Speed, int, 0);5656+MODULE_PARM_DESC(Speed, "Speed setting");5757+5858+/**5959+ * Duplex - User Specified Duplex Override6060+ * @Valid Range: 0-26161+ * - 0: auto-negotiate for duplex6262+ * - 1: only link at half duplex6363+ * - 2: only link at full duplex6464+ * @Default Value: 06565+ */6666+static int Duplex = OPTION_UNSET;6767+module_param(Duplex, int, 0);6868+MODULE_PARM_DESC(Duplex, "Duplex setting");6969+7070+#define HALF_DUPLEX 17171+#define FULL_DUPLEX 27272+7373+/**7474+ * AutoNeg - Auto-negotiation Advertisement Override7575+ * @Valid Range: 0x01-0x0F, 0x20-0x2F7676+ *7777+ * The AutoNeg value is a bit mask describing which speed and duplex7878+ * combinations should be advertised during auto-negotiation.7979+ * The supported speed and duplex modes are listed below8080+ *8181+ * Bit 7 6 5 4 3 2 1 08282+ * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 108383+ * Duplex Full Full Half Full Half8484+ *8585+ * @Default Value: 0x2F (copper)8686+ */8787+static int AutoNeg = OPTION_UNSET;8888+module_param(AutoNeg, int, 0);8989+MODULE_PARM_DESC(AutoNeg, "Advertised auto-negotiation setting");9090+9191+#define PHY_ADVERTISE_10_HALF 0x00019292+#define PHY_ADVERTISE_10_FULL 0x00029393+#define PHY_ADVERTISE_100_HALF 0x00049494+#define PHY_ADVERTISE_100_FULL 0x00089595+#define PHY_ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */9696+#define PHY_ADVERTISE_1000_FULL 0x00209797+#define PCH_AUTONEG_ADVERTISE_DEFAULT 0x2F9898+9999+/**100100+ * FlowControl - User Specified Flow Control Override101101+ * @Valid Range: 0-3102102+ * - 0: No Flow Control103103+ * - 1: Rx only, respond to PAUSE frames but do not generate them104104+ * - 2: Tx only, generate PAUSE frames but ignore them on receive105105+ * - 3: Full Flow Control Support106106+ * @Default Value: Read flow control settings from the EEPROM107107+ */108108+static int FlowControl = OPTION_UNSET;109109+module_param(FlowControl, int, 0);110110+MODULE_PARM_DESC(FlowControl, "Flow Control setting");111111+112112+/*113113+ * XsumRX - Receive Checksum Offload Enable/Disable114114+ * @Valid Range: 0, 1115115+ * - 0: disables all checksum offload116116+ * - 1: enables receive IP/TCP/UDP checksum offload117117+ * @Default Value: PCH_GBE_DEFAULT_RX_CSUM118118+ */119119+static int XsumRX = OPTION_UNSET;120120+module_param(XsumRX, int, 0);121121+MODULE_PARM_DESC(XsumRX, "Disable or enable Receive Checksum offload");122122+123123+#define PCH_GBE_DEFAULT_RX_CSUM true /* trueorfalse */124124+125125+/*126126+ * XsumTX - Transmit Checksum Offload Enable/Disable127127+ * @Valid Range: 0, 1128128+ * - 0: disables all checksum offload129129+ * - 1: enables transmit IP/TCP/UDP checksum offload130130+ * @Default Value: PCH_GBE_DEFAULT_TX_CSUM131131+ */132132+static int XsumTX = OPTION_UNSET;133133+module_param(XsumTX, int, 0);134134+MODULE_PARM_DESC(XsumTX, "Disable or enable Transmit Checksum offload");135135+136136+#define PCH_GBE_DEFAULT_TX_CSUM true /* trueorfalse */137137+138138+/**139139+ * pch_gbe_option - Force the MAC's flow control settings140140+ * @hw: Pointer to the HW structure141141+ * Returns142142+ * 0: Successful.143143+ * Negative value: Failed.144144+ */145145+struct pch_gbe_option {146146+ enum { enable_option, range_option, list_option } type;147147+ char *name;148148+ char *err;149149+ int def;150150+ union {151151+ struct { /* range_option info */152152+ int min;153153+ int max;154154+ } r;155155+ struct { /* list_option info */156156+ int nr;157157+ const struct pch_gbe_opt_list { int i; char *str; } *p;158158+ } l;159159+ } arg;160160+};161161+162162+static const struct pch_gbe_opt_list speed_list[] = {163163+ { 0, "" },164164+ { SPEED_10, "" },165165+ { SPEED_100, "" },166166+ { SPEED_1000, "" }167167+};168168+169169+static const struct pch_gbe_opt_list dplx_list[] = {170170+ { 0, "" },171171+ { HALF_DUPLEX, "" },172172+ { FULL_DUPLEX, "" }173173+};174174+175175+static const struct pch_gbe_opt_list an_list[] =176176+ #define AA "AutoNeg advertising "177177+ {{ 0x01, AA "10/HD" },178178+ { 0x02, AA "10/FD" },179179+ { 0x03, AA "10/FD, 10/HD" },180180+ { 0x04, AA "100/HD" },181181+ { 0x05, AA "100/HD, 10/HD" },182182+ { 0x06, AA "100/HD, 10/FD" },183183+ { 0x07, AA "100/HD, 10/FD, 10/HD" },184184+ { 0x08, AA "100/FD" },185185+ { 0x09, AA "100/FD, 10/HD" },186186+ { 0x0a, AA "100/FD, 10/FD" },187187+ { 0x0b, AA "100/FD, 10/FD, 10/HD" },188188+ { 0x0c, AA "100/FD, 100/HD" },189189+ { 0x0d, AA "100/FD, 100/HD, 10/HD" },190190+ { 0x0e, AA "100/FD, 100/HD, 10/FD" },191191+ { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },192192+ { 0x20, AA "1000/FD" },193193+ { 0x21, AA "1000/FD, 10/HD" },194194+ { 0x22, AA "1000/FD, 10/FD" },195195+ { 0x23, AA "1000/FD, 10/FD, 10/HD" },196196+ { 0x24, AA "1000/FD, 100/HD" },197197+ { 0x25, AA "1000/FD, 100/HD, 10/HD" },198198+ { 0x26, AA "1000/FD, 100/HD, 10/FD" },199199+ { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },200200+ { 0x28, AA "1000/FD, 100/FD" },201201+ { 0x29, AA "1000/FD, 100/FD, 10/HD" },202202+ { 0x2a, AA "1000/FD, 100/FD, 10/FD" },203203+ { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },204204+ { 0x2c, AA "1000/FD, 100/FD, 100/HD" },205205+ { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },206206+ { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },207207+ { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }208208+};209209+210210+static const struct pch_gbe_opt_list fc_list[] = {211211+ { PCH_GBE_FC_NONE, "Flow Control Disabled" },212212+ { PCH_GBE_FC_RX_PAUSE, "Flow Control Receive Only" },213213+ { PCH_GBE_FC_TX_PAUSE, "Flow Control Transmit Only" },214214+ { PCH_GBE_FC_FULL, "Flow Control Enabled" }215215+};216216+217217+/**218218+ * pch_gbe_validate_option - Validate option219219+ * @value: value220220+ * @opt: option221221+ * @adapter: Board private structure222222+ * Returns223223+ * 0: Successful.224224+ * Negative value: Failed.225225+ */226226+static int pch_gbe_validate_option(int *value,227227+ const struct pch_gbe_option *opt,228228+ struct pch_gbe_adapter *adapter)229229+{230230+ if (*value == OPTION_UNSET) {231231+ *value = opt->def;232232+ return 0;233233+ }234234+235235+ switch (opt->type) {236236+ case enable_option:237237+ switch (*value) {238238+ case OPTION_ENABLED:239239+ pr_debug("%s Enabled\n", opt->name);240240+ return 0;241241+ case OPTION_DISABLED:242242+ pr_debug("%s Disabled\n", opt->name);243243+ return 0;244244+ }245245+ break;246246+ case range_option:247247+ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {248248+ pr_debug("%s set to %i\n", opt->name, *value);249249+ return 0;250250+ }251251+ break;252252+ case list_option: {253253+ int i;254254+ const struct pch_gbe_opt_list *ent;255255+256256+ for (i = 0; i < opt->arg.l.nr; i++) {257257+ ent = &opt->arg.l.p[i];258258+ if (*value == ent->i) {259259+ if (ent->str[0] != '\0')260260+ pr_debug("%s\n", ent->str);261261+ return 0;262262+ }263263+ }264264+ }265265+ break;266266+ default:267267+ BUG();268268+ }269269+270270+ pr_debug("Invalid %s value specified (%i) %s\n",271271+ opt->name, *value, opt->err);272272+ *value = opt->def;273273+ return -1;274274+}275275+276276+/**277277+ * pch_gbe_check_copper_options - Range Checking for Link Options, Copper Version278278+ * @adapter: Board private structure279279+ */280280+static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter)281281+{282282+ struct pch_gbe_hw *hw = &adapter->hw;283283+ int speed, dplx;284284+285285+ { /* Speed */286286+ static const struct pch_gbe_option opt = {287287+ .type = list_option,288288+ .name = "Speed",289289+ .err = "parameter ignored",290290+ .def = 0,291291+ .arg = { .l = { .nr = (int)ARRAY_SIZE(speed_list),292292+ .p = speed_list } }293293+ };294294+ speed = Speed;295295+ pch_gbe_validate_option(&speed, &opt, adapter);296296+ }297297+ { /* Duplex */298298+ static const struct pch_gbe_option opt = {299299+ .type = list_option,300300+ .name = "Duplex",301301+ .err = "parameter ignored",302302+ .def = 0,303303+ .arg = { .l = { .nr = (int)ARRAY_SIZE(dplx_list),304304+ .p = dplx_list } }305305+ };306306+ dplx = Duplex;307307+ pch_gbe_validate_option(&dplx, &opt, adapter);308308+ }309309+310310+ { /* Autoneg */311311+ static const struct pch_gbe_option opt = {312312+ .type = list_option,313313+ .name = "AutoNeg",314314+ .err = "parameter ignored",315315+ .def = PCH_AUTONEG_ADVERTISE_DEFAULT,316316+ .arg = { .l = { .nr = (int)ARRAY_SIZE(an_list),317317+ .p = an_list} }318318+ };319319+ if (speed || dplx) {320320+ pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n");321321+ hw->phy.autoneg_advertised = opt.def;322322+ } else {323323+ hw->phy.autoneg_advertised = AutoNeg;324324+ pch_gbe_validate_option(325325+ (int *)(&hw->phy.autoneg_advertised),326326+ &opt, adapter);327327+ }328328+ }329329+330330+ switch (speed + dplx) {331331+ case 0:332332+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;333333+ if ((speed || dplx))334334+ pr_debug("Speed and duplex autonegotiation enabled\n");335335+ hw->mac.link_speed = SPEED_10;336336+ hw->mac.link_duplex = DUPLEX_HALF;337337+ break;338338+ case HALF_DUPLEX:339339+ pr_debug("Half Duplex specified without Speed\n");340340+ pr_debug("Using Autonegotiation at Half Duplex only\n");341341+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;342342+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |343343+ PHY_ADVERTISE_100_HALF;344344+ hw->mac.link_speed = SPEED_10;345345+ hw->mac.link_duplex = DUPLEX_HALF;346346+ break;347347+ case FULL_DUPLEX:348348+ pr_debug("Full Duplex specified without Speed\n");349349+ pr_debug("Using Autonegotiation at Full Duplex only\n");350350+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;351351+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL |352352+ PHY_ADVERTISE_100_FULL |353353+ PHY_ADVERTISE_1000_FULL;354354+ hw->mac.link_speed = SPEED_10;355355+ hw->mac.link_duplex = DUPLEX_FULL;356356+ break;357357+ case SPEED_10:358358+ pr_debug("10 Mbps Speed specified without Duplex\n");359359+ pr_debug("Using Autonegotiation at 10 Mbps only\n");360360+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;361361+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |362362+ PHY_ADVERTISE_10_FULL;363363+ hw->mac.link_speed = SPEED_10;364364+ hw->mac.link_duplex = DUPLEX_HALF;365365+ break;366366+ case SPEED_10 + HALF_DUPLEX:367367+ pr_debug("Forcing to 10 Mbps Half Duplex\n");368368+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;369369+ hw->phy.autoneg_advertised = 0;370370+ hw->mac.link_speed = SPEED_10;371371+ hw->mac.link_duplex = DUPLEX_HALF;372372+ break;373373+ case SPEED_10 + FULL_DUPLEX:374374+ pr_debug("Forcing to 10 Mbps Full Duplex\n");375375+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;376376+ hw->phy.autoneg_advertised = 0;377377+ hw->mac.link_speed = SPEED_10;378378+ hw->mac.link_duplex = DUPLEX_FULL;379379+ break;380380+ case SPEED_100:381381+ pr_debug("100 Mbps Speed specified without Duplex\n");382382+ pr_debug("Using Autonegotiation at 100 Mbps only\n");383383+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;384384+ hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF |385385+ PHY_ADVERTISE_100_FULL;386386+ hw->mac.link_speed = SPEED_100;387387+ hw->mac.link_duplex = DUPLEX_HALF;388388+ break;389389+ case SPEED_100 + HALF_DUPLEX:390390+ pr_debug("Forcing to 100 Mbps Half Duplex\n");391391+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;392392+ hw->phy.autoneg_advertised = 0;393393+ hw->mac.link_speed = SPEED_100;394394+ hw->mac.link_duplex = DUPLEX_HALF;395395+ break;396396+ case SPEED_100 + FULL_DUPLEX:397397+ pr_debug("Forcing to 100 Mbps Full Duplex\n");398398+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;399399+ hw->phy.autoneg_advertised = 0;400400+ hw->mac.link_speed = SPEED_100;401401+ hw->mac.link_duplex = DUPLEX_FULL;402402+ break;403403+ case SPEED_1000:404404+ pr_debug("1000 Mbps Speed specified without Duplex\n");405405+ goto full_duplex_only;406406+ case SPEED_1000 + HALF_DUPLEX:407407+ pr_debug("Half Duplex is not supported at 1000 Mbps\n");408408+ /* fall through */409409+ case SPEED_1000 + FULL_DUPLEX:410410+full_duplex_only:411411+ pr_debug("Using Autonegotiation at 1000 Mbps Full Duplex only\n");412412+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;413413+ hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL;414414+ hw->mac.link_speed = SPEED_1000;415415+ hw->mac.link_duplex = DUPLEX_FULL;416416+ break;417417+ default:418418+ BUG();419419+ }420420+}421421+422422+/**423423+ * pch_gbe_check_options - Range Checking for Command Line Parameters424424+ * @adapter: Board private structure425425+ */426426+void pch_gbe_check_options(struct pch_gbe_adapter *adapter)427427+{428428+ struct pch_gbe_hw *hw = &adapter->hw;429429+430430+ { /* Transmit Descriptor Count */431431+ static const struct pch_gbe_option opt = {432432+ .type = range_option,433433+ .name = "Transmit Descriptors",434434+ .err = "using default of "435435+ __MODULE_STRING(PCH_GBE_DEFAULT_TXD),436436+ .def = PCH_GBE_DEFAULT_TXD,437437+ .arg = { .r = { .min = PCH_GBE_MIN_TXD } },438438+ .arg = { .r = { .max = PCH_GBE_MAX_TXD } }439439+ };440440+ struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;441441+ tx_ring->count = TxDescriptors;442442+ pch_gbe_validate_option(&tx_ring->count, &opt, adapter);443443+ tx_ring->count = roundup(tx_ring->count,444444+ PCH_GBE_TX_DESC_MULTIPLE);445445+ }446446+ { /* Receive Descriptor Count */447447+ static const struct pch_gbe_option opt = {448448+ .type = range_option,449449+ .name = "Receive Descriptors",450450+ .err = "using default of "451451+ __MODULE_STRING(PCH_GBE_DEFAULT_RXD),452452+ .def = PCH_GBE_DEFAULT_RXD,453453+ .arg = { .r = { .min = PCH_GBE_MIN_RXD } },454454+ .arg = { .r = { .max = PCH_GBE_MAX_RXD } }455455+ };456456+ struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;457457+ rx_ring->count = RxDescriptors;458458+ pch_gbe_validate_option(&rx_ring->count, &opt, adapter);459459+ rx_ring->count = roundup(rx_ring->count,460460+ PCH_GBE_RX_DESC_MULTIPLE);461461+ }462462+ { /* Checksum Offload Enable/Disable */463463+ static const struct pch_gbe_option opt = {464464+ .type = enable_option,465465+ .name = "Checksum Offload",466466+ .err = "defaulting to Enabled",467467+ .def = PCH_GBE_DEFAULT_RX_CSUM468468+ };469469+ adapter->rx_csum = XsumRX;470470+ pch_gbe_validate_option((int *)(&adapter->rx_csum),471471+ &opt, adapter);472472+ }473473+ { /* Checksum Offload Enable/Disable */474474+ static const struct pch_gbe_option opt = {475475+ .type = enable_option,476476+ .name = "Checksum Offload",477477+ .err = "defaulting to Enabled",478478+ .def = PCH_GBE_DEFAULT_TX_CSUM479479+ };480480+ adapter->tx_csum = XsumTX;481481+ pch_gbe_validate_option((int *)(&adapter->tx_csum),482482+ &opt, adapter);483483+ }484484+ { /* Flow Control */485485+ static const struct pch_gbe_option opt = {486486+ .type = list_option,487487+ .name = "Flow Control",488488+ .err = "reading default settings from EEPROM",489489+ .def = PCH_GBE_FC_DEFAULT,490490+ .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list),491491+ .p = fc_list } }492492+ };493493+ hw->mac.fc = FlowControl;494494+ pch_gbe_validate_option((int *)(&hw->mac.fc),495495+ &opt, adapter);496496+ }497497+498498+ pch_gbe_check_copper_options(adapter);499499+}
+274
drivers/net/pch_gbe/pch_gbe_phy.c
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+2121+#include "pch_gbe.h"2222+#include "pch_gbe_phy.h"2323+2424+#define PHY_MAX_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */2525+2626+/* PHY 1000 MII Register/Bit Definitions */2727+/* PHY Registers defined by IEEE */2828+#define PHY_CONTROL 0x00 /* Control Register */2929+#define PHY_STATUS 0x01 /* Status Regiser */3030+#define PHY_ID1 0x02 /* Phy Id Register (word 1) */3131+#define PHY_ID2 0x03 /* Phy Id Register (word 2) */3232+#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */3333+#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */3434+#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Register */3535+#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */3636+#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */3737+#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Register */3838+#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Register */3939+#define PHY_EXT_STATUS 0x0F /* Extended Status Register */4040+#define PHY_PHYSP_CONTROL 0x10 /* PHY Specific Control Register */4141+#define PHY_EXT_PHYSP_CONTROL 0x14 /* Extended PHY Specific Control Register */4242+#define PHY_LED_CONTROL 0x18 /* LED Control Register */4343+#define PHY_EXT_PHYSP_STATUS 0x1B /* Extended PHY Specific Status Register */4444+4545+/* PHY Control Register */4646+#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */4747+#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */4848+#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */4949+#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */5050+#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */5151+#define MII_CR_POWER_DOWN 0x0800 /* Power down */5252+#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */5353+#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */5454+#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */5555+#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */5656+#define MII_CR_SPEED_1000 0x00405757+#define MII_CR_SPEED_100 0x20005858+#define MII_CR_SPEED_10 0x00005959+6060+/* PHY Status Register */6161+#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */6262+#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */6363+#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */6464+#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */6565+#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */6666+#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */6767+#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */6868+#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */6969+#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */7070+#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */7171+#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */7272+#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */7373+#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */7474+#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */7575+#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */7676+7777+/* Phy Id Register (word 2) */7878+#define PHY_REVISION_MASK 0x000F7979+8080+/* PHY Specific Control Register */8181+#define PHYSP_CTRL_ASSERT_CRS_TX 0x08008282+8383+8484+/* Default value of PHY register */8585+#define PHY_CONTROL_DEFAULT 0x1140 /* Control Register */8686+#define PHY_AUTONEG_ADV_DEFAULT 0x01e0 /* Autoneg Advertisement */8787+#define PHY_NEXT_PAGE_TX_DEFAULT 0x2001 /* Next Page TX */8888+#define PHY_1000T_CTRL_DEFAULT 0x0300 /* 1000Base-T Control Register */8989+#define PHY_PHYSP_CONTROL_DEFAULT 0x01EE /* PHY Specific Control Register */9090+9191+/**9292+ * pch_gbe_phy_get_id - Retrieve the PHY ID and revision9393+ * @hw: Pointer to the HW structure9494+ * Returns9595+ * 0: Successful.9696+ * Negative value: Failed.9797+ */9898+s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw)9999+{100100+ struct pch_gbe_phy_info *phy = &hw->phy;101101+ s32 ret;102102+ u16 phy_id1;103103+ u16 phy_id2;104104+105105+ ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID1, &phy_id1);106106+ if (ret)107107+ return ret;108108+ ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID2, &phy_id2);109109+ if (ret)110110+ return ret;111111+ /*112112+ * PHY_ID1: [bit15-0:ID(21-6)]113113+ * PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision]114114+ */115115+ phy->id = (u32)phy_id1;116116+ phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10));117117+ phy->revision = (u32) (phy_id2 & 0x000F);118118+ pr_debug("phy->id : 0x%08x phy->revision : 0x%08x\n",119119+ phy->id, phy->revision);120120+ return 0;121121+}122122+123123+/**124124+ * pch_gbe_phy_read_reg_miic - Read MII control register125125+ * @hw: Pointer to the HW structure126126+ * @offset: Register offset to be read127127+ * @data: Pointer to the read data128128+ * Returns129129+ * 0: Successful.130130+ * -EINVAL: Invalid argument.131131+ */132132+s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data)133133+{134134+ struct pch_gbe_phy_info *phy = &hw->phy;135135+136136+ if (offset > PHY_MAX_REG_ADDRESS) {137137+ pr_err("PHY Address %d is out of range\n", offset);138138+ return -EINVAL;139139+ }140140+ *data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,141141+ offset, (u16)0);142142+ return 0;143143+}144144+145145+/**146146+ * pch_gbe_phy_write_reg_miic - Write MII control register147147+ * @hw: Pointer to the HW structure148148+ * @offset: Register offset to be read149149+ * @data: data to write to register at offset150150+ * Returns151151+ * 0: Successful.152152+ * -EINVAL: Invalid argument.153153+ */154154+s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data)155155+{156156+ struct pch_gbe_phy_info *phy = &hw->phy;157157+158158+ if (offset > PHY_MAX_REG_ADDRESS) {159159+ pr_err("PHY Address %d is out of range\n", offset);160160+ return -EINVAL;161161+ }162162+ pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,163163+ offset, data);164164+ return 0;165165+}166166+167167+/**168168+ * pch_gbe_phy_sw_reset - PHY software reset169169+ * @hw: Pointer to the HW structure170170+ */171171+void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw)172172+{173173+ u16 phy_ctrl;174174+175175+ pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &phy_ctrl);176176+ phy_ctrl |= MII_CR_RESET;177177+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, phy_ctrl);178178+ udelay(1);179179+}180180+181181+/**182182+ * pch_gbe_phy_hw_reset - PHY hardware reset183183+ * @hw: Pointer to the HW structure184184+ */185185+void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw)186186+{187187+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT);188188+ pch_gbe_phy_write_reg_miic(hw, PHY_AUTONEG_ADV,189189+ PHY_AUTONEG_ADV_DEFAULT);190190+ pch_gbe_phy_write_reg_miic(hw, PHY_NEXT_PAGE_TX,191191+ PHY_NEXT_PAGE_TX_DEFAULT);192192+ pch_gbe_phy_write_reg_miic(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT);193193+ pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL,194194+ PHY_PHYSP_CONTROL_DEFAULT);195195+}196196+197197+/**198198+ * pch_gbe_phy_power_up - restore link in case the phy was powered down199199+ * @hw: Pointer to the HW structure200200+ */201201+void pch_gbe_phy_power_up(struct pch_gbe_hw *hw)202202+{203203+ u16 mii_reg;204204+205205+ mii_reg = 0;206206+ /* Just clear the power down bit to wake the phy back up */207207+ /* according to the manual, the phy will retain its208208+ * settings across a power-down/up cycle */209209+ pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);210210+ mii_reg &= ~MII_CR_POWER_DOWN;211211+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);212212+}213213+214214+/**215215+ * pch_gbe_phy_power_down - Power down PHY216216+ * @hw: Pointer to the HW structure217217+ */218218+void pch_gbe_phy_power_down(struct pch_gbe_hw *hw)219219+{220220+ u16 mii_reg;221221+222222+ mii_reg = 0;223223+ /* Power down the PHY so no link is implied when interface is down *224224+ * The PHY cannot be powered down if any of the following is TRUE *225225+ * (a) WoL is enabled226226+ * (b) AMT is active227227+ */228228+ pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);229229+ mii_reg |= MII_CR_POWER_DOWN;230230+ pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);231231+ mdelay(1);232232+}233233+234234+/**235235+ * pch_gbe_phy_set_rgmii - RGMII interface setting236236+ * @hw: Pointer to the HW structure237237+ */238238+inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)239239+{240240+ pch_gbe_phy_sw_reset(hw);241241+}242242+243243+/**244244+ * pch_gbe_phy_init_setting - PHY initial setting245245+ * @hw: Pointer to the HW structure246246+ */247247+void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)248248+{249249+ struct pch_gbe_adapter *adapter;250250+ struct ethtool_cmd cmd;251251+ int ret;252252+ u16 mii_reg;253253+254254+ adapter = container_of(hw, struct pch_gbe_adapter, hw);255255+ ret = mii_ethtool_gset(&adapter->mii, &cmd);256256+ if (ret)257257+ pr_err("Error: mii_ethtool_gset\n");258258+259259+ cmd.speed = hw->mac.link_speed;260260+ cmd.duplex = hw->mac.link_duplex;261261+ cmd.advertising = hw->phy.autoneg_advertised;262262+ cmd.autoneg = hw->mac.autoneg;263263+ pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);264264+ ret = mii_ethtool_sset(&adapter->mii, &cmd);265265+ if (ret)266266+ pr_err("Error: mii_ethtool_sset\n");267267+268268+ pch_gbe_phy_sw_reset(hw);269269+270270+ pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg);271271+ mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;272272+ pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg);273273+274274+}
+37
drivers/net/pch_gbe/pch_gbe_phy.h
···11+/*22+ * Copyright (C) 1999 - 2010 Intel Corporation.33+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.44+ *55+ * This code was derived from the Intel e1000e Linux driver.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of the GNU General Public License as published by99+ * the Free Software Foundation; version 2 of the License.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.1919+ */2020+#ifndef _PCH_GBE_PHY_H_2121+#define _PCH_GBE_PHY_H_2222+2323+#define PCH_GBE_PHY_REGS_LEN 322424+#define PCH_GBE_PHY_RESET_DELAY_US 102525+#define PCH_GBE_MAC_IFOP_RGMII2626+2727+s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw);2828+s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data);2929+s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data);3030+void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw);3131+void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw);3232+void pch_gbe_phy_power_up(struct pch_gbe_hw *hw);3333+void pch_gbe_phy_power_down(struct pch_gbe_hw *hw);3434+void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw);3535+void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw);3636+3737+#endif /* _PCH_GBE_PHY_H_ */