net: Add Gigabit Ethernet driver of Topcliff PCH
Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
59104f0624
commit
77555ee722
@ -2515,6 +2515,18 @@ config S6GMAC
|
||||
|
||||
source "drivers/net/stmmac/Kconfig"
|
||||
|
||||
config PCH_GBE
|
||||
tristate "PCH Gigabit Ethernet"
|
||||
depends on PCI
|
||||
---help---
|
||||
This is a gigabit ethernet driver for Topcliff PCH.
|
||||
Topcliff PCH is the platform controller hub that is used in Intel's
|
||||
general embedded platform.
|
||||
Topcliff PCH has Gigabit Ethernet interface.
|
||||
Using this interface, it is able to access system devices connected
|
||||
to Gigabit Ethernet.
|
||||
This driver enables Gigabit Ethernet function.
|
||||
|
||||
endif # NETDEV_1000
|
||||
|
||||
#
|
||||
|
@ -298,3 +298,4 @@ obj-$(CONFIG_WIMAX) += wimax/
|
||||
obj-$(CONFIG_CAIF) += caif/
|
||||
|
||||
obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
|
||||
obj-$(CONFIG_PCH_GBE) += pch_gbe/
|
||||
|
4
drivers/net/pch_gbe/Makefile
Normal file
4
drivers/net/pch_gbe/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
obj-$(CONFIG_PCH_GBE) += pch_gbe.o
|
||||
|
||||
pch_gbe-y := pch_gbe_phy.o pch_gbe_ethtool.o pch_gbe_param.o
|
||||
pch_gbe-y += pch_gbe_api.o pch_gbe_main.o
|
659
drivers/net/pch_gbe/pch_gbe.h
Normal file
659
drivers/net/pch_gbe/pch_gbe.h
Normal file
@ -0,0 +1,659 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _PCH_GBE_H_
|
||||
#define _PCH_GBE_H_
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/mii.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
/**
|
||||
* pch_gbe_regs_mac_adr - Structure holding values of mac address registers
|
||||
* @high Denotes the 1st to 4th byte from the initial of MAC address
|
||||
* @low Denotes the 5th to 6th byte from the initial of MAC address
|
||||
*/
|
||||
struct pch_gbe_regs_mac_adr {
|
||||
u32 high;
|
||||
u32 low;
|
||||
};
|
||||
/**
|
||||
* pch_udc_regs - Structure holding values of MAC registers
|
||||
*/
|
||||
struct pch_gbe_regs {
|
||||
u32 INT_ST;
|
||||
u32 INT_EN;
|
||||
u32 MODE;
|
||||
u32 RESET;
|
||||
u32 TCPIP_ACC;
|
||||
u32 EX_LIST;
|
||||
u32 INT_ST_HOLD;
|
||||
u32 PHY_INT_CTRL;
|
||||
u32 MAC_RX_EN;
|
||||
u32 RX_FCTRL;
|
||||
u32 PAUSE_REQ;
|
||||
u32 RX_MODE;
|
||||
u32 TX_MODE;
|
||||
u32 RX_FIFO_ST;
|
||||
u32 TX_FIFO_ST;
|
||||
u32 TX_FID;
|
||||
u32 TX_RESULT;
|
||||
u32 PAUSE_PKT1;
|
||||
u32 PAUSE_PKT2;
|
||||
u32 PAUSE_PKT3;
|
||||
u32 PAUSE_PKT4;
|
||||
u32 PAUSE_PKT5;
|
||||
u32 reserve[2];
|
||||
struct pch_gbe_regs_mac_adr mac_adr[16];
|
||||
u32 ADDR_MASK;
|
||||
u32 MIIM;
|
||||
u32 reserve2;
|
||||
u32 RGMII_ST;
|
||||
u32 RGMII_CTRL;
|
||||
u32 reserve3[3];
|
||||
u32 DMA_CTRL;
|
||||
u32 reserve4[3];
|
||||
u32 RX_DSC_BASE;
|
||||
u32 RX_DSC_SIZE;
|
||||
u32 RX_DSC_HW_P;
|
||||
u32 RX_DSC_HW_P_HLD;
|
||||
u32 RX_DSC_SW_P;
|
||||
u32 reserve5[3];
|
||||
u32 TX_DSC_BASE;
|
||||
u32 TX_DSC_SIZE;
|
||||
u32 TX_DSC_HW_P;
|
||||
u32 TX_DSC_HW_P_HLD;
|
||||
u32 TX_DSC_SW_P;
|
||||
u32 reserve6[3];
|
||||
u32 RX_DMA_ST;
|
||||
u32 TX_DMA_ST;
|
||||
u32 reserve7[2];
|
||||
u32 WOL_ST;
|
||||
u32 WOL_CTRL;
|
||||
u32 WOL_ADDR_MASK;
|
||||
};
|
||||
|
||||
/* Interrupt Status */
|
||||
/* Interrupt Status Hold */
|
||||
/* Interrupt Enable */
|
||||
#define PCH_GBE_INT_RX_DMA_CMPLT 0x00000001 /* Receive DMA Transfer Complete */
|
||||
#define PCH_GBE_INT_RX_VALID 0x00000002 /* MAC Normal Receive Complete */
|
||||
#define PCH_GBE_INT_RX_FRAME_ERR 0x00000004 /* Receive frame error */
|
||||
#define PCH_GBE_INT_RX_FIFO_ERR 0x00000008 /* Receive FIFO Overflow */
|
||||
#define PCH_GBE_INT_RX_DMA_ERR 0x00000010 /* Receive DMA Transfer Error */
|
||||
#define PCH_GBE_INT_RX_DSC_EMP 0x00000020 /* Receive Descriptor Empty */
|
||||
#define PCH_GBE_INT_TX_CMPLT 0x00000100 /* MAC Transmission Complete */
|
||||
#define PCH_GBE_INT_TX_DMA_CMPLT 0x00000200 /* DMA Transfer Complete */
|
||||
#define PCH_GBE_INT_TX_FIFO_ERR 0x00000400 /* Transmission FIFO underflow. */
|
||||
#define PCH_GBE_INT_TX_DMA_ERR 0x00000800 /* Transmission DMA Error */
|
||||
#define PCH_GBE_INT_PAUSE_CMPLT 0x00001000 /* Pause Transmission complete */
|
||||
#define PCH_GBE_INT_MIIM_CMPLT 0x00010000 /* MIIM I/F Read completion */
|
||||
#define PCH_GBE_INT_PHY_INT 0x00100000 /* Interruption from PHY */
|
||||
#define PCH_GBE_INT_WOL_DET 0x01000000 /* Wake On LAN Event detection. */
|
||||
#define PCH_GBE_INT_TCPIP_ERR 0x10000000 /* TCP/IP Accelerator Error */
|
||||
|
||||
/* Mode */
|
||||
#define PCH_GBE_MODE_MII_ETHER 0x00000000 /* GIGA Ethernet Mode [MII] */
|
||||
#define PCH_GBE_MODE_GMII_ETHER 0x80000000 /* GIGA Ethernet Mode [GMII] */
|
||||
#define PCH_GBE_MODE_HALF_DUPLEX 0x00000000 /* Duplex Mode [half duplex] */
|
||||
#define PCH_GBE_MODE_FULL_DUPLEX 0x40000000 /* Duplex Mode [full duplex] */
|
||||
#define PCH_GBE_MODE_FR_BST 0x04000000 /* Frame bursting is done */
|
||||
|
||||
/* Reset */
|
||||
#define PCH_GBE_ALL_RST 0x80000000 /* All reset */
|
||||
#define PCH_GBE_TX_RST 0x40000000 /* TX MAC, TX FIFO, TX DMA reset */
|
||||
#define PCH_GBE_RX_RST 0x04000000 /* RX MAC, RX FIFO, RX DMA reset */
|
||||
|
||||
/* TCP/IP Accelerator Control */
|
||||
#define PCH_GBE_EX_LIST_EN 0x00000008 /* External List Enable */
|
||||
#define PCH_GBE_RX_TCPIPACC_OFF 0x00000004 /* RX TCP/IP ACC Disabled */
|
||||
#define PCH_GBE_TX_TCPIPACC_EN 0x00000002 /* TX TCP/IP ACC Enable */
|
||||
#define PCH_GBE_RX_TCPIPACC_EN 0x00000001 /* RX TCP/IP ACC Enable */
|
||||
|
||||
/* MAC RX Enable */
|
||||
#define PCH_GBE_MRE_MAC_RX_EN 0x00000001 /* MAC Receive Enable */
|
||||
|
||||
/* RX Flow Control */
|
||||
#define PCH_GBE_FL_CTRL_EN 0x80000000 /* Pause packet is enabled */
|
||||
|
||||
/* Pause Packet Request */
|
||||
#define PCH_GBE_PS_PKT_RQ 0x80000000 /* Pause packet Request */
|
||||
|
||||
/* RX Mode */
|
||||
#define PCH_GBE_ADD_FIL_EN 0x80000000 /* Address Filtering Enable */
|
||||
/* Multicast Filtering Enable */
|
||||
#define PCH_GBE_MLT_FIL_EN 0x40000000
|
||||
/* Receive Almost Empty Threshold */
|
||||
#define PCH_GBE_RH_ALM_EMP_4 0x00000000 /* 4 words */
|
||||
#define PCH_GBE_RH_ALM_EMP_8 0x00004000 /* 8 words */
|
||||
#define PCH_GBE_RH_ALM_EMP_16 0x00008000 /* 16 words */
|
||||
#define PCH_GBE_RH_ALM_EMP_32 0x0000C000 /* 32 words */
|
||||
/* Receive Almost Full Threshold */
|
||||
#define PCH_GBE_RH_ALM_FULL_4 0x00000000 /* 4 words */
|
||||
#define PCH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */
|
||||
#define PCH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */
|
||||
#define PCH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */
|
||||
/* RX FIFO Read Triger Threshold */
|
||||
#define PCH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */
|
||||
#define PCH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */
|
||||
#define PCH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */
|
||||
#define PCH_GBE_RH_RD_TRG_32 0x00000600 /* 32 words */
|
||||
#define PCH_GBE_RH_RD_TRG_64 0x00000800 /* 64 words */
|
||||
#define PCH_GBE_RH_RD_TRG_128 0x00000A00 /* 128 words */
|
||||
#define PCH_GBE_RH_RD_TRG_256 0x00000C00 /* 256 words */
|
||||
#define PCH_GBE_RH_RD_TRG_512 0x00000E00 /* 512 words */
|
||||
|
||||
/* Receive Descriptor bit definitions */
|
||||
#define PCH_GBE_RXD_ACC_STAT_BCAST 0x00000400
|
||||
#define PCH_GBE_RXD_ACC_STAT_MCAST 0x00000200
|
||||
#define PCH_GBE_RXD_ACC_STAT_UCAST 0x00000100
|
||||
#define PCH_GBE_RXD_ACC_STAT_TCPIPOK 0x000000C0
|
||||
#define PCH_GBE_RXD_ACC_STAT_IPOK 0x00000080
|
||||
#define PCH_GBE_RXD_ACC_STAT_TCPOK 0x00000040
|
||||
#define PCH_GBE_RXD_ACC_STAT_IP6ERR 0x00000020
|
||||
#define PCH_GBE_RXD_ACC_STAT_OFLIST 0x00000010
|
||||
#define PCH_GBE_RXD_ACC_STAT_TYPEIP 0x00000008
|
||||
#define PCH_GBE_RXD_ACC_STAT_MACL 0x00000004
|
||||
#define PCH_GBE_RXD_ACC_STAT_PPPOE 0x00000002
|
||||
#define PCH_GBE_RXD_ACC_STAT_VTAGT 0x00000001
|
||||
#define PCH_GBE_RXD_GMAC_STAT_PAUSE 0x0200
|
||||
#define PCH_GBE_RXD_GMAC_STAT_MARBR 0x0100
|
||||
#define PCH_GBE_RXD_GMAC_STAT_MARMLT 0x0080
|
||||
#define PCH_GBE_RXD_GMAC_STAT_MARIND 0x0040
|
||||
#define PCH_GBE_RXD_GMAC_STAT_MARNOTMT 0x0020
|
||||
#define PCH_GBE_RXD_GMAC_STAT_TLONG 0x0010
|
||||
#define PCH_GBE_RXD_GMAC_STAT_TSHRT 0x0008
|
||||
#define PCH_GBE_RXD_GMAC_STAT_NOTOCTAL 0x0004
|
||||
#define PCH_GBE_RXD_GMAC_STAT_NBLERR 0x0002
|
||||
#define PCH_GBE_RXD_GMAC_STAT_CRCERR 0x0001
|
||||
|
||||
/* Transmit Descriptor bit definitions */
|
||||
#define PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF 0x0008
|
||||
#define PCH_GBE_TXD_CTRL_ITAG 0x0004
|
||||
#define PCH_GBE_TXD_CTRL_ICRC 0x0002
|
||||
#define PCH_GBE_TXD_CTRL_APAD 0x0001
|
||||
#define PCH_GBE_TXD_WORDS_SHIFT 2
|
||||
#define PCH_GBE_TXD_GMAC_STAT_CMPLT 0x2000
|
||||
#define PCH_GBE_TXD_GMAC_STAT_ABT 0x1000
|
||||
#define PCH_GBE_TXD_GMAC_STAT_EXCOL 0x0800
|
||||
#define PCH_GBE_TXD_GMAC_STAT_SNGCOL 0x0400
|
||||
#define PCH_GBE_TXD_GMAC_STAT_MLTCOL 0x0200
|
||||
#define PCH_GBE_TXD_GMAC_STAT_CRSER 0x0100
|
||||
#define PCH_GBE_TXD_GMAC_STAT_TLNG 0x0080
|
||||
#define PCH_GBE_TXD_GMAC_STAT_TSHRT 0x0040
|
||||
#define PCH_GBE_TXD_GMAC_STAT_LTCOL 0x0020
|
||||
#define PCH_GBE_TXD_GMAC_STAT_TFUNDFLW 0x0010
|
||||
#define PCH_GBE_TXD_GMAC_STAT_RTYCNT_MASK 0x000F
|
||||
|
||||
/* TX Mode */
|
||||
#define PCH_GBE_TM_NO_RTRY 0x80000000 /* No Retransmission */
|
||||
#define PCH_GBE_TM_LONG_PKT 0x40000000 /* Long Packt TX Enable */
|
||||
#define PCH_GBE_TM_ST_AND_FD 0x20000000 /* Stare and Forward */
|
||||
#define PCH_GBE_TM_SHORT_PKT 0x10000000 /* Short Packet TX Enable */
|
||||
#define PCH_GBE_TM_LTCOL_RETX 0x08000000 /* Retransmission at Late Collision */
|
||||
/* Frame Start Threshold */
|
||||
#define PCH_GBE_TM_TH_TX_STRT_4 0x00000000 /* 4 words */
|
||||
#define PCH_GBE_TM_TH_TX_STRT_8 0x00004000 /* 8 words */
|
||||
#define PCH_GBE_TM_TH_TX_STRT_16 0x00008000 /* 16 words */
|
||||
#define PCH_GBE_TM_TH_TX_STRT_32 0x0000C000 /* 32 words */
|
||||
/* Transmit Almost Empty Threshold */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_4 0x00000000 /* 4 words */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_8 0x00000800 /* 8 words */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_16 0x00001000 /* 16 words */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_32 0x00001800 /* 32 words */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_64 0x00002000 /* 64 words */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_128 0x00002800 /* 128 words */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_256 0x00003000 /* 256 words */
|
||||
#define PCH_GBE_TM_TH_ALM_EMP_512 0x00003800 /* 512 words */
|
||||
/* Transmit Almost Full Threshold */
|
||||
#define PCH_GBE_TM_TH_ALM_FULL_4 0x00000000 /* 4 words */
|
||||
#define PCH_GBE_TM_TH_ALM_FULL_8 0x00000200 /* 8 words */
|
||||
#define PCH_GBE_TM_TH_ALM_FULL_16 0x00000400 /* 16 words */
|
||||
#define PCH_GBE_TM_TH_ALM_FULL_32 0x00000600 /* 32 words */
|
||||
|
||||
/* RX FIFO Status */
|
||||
#define PCH_GBE_RF_ALM_FULL 0x80000000 /* RX FIFO is almost full. */
|
||||
#define PCH_GBE_RF_ALM_EMP 0x40000000 /* RX FIFO is almost empty. */
|
||||
#define PCH_GBE_RF_RD_TRG 0x20000000 /* Become more than RH_RD_TRG. */
|
||||
#define PCH_GBE_RF_STRWD 0x1FFE0000 /* The word count of RX FIFO. */
|
||||
#define PCH_GBE_RF_RCVING 0x00010000 /* Stored in RX FIFO. */
|
||||
|
||||
/* MAC Address Mask */
|
||||
#define PCH_GBE_BUSY 0x80000000
|
||||
|
||||
/* MIIM */
|
||||
#define PCH_GBE_MIIM_OPER_WRITE 0x04000000
|
||||
#define PCH_GBE_MIIM_OPER_READ 0x00000000
|
||||
#define PCH_GBE_MIIM_OPER_READY 0x04000000
|
||||
#define PCH_GBE_MIIM_PHY_ADDR_SHIFT 21
|
||||
#define PCH_GBE_MIIM_REG_ADDR_SHIFT 16
|
||||
|
||||
/* RGMII Status */
|
||||
#define PCH_GBE_LINK_UP 0x80000008
|
||||
#define PCH_GBE_RXC_SPEED_MSK 0x00000006
|
||||
#define PCH_GBE_RXC_SPEED_2_5M 0x00000000 /* 2.5MHz */
|
||||
#define PCH_GBE_RXC_SPEED_25M 0x00000002 /* 25MHz */
|
||||
#define PCH_GBE_RXC_SPEED_125M 0x00000004 /* 100MHz */
|
||||
#define PCH_GBE_DUPLEX_FULL 0x00000001
|
||||
|
||||
/* RGMII Control */
|
||||
#define PCH_GBE_CRS_SEL 0x00000010
|
||||
#define PCH_GBE_RGMII_RATE_125M 0x00000000
|
||||
#define PCH_GBE_RGMII_RATE_25M 0x00000008
|
||||
#define PCH_GBE_RGMII_RATE_2_5M 0x0000000C
|
||||
#define PCH_GBE_RGMII_MODE_GMII 0x00000000
|
||||
#define PCH_GBE_RGMII_MODE_RGMII 0x00000002
|
||||
#define PCH_GBE_CHIP_TYPE_EXTERNAL 0x00000000
|
||||
#define PCH_GBE_CHIP_TYPE_INTERNAL 0x00000001
|
||||
|
||||
/* DMA Control */
|
||||
#define PCH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */
|
||||
#define PCH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */
|
||||
|
||||
/* Wake On LAN Status */
|
||||
#define PCH_GBE_WLS_BR 0x00000008 /* Broadcas Address */
|
||||
#define PCH_GBE_WLS_MLT 0x00000004 /* Multicast Address */
|
||||
|
||||
/* The Frame registered in Address Recognizer */
|
||||
#define PCH_GBE_WLS_IND 0x00000002
|
||||
#define PCH_GBE_WLS_MP 0x00000001 /* Magic packet Address */
|
||||
|
||||
/* Wake On LAN Control */
|
||||
#define PCH_GBE_WLC_WOL_MODE 0x00010000
|
||||
#define PCH_GBE_WLC_IGN_TLONG 0x00000100
|
||||
#define PCH_GBE_WLC_IGN_TSHRT 0x00000080
|
||||
#define PCH_GBE_WLC_IGN_OCTER 0x00000040
|
||||
#define PCH_GBE_WLC_IGN_NBLER 0x00000020
|
||||
#define PCH_GBE_WLC_IGN_CRCER 0x00000010
|
||||
#define PCH_GBE_WLC_BR 0x00000008
|
||||
#define PCH_GBE_WLC_MLT 0x00000004
|
||||
#define PCH_GBE_WLC_IND 0x00000002
|
||||
#define PCH_GBE_WLC_MP 0x00000001
|
||||
|
||||
/* Wake On LAN Address Mask */
|
||||
#define PCH_GBE_WLA_BUSY 0x80000000
|
||||
|
||||
|
||||
|
||||
/* TX/RX descriptor defines */
|
||||
#define PCH_GBE_MAX_TXD 4096
|
||||
#define PCH_GBE_DEFAULT_TXD 256
|
||||
#define PCH_GBE_MIN_TXD 8
|
||||
#define PCH_GBE_MAX_RXD 4096
|
||||
#define PCH_GBE_DEFAULT_RXD 256
|
||||
#define PCH_GBE_MIN_RXD 8
|
||||
|
||||
/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
|
||||
#define PCH_GBE_TX_DESC_MULTIPLE 8
|
||||
#define PCH_GBE_RX_DESC_MULTIPLE 8
|
||||
|
||||
/* Read/Write operation is done through MII Management IF */
|
||||
#define PCH_GBE_HAL_MIIM_READ ((u32)0x00000000)
|
||||
#define PCH_GBE_HAL_MIIM_WRITE ((u32)0x04000000)
|
||||
|
||||
/* flow control values */
|
||||
#define PCH_GBE_FC_NONE 0
|
||||
#define PCH_GBE_FC_RX_PAUSE 1
|
||||
#define PCH_GBE_FC_TX_PAUSE 2
|
||||
#define PCH_GBE_FC_FULL 3
|
||||
#define PCH_GBE_FC_DEFAULT PCH_GBE_FC_FULL
|
||||
|
||||
|
||||
struct pch_gbe_hw;
|
||||
/**
|
||||
* struct pch_gbe_functions - HAL APi function pointer
|
||||
* @get_bus_info: for pch_gbe_hal_get_bus_info
|
||||
* @init_hw: for pch_gbe_hal_init_hw
|
||||
* @read_phy_reg: for pch_gbe_hal_read_phy_reg
|
||||
* @write_phy_reg: for pch_gbe_hal_write_phy_reg
|
||||
* @reset_phy: for pch_gbe_hal_phy_hw_reset
|
||||
* @sw_reset_phy: for pch_gbe_hal_phy_sw_reset
|
||||
* @power_up_phy: for pch_gbe_hal_power_up_phy
|
||||
* @power_down_phy: for pch_gbe_hal_power_down_phy
|
||||
* @read_mac_addr: for pch_gbe_hal_read_mac_addr
|
||||
*/
|
||||
struct pch_gbe_functions {
|
||||
void (*get_bus_info) (struct pch_gbe_hw *);
|
||||
s32 (*init_hw) (struct pch_gbe_hw *);
|
||||
s32 (*read_phy_reg) (struct pch_gbe_hw *, u32, u16 *);
|
||||
s32 (*write_phy_reg) (struct pch_gbe_hw *, u32, u16);
|
||||
void (*reset_phy) (struct pch_gbe_hw *);
|
||||
void (*sw_reset_phy) (struct pch_gbe_hw *);
|
||||
void (*power_up_phy) (struct pch_gbe_hw *hw);
|
||||
void (*power_down_phy) (struct pch_gbe_hw *hw);
|
||||
s32 (*read_mac_addr) (struct pch_gbe_hw *);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_mac_info - MAC infomation
|
||||
* @addr[6]: Store the MAC address
|
||||
* @fc: Mode of flow control
|
||||
* @fc_autoneg: Auto negotiation enable for flow control setting
|
||||
* @tx_fc_enable: Enable flag of Transmit flow control
|
||||
* @max_frame_size: Max transmit frame size
|
||||
* @min_frame_size: Min transmit frame size
|
||||
* @autoneg: Auto negotiation enable
|
||||
* @link_speed: Link speed
|
||||
* @link_duplex: Link duplex
|
||||
*/
|
||||
struct pch_gbe_mac_info {
|
||||
u8 addr[6];
|
||||
u8 fc;
|
||||
u8 fc_autoneg;
|
||||
u8 tx_fc_enable;
|
||||
u32 max_frame_size;
|
||||
u32 min_frame_size;
|
||||
u8 autoneg;
|
||||
u16 link_speed;
|
||||
u16 link_duplex;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_phy_info - PHY infomation
|
||||
* @addr: PHY address
|
||||
* @id: PHY's identifier
|
||||
* @revision: PHY's revision
|
||||
* @reset_delay_us: HW reset delay time[us]
|
||||
* @autoneg_advertised: Autoneg advertised
|
||||
*/
|
||||
struct pch_gbe_phy_info {
|
||||
u32 addr;
|
||||
u32 id;
|
||||
u32 revision;
|
||||
u32 reset_delay_us;
|
||||
u16 autoneg_advertised;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @ingroup Gigabit Ether driver Layer
|
||||
* @struct pch_gbe_bus_info
|
||||
* @brief Bus infomation
|
||||
*/
|
||||
struct pch_gbe_bus_info {
|
||||
u8 type;
|
||||
u8 speed;
|
||||
u8 width;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @ingroup Gigabit Ether driver Layer
|
||||
* @struct pch_gbe_hw
|
||||
* @brief Hardware infomation
|
||||
*/
|
||||
struct pch_gbe_hw {
|
||||
void *back;
|
||||
|
||||
struct pch_gbe_regs __iomem *reg;
|
||||
spinlock_t miim_lock;
|
||||
|
||||
const struct pch_gbe_functions *func;
|
||||
struct pch_gbe_mac_info mac;
|
||||
struct pch_gbe_phy_info phy;
|
||||
struct pch_gbe_bus_info bus;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_rx_desc - Receive Descriptor
|
||||
* @buffer_addr: RX Frame Buffer Address
|
||||
* @tcp_ip_status: TCP/IP Accelerator Status
|
||||
* @rx_words_eob: RX word count and Byte position
|
||||
* @gbec_status: GMAC Status
|
||||
* @dma_status: DMA Status
|
||||
* @reserved1: Reserved
|
||||
* @reserved2: Reserved
|
||||
*/
|
||||
struct pch_gbe_rx_desc {
|
||||
u32 buffer_addr;
|
||||
u32 tcp_ip_status;
|
||||
u16 rx_words_eob;
|
||||
u16 gbec_status;
|
||||
u8 dma_status;
|
||||
u8 reserved1;
|
||||
u16 reserved2;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_tx_desc - Transmit Descriptor
|
||||
* @buffer_addr: TX Frame Buffer Address
|
||||
* @length: Data buffer length
|
||||
* @reserved1: Reserved
|
||||
* @tx_words_eob: TX word count and Byte position
|
||||
* @tx_frame_ctrl: TX Frame Control
|
||||
* @dma_status: DMA Status
|
||||
* @reserved2: Reserved
|
||||
* @gbec_status: GMAC Status
|
||||
*/
|
||||
struct pch_gbe_tx_desc {
|
||||
u32 buffer_addr;
|
||||
u16 length;
|
||||
u16 reserved1;
|
||||
u16 tx_words_eob;
|
||||
u16 tx_frame_ctrl;
|
||||
u8 dma_status;
|
||||
u8 reserved2;
|
||||
u16 gbec_status;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct pch_gbe_buffer - Buffer infomation
|
||||
* @skb: pointer to a socket buffer
|
||||
* @dma: DMA address
|
||||
* @time_stamp: time stamp
|
||||
* @length: data size
|
||||
*/
|
||||
struct pch_gbe_buffer {
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t dma;
|
||||
unsigned long time_stamp;
|
||||
u16 length;
|
||||
bool mapped;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_tx_ring - tx ring infomation
|
||||
* @tx_lock: spinlock structs
|
||||
* @desc: pointer to the descriptor ring memory
|
||||
* @dma: physical address of the descriptor ring
|
||||
* @size: length of descriptor ring in bytes
|
||||
* @count: number of descriptors in the ring
|
||||
* @next_to_use: next descriptor to associate a buffer with
|
||||
* @next_to_clean: next descriptor to check for DD status bit
|
||||
* @buffer_info: array of buffer information structs
|
||||
*/
|
||||
struct pch_gbe_tx_ring {
|
||||
spinlock_t tx_lock;
|
||||
struct pch_gbe_tx_desc *desc;
|
||||
dma_addr_t dma;
|
||||
unsigned int size;
|
||||
unsigned int count;
|
||||
unsigned int next_to_use;
|
||||
unsigned int next_to_clean;
|
||||
struct pch_gbe_buffer *buffer_info;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_rx_ring - rx ring infomation
|
||||
* @desc: pointer to the descriptor ring memory
|
||||
* @dma: physical address of the descriptor ring
|
||||
* @size: length of descriptor ring in bytes
|
||||
* @count: number of descriptors in the ring
|
||||
* @next_to_use: next descriptor to associate a buffer with
|
||||
* @next_to_clean: next descriptor to check for DD status bit
|
||||
* @buffer_info: array of buffer information structs
|
||||
*/
|
||||
struct pch_gbe_rx_ring {
|
||||
struct pch_gbe_rx_desc *desc;
|
||||
dma_addr_t dma;
|
||||
unsigned int size;
|
||||
unsigned int count;
|
||||
unsigned int next_to_use;
|
||||
unsigned int next_to_clean;
|
||||
struct pch_gbe_buffer *buffer_info;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_hw_stats - Statistics counters collected by the MAC
|
||||
* @rx_packets: total packets received
|
||||
* @tx_packets: total packets transmitted
|
||||
* @rx_bytes: total bytes received
|
||||
* @tx_bytes: total bytes transmitted
|
||||
* @rx_errors: bad packets received
|
||||
* @tx_errors: packet transmit problems
|
||||
* @rx_dropped: no space in Linux buffers
|
||||
* @tx_dropped: no space available in Linux
|
||||
* @multicast: multicast packets received
|
||||
* @collisions: collisions
|
||||
* @rx_crc_errors: received packet with crc error
|
||||
* @rx_frame_errors: received frame alignment error
|
||||
* @rx_alloc_buff_failed: allocate failure of a receive buffer
|
||||
* @tx_length_errors: transmit length error
|
||||
* @tx_aborted_errors: transmit aborted error
|
||||
* @tx_carrier_errors: transmit carrier error
|
||||
* @tx_timeout_count: Number of transmit timeout
|
||||
* @tx_restart_count: Number of transmit restert
|
||||
* @intr_rx_dsc_empty_count: Interrupt count of receive descriptor empty
|
||||
* @intr_rx_frame_err_count: Interrupt count of receive frame error
|
||||
* @intr_rx_fifo_err_count: Interrupt count of receive FIFO error
|
||||
* @intr_rx_dma_err_count: Interrupt count of receive DMA error
|
||||
* @intr_tx_fifo_err_count: Interrupt count of transmit FIFO error
|
||||
* @intr_tx_dma_err_count: Interrupt count of transmit DMA error
|
||||
* @intr_tcpip_err_count: Interrupt count of TCP/IP Accelerator
|
||||
*/
|
||||
struct pch_gbe_hw_stats {
|
||||
u32 rx_packets;
|
||||
u32 tx_packets;
|
||||
u32 rx_bytes;
|
||||
u32 tx_bytes;
|
||||
u32 rx_errors;
|
||||
u32 tx_errors;
|
||||
u32 rx_dropped;
|
||||
u32 tx_dropped;
|
||||
u32 multicast;
|
||||
u32 collisions;
|
||||
u32 rx_crc_errors;
|
||||
u32 rx_frame_errors;
|
||||
u32 rx_alloc_buff_failed;
|
||||
u32 tx_length_errors;
|
||||
u32 tx_aborted_errors;
|
||||
u32 tx_carrier_errors;
|
||||
u32 tx_timeout_count;
|
||||
u32 tx_restart_count;
|
||||
u32 intr_rx_dsc_empty_count;
|
||||
u32 intr_rx_frame_err_count;
|
||||
u32 intr_rx_fifo_err_count;
|
||||
u32 intr_rx_dma_err_count;
|
||||
u32 intr_tx_fifo_err_count;
|
||||
u32 intr_tx_dma_err_count;
|
||||
u32 intr_tcpip_err_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pch_gbe_adapter - board specific private data structure
|
||||
* @stats_lock: Spinlock structure for status
|
||||
* @tx_queue_lock: Spinlock structure for transmit
|
||||
* @ethtool_lock: Spinlock structure for ethtool
|
||||
* @irq_sem: Semaphore for interrupt
|
||||
* @netdev: Pointer of network device structure
|
||||
* @pdev: Pointer of pci device structure
|
||||
* @polling_netdev: Pointer of polling network device structure
|
||||
* @napi: NAPI structure
|
||||
* @hw: Pointer of hardware structure
|
||||
* @stats: Hardware status
|
||||
* @reset_task: Reset task
|
||||
* @mii: MII information structure
|
||||
* @watchdog_timer: Watchdog timer list
|
||||
* @wake_up_evt: Wake up event
|
||||
* @config_space: Configuration space
|
||||
* @msg_enable: Driver message level
|
||||
* @led_status: LED status
|
||||
* @tx_ring: Pointer of Tx descriptor ring structure
|
||||
* @rx_ring: Pointer of Rx descriptor ring structure
|
||||
* @rx_buffer_len: Receive buffer length
|
||||
* @tx_queue_len: Transmit queue length
|
||||
* @rx_csum: Receive TCP/IP checksum enable/disable
|
||||
* @tx_csum: Transmit TCP/IP checksum enable/disable
|
||||
* @have_msi: PCI MSI mode flag
|
||||
*/
|
||||
|
||||
struct pch_gbe_adapter {
|
||||
spinlock_t stats_lock;
|
||||
spinlock_t tx_queue_lock;
|
||||
spinlock_t ethtool_lock;
|
||||
atomic_t irq_sem;
|
||||
struct net_device *netdev;
|
||||
struct pci_dev *pdev;
|
||||
struct net_device *polling_netdev;
|
||||
struct napi_struct napi;
|
||||
struct pch_gbe_hw hw;
|
||||
struct pch_gbe_hw_stats stats;
|
||||
struct work_struct reset_task;
|
||||
struct mii_if_info mii;
|
||||
struct timer_list watchdog_timer;
|
||||
u32 wake_up_evt;
|
||||
u32 *config_space;
|
||||
unsigned long led_status;
|
||||
struct pch_gbe_tx_ring *tx_ring;
|
||||
struct pch_gbe_rx_ring *rx_ring;
|
||||
unsigned long rx_buffer_len;
|
||||
unsigned long tx_queue_len;
|
||||
bool rx_csum;
|
||||
bool tx_csum;
|
||||
bool have_msi;
|
||||
};
|
||||
|
||||
extern const char pch_driver_version[];
|
||||
|
||||
/* pch_gbe_main.c */
|
||||
extern int pch_gbe_up(struct pch_gbe_adapter *adapter);
|
||||
extern void pch_gbe_down(struct pch_gbe_adapter *adapter);
|
||||
extern void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter);
|
||||
extern void pch_gbe_reset(struct pch_gbe_adapter *adapter);
|
||||
extern int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,
|
||||
struct pch_gbe_tx_ring *txdr);
|
||||
extern int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter,
|
||||
struct pch_gbe_rx_ring *rxdr);
|
||||
extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter,
|
||||
struct pch_gbe_tx_ring *tx_ring);
|
||||
extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter,
|
||||
struct pch_gbe_rx_ring *rx_ring);
|
||||
extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter);
|
||||
extern int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg);
|
||||
extern void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg,
|
||||
int data);
|
||||
/* pch_gbe_param.c */
|
||||
extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter);
|
||||
|
||||
/* pch_gbe_ethtool.c */
|
||||
extern void pch_gbe_set_ethtool_ops(struct net_device *netdev);
|
||||
|
||||
/* pch_gbe_mac.c */
|
||||
extern s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw);
|
||||
extern s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw);
|
||||
extern u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw,
|
||||
u32 addr, u32 dir, u32 reg, u16 data);
|
||||
#endif /* _PCH_GBE_H_ */
|
245
drivers/net/pch_gbe/pch_gbe_api.c
Normal file
245
drivers/net/pch_gbe/pch_gbe_api.c
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "pch_gbe.h"
|
||||
#include "pch_gbe_phy.h"
|
||||
|
||||
/* bus type values */
|
||||
#define pch_gbe_bus_type_unknown 0
|
||||
#define pch_gbe_bus_type_pci 1
|
||||
#define pch_gbe_bus_type_pcix 2
|
||||
#define pch_gbe_bus_type_pci_express 3
|
||||
#define pch_gbe_bus_type_reserved 4
|
||||
|
||||
/* bus speed values */
|
||||
#define pch_gbe_bus_speed_unknown 0
|
||||
#define pch_gbe_bus_speed_33 1
|
||||
#define pch_gbe_bus_speed_66 2
|
||||
#define pch_gbe_bus_speed_100 3
|
||||
#define pch_gbe_bus_speed_120 4
|
||||
#define pch_gbe_bus_speed_133 5
|
||||
#define pch_gbe_bus_speed_2500 6
|
||||
#define pch_gbe_bus_speed_reserved 7
|
||||
|
||||
/* bus width values */
|
||||
#define pch_gbe_bus_width_unknown 0
|
||||
#define pch_gbe_bus_width_pcie_x1 1
|
||||
#define pch_gbe_bus_width_pcie_x2 2
|
||||
#define pch_gbe_bus_width_pcie_x4 4
|
||||
#define pch_gbe_bus_width_32 5
|
||||
#define pch_gbe_bus_width_64 6
|
||||
#define pch_gbe_bus_width_reserved 7
|
||||
|
||||
/**
|
||||
* pch_gbe_plat_get_bus_info - Obtain bus information for adapter
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw)
|
||||
{
|
||||
hw->bus.type = pch_gbe_bus_type_pci_express;
|
||||
hw->bus.speed = pch_gbe_bus_speed_2500;
|
||||
hw->bus.width = pch_gbe_bus_width_pcie_x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_plat_init_hw - Initialize hardware
|
||||
* @hw: Pointer to the HW structure
|
||||
* Returns
|
||||
* 0: Successfully
|
||||
* Negative value: Failed-EBUSY
|
||||
*/
|
||||
static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw)
|
||||
{
|
||||
s32 ret_val;
|
||||
|
||||
ret_val = pch_gbe_phy_get_id(hw);
|
||||
if (ret_val) {
|
||||
pr_err("pch_gbe_phy_get_id error\n");
|
||||
return ret_val;
|
||||
}
|
||||
pch_gbe_phy_init_setting(hw);
|
||||
/* Setup Mac interface option RGMII */
|
||||
#ifdef PCH_GBE_MAC_IFOP_RGMII
|
||||
pch_gbe_phy_set_rgmii(hw);
|
||||
#endif
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static const struct pch_gbe_functions pch_gbe_ops = {
|
||||
.get_bus_info = pch_gbe_plat_get_bus_info,
|
||||
.init_hw = pch_gbe_plat_init_hw,
|
||||
.read_phy_reg = pch_gbe_phy_read_reg_miic,
|
||||
.write_phy_reg = pch_gbe_phy_write_reg_miic,
|
||||
.reset_phy = pch_gbe_phy_hw_reset,
|
||||
.sw_reset_phy = pch_gbe_phy_sw_reset,
|
||||
.power_up_phy = pch_gbe_phy_power_up,
|
||||
.power_down_phy = pch_gbe_phy_power_down,
|
||||
.read_mac_addr = pch_gbe_mac_read_mac_addr
|
||||
};
|
||||
|
||||
/**
|
||||
* pch_gbe_plat_init_function_pointers - Init func ptrs
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw)
|
||||
{
|
||||
/* Set PHY parameter */
|
||||
hw->phy.reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US;
|
||||
/* Set function pointers */
|
||||
hw->func = &pch_gbe_ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_setup_init_funcs - Initializes function pointers
|
||||
* @hw: Pointer to the HW structure
|
||||
* Returns
|
||||
* 0: Successfully
|
||||
* ENOSYS: Function is not registered
|
||||
*/
|
||||
inline s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (!hw->reg) {
|
||||
pr_err("ERROR: Registers not mapped\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
pch_gbe_plat_init_function_pointers(hw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_get_bus_info - Obtain bus information for adapter
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
inline void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (!hw->func->get_bus_info)
|
||||
pr_err("ERROR: configuration\n");
|
||||
else
|
||||
hw->func->get_bus_info(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_init_hw - Initialize hardware
|
||||
* @hw: Pointer to the HW structure
|
||||
* Returns
|
||||
* 0: Successfully
|
||||
* ENOSYS: Function is not registered
|
||||
*/
|
||||
inline s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (!hw->func->init_hw) {
|
||||
pr_err("ERROR: configuration\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
return hw->func->init_hw(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_read_phy_reg - Reads PHY register
|
||||
* @hw: Pointer to the HW structure
|
||||
* @offset: The register to read
|
||||
* @data: The buffer to store the 16-bit read.
|
||||
* Returns
|
||||
* 0: Successfully
|
||||
* Negative value: Failed
|
||||
*/
|
||||
inline s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset,
|
||||
u16 *data)
|
||||
{
|
||||
if (!hw->func->read_phy_reg)
|
||||
return 0;
|
||||
return hw->func->read_phy_reg(hw, offset, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_write_phy_reg - Writes PHY register
|
||||
* @hw: Pointer to the HW structure
|
||||
* @offset: The register to read
|
||||
* @data: The value to write.
|
||||
* Returns
|
||||
* 0: Successfully
|
||||
* Negative value: Failed
|
||||
*/
|
||||
inline s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset,
|
||||
u16 data)
|
||||
{
|
||||
if (!hw->func->write_phy_reg)
|
||||
return 0;
|
||||
return hw->func->write_phy_reg(hw, offset, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_phy_hw_reset - Hard PHY reset
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
inline void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (!hw->func->reset_phy)
|
||||
pr_err("ERROR: configuration\n");
|
||||
else
|
||||
hw->func->reset_phy(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_phy_sw_reset - Soft PHY reset
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
inline void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (!hw->func->sw_reset_phy)
|
||||
pr_err("ERROR: configuration\n");
|
||||
else
|
||||
hw->func->sw_reset_phy(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_read_mac_addr - Reads MAC address
|
||||
* @hw: Pointer to the HW structure
|
||||
* Returns
|
||||
* 0: Successfully
|
||||
* ENOSYS: Function is not registered
|
||||
*/
|
||||
inline s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (!hw->func->read_mac_addr) {
|
||||
pr_err("ERROR: configuration\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
return hw->func->read_mac_addr(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_power_up_phy - Power up PHY
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
inline void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (hw->func->power_up_phy)
|
||||
hw->func->power_up_phy(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_hal_power_down_phy - Power down PHY
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
inline void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
|
||||
{
|
||||
if (hw->func->power_down_phy)
|
||||
hw->func->power_down_phy(hw);
|
||||
}
|
36
drivers/net/pch_gbe/pch_gbe_api.h
Normal file
36
drivers/net/pch_gbe/pch_gbe_api.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _PCH_GBE_API_H_
|
||||
#define _PCH_GBE_API_H_
|
||||
|
||||
#include "pch_gbe_phy.h"
|
||||
|
||||
s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw);
|
||||
s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw);
|
||||
s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 *data);
|
||||
s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 data);
|
||||
void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw);
|
||||
s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw);
|
||||
|
||||
#endif
|
584
drivers/net/pch_gbe/pch_gbe_ethtool.c
Normal file
584
drivers/net/pch_gbe/pch_gbe_ethtool.c
Normal file
@ -0,0 +1,584 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "pch_gbe.h"
|
||||
#include "pch_gbe_api.h"
|
||||
|
||||
/**
|
||||
* pch_gbe_stats - Stats item infomation
|
||||
*/
|
||||
struct pch_gbe_stats {
|
||||
char string[ETH_GSTRING_LEN];
|
||||
size_t size;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
#define PCH_GBE_STAT(m) \
|
||||
{ \
|
||||
.string = #m, \
|
||||
.size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m), \
|
||||
.offset = offsetof(struct pch_gbe_hw_stats, m), \
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_gstrings_stats - ethtool information status name list
|
||||
*/
|
||||
static const struct pch_gbe_stats pch_gbe_gstrings_stats[] = {
|
||||
PCH_GBE_STAT(rx_packets),
|
||||
PCH_GBE_STAT(tx_packets),
|
||||
PCH_GBE_STAT(rx_bytes),
|
||||
PCH_GBE_STAT(tx_bytes),
|
||||
PCH_GBE_STAT(rx_errors),
|
||||
PCH_GBE_STAT(tx_errors),
|
||||
PCH_GBE_STAT(rx_dropped),
|
||||
PCH_GBE_STAT(tx_dropped),
|
||||
PCH_GBE_STAT(multicast),
|
||||
PCH_GBE_STAT(collisions),
|
||||
PCH_GBE_STAT(rx_crc_errors),
|
||||
PCH_GBE_STAT(rx_frame_errors),
|
||||
PCH_GBE_STAT(rx_alloc_buff_failed),
|
||||
PCH_GBE_STAT(tx_length_errors),
|
||||
PCH_GBE_STAT(tx_aborted_errors),
|
||||
PCH_GBE_STAT(tx_carrier_errors),
|
||||
PCH_GBE_STAT(tx_timeout_count),
|
||||
PCH_GBE_STAT(tx_restart_count),
|
||||
PCH_GBE_STAT(intr_rx_dsc_empty_count),
|
||||
PCH_GBE_STAT(intr_rx_frame_err_count),
|
||||
PCH_GBE_STAT(intr_rx_fifo_err_count),
|
||||
PCH_GBE_STAT(intr_rx_dma_err_count),
|
||||
PCH_GBE_STAT(intr_tx_fifo_err_count),
|
||||
PCH_GBE_STAT(intr_tx_dma_err_count),
|
||||
PCH_GBE_STAT(intr_tcpip_err_count)
|
||||
};
|
||||
|
||||
#define PCH_GBE_QUEUE_STATS_LEN 0
|
||||
#define PCH_GBE_GLOBAL_STATS_LEN ARRAY_SIZE(pch_gbe_gstrings_stats)
|
||||
#define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN)
|
||||
|
||||
#define PCH_GBE_MAC_REGS_LEN (sizeof(struct pch_gbe_regs) / 4)
|
||||
#define PCH_GBE_REGS_LEN (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN)
|
||||
/**
|
||||
* pch_gbe_get_settings - Get device-specific settings
|
||||
* @netdev: Network interface device structure
|
||||
* @ecmd: Ethtool command
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_get_settings(struct net_device *netdev,
|
||||
struct ethtool_cmd *ecmd)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
int ret;
|
||||
|
||||
ret = mii_ethtool_gset(&adapter->mii, ecmd);
|
||||
ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half);
|
||||
ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
|
||||
|
||||
if (!netif_carrier_ok(adapter->netdev))
|
||||
ecmd->speed = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_set_settings - Set device-specific settings
|
||||
* @netdev: Network interface device structure
|
||||
* @ecmd: Ethtool command
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_set_settings(struct net_device *netdev,
|
||||
struct ethtool_cmd *ecmd)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct pch_gbe_hw *hw = &adapter->hw;
|
||||
int ret;
|
||||
|
||||
pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
|
||||
|
||||
if (ecmd->speed == -1)
|
||||
ecmd->speed = SPEED_1000;
|
||||
ecmd->duplex = DUPLEX_FULL;
|
||||
ret = mii_ethtool_sset(&adapter->mii, ecmd);
|
||||
if (ret) {
|
||||
pr_err("Error: mii_ethtool_sset\n");
|
||||
return ret;
|
||||
}
|
||||
hw->mac.link_speed = ecmd->speed;
|
||||
hw->mac.link_duplex = ecmd->duplex;
|
||||
hw->phy.autoneg_advertised = ecmd->advertising;
|
||||
hw->mac.autoneg = ecmd->autoneg;
|
||||
pch_gbe_hal_phy_sw_reset(hw);
|
||||
|
||||
/* reset the link */
|
||||
if (netif_running(adapter->netdev)) {
|
||||
pch_gbe_down(adapter);
|
||||
ret = pch_gbe_up(adapter);
|
||||
} else {
|
||||
pch_gbe_reset(adapter);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_regs_len - Report the size of device registers
|
||||
* @netdev: Network interface device structure
|
||||
* Returns: the size of device registers.
|
||||
*/
|
||||
static int pch_gbe_get_regs_len(struct net_device *netdev)
|
||||
{
|
||||
return PCH_GBE_REGS_LEN * (int)sizeof(u32);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_drvinfo - Report driver information
|
||||
* @netdev: Network interface device structure
|
||||
* @drvinfo: Driver information structure
|
||||
*/
|
||||
static void pch_gbe_get_drvinfo(struct net_device *netdev,
|
||||
struct ethtool_drvinfo *drvinfo)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
strcpy(drvinfo->driver, KBUILD_MODNAME);
|
||||
strcpy(drvinfo->version, pch_driver_version);
|
||||
strcpy(drvinfo->fw_version, "N/A");
|
||||
strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
|
||||
drvinfo->regdump_len = pch_gbe_get_regs_len(netdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_regs - Get device registers
|
||||
* @netdev: Network interface device structure
|
||||
* @regs: Ethtool register structure
|
||||
* @p: Buffer pointer of read device register date
|
||||
*/
|
||||
static void pch_gbe_get_regs(struct net_device *netdev,
|
||||
struct ethtool_regs *regs, void *p)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct pch_gbe_hw *hw = &adapter->hw;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
u32 *regs_buff = p;
|
||||
u16 i, tmp;
|
||||
|
||||
regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device;
|
||||
for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++)
|
||||
*regs_buff++ = ioread32(&hw->reg->INT_ST + i);
|
||||
/* PHY register */
|
||||
for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) {
|
||||
pch_gbe_hal_read_phy_reg(&adapter->hw, i, &tmp);
|
||||
*regs_buff++ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_wol - Report whether Wake-on-Lan is enabled
|
||||
* @netdev: Network interface device structure
|
||||
* @wol: Wake-on-Lan information
|
||||
*/
|
||||
static void pch_gbe_get_wol(struct net_device *netdev,
|
||||
struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
|
||||
wol->wolopts = 0;
|
||||
|
||||
if ((adapter->wake_up_evt & PCH_GBE_WLC_IND))
|
||||
wol->wolopts |= WAKE_UCAST;
|
||||
if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT))
|
||||
wol->wolopts |= WAKE_MCAST;
|
||||
if ((adapter->wake_up_evt & PCH_GBE_WLC_BR))
|
||||
wol->wolopts |= WAKE_BCAST;
|
||||
if ((adapter->wake_up_evt & PCH_GBE_WLC_MP))
|
||||
wol->wolopts |= WAKE_MAGIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_set_wol - Turn Wake-on-Lan on or off
|
||||
* @netdev: Network interface device structure
|
||||
* @wol: Pointer of wake-on-Lan information straucture
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_set_wol(struct net_device *netdev,
|
||||
struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)))
|
||||
return -EOPNOTSUPP;
|
||||
/* these settings will always override what we currently have */
|
||||
adapter->wake_up_evt = 0;
|
||||
|
||||
if ((wol->wolopts & WAKE_UCAST))
|
||||
adapter->wake_up_evt |= PCH_GBE_WLC_IND;
|
||||
if ((wol->wolopts & WAKE_MCAST))
|
||||
adapter->wake_up_evt |= PCH_GBE_WLC_MLT;
|
||||
if ((wol->wolopts & WAKE_BCAST))
|
||||
adapter->wake_up_evt |= PCH_GBE_WLC_BR;
|
||||
if ((wol->wolopts & WAKE_MAGIC))
|
||||
adapter->wake_up_evt |= PCH_GBE_WLC_MP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_nway_reset - Restart autonegotiation
|
||||
* @netdev: Network interface device structure
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_nway_reset(struct net_device *netdev)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
return mii_nway_restart(&adapter->mii);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_ringparam - Report ring sizes
|
||||
* @netdev: Network interface device structure
|
||||
* @ring: Ring param structure
|
||||
*/
|
||||
static void pch_gbe_get_ringparam(struct net_device *netdev,
|
||||
struct ethtool_ringparam *ring)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct pch_gbe_tx_ring *txdr = adapter->tx_ring;
|
||||
struct pch_gbe_rx_ring *rxdr = adapter->rx_ring;
|
||||
|
||||
ring->rx_max_pending = PCH_GBE_MAX_RXD;
|
||||
ring->tx_max_pending = PCH_GBE_MAX_TXD;
|
||||
ring->rx_mini_max_pending = 0;
|
||||
ring->rx_jumbo_max_pending = 0;
|
||||
ring->rx_pending = rxdr->count;
|
||||
ring->tx_pending = txdr->count;
|
||||
ring->rx_mini_pending = 0;
|
||||
ring->rx_jumbo_pending = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_set_ringparam - Set ring sizes
|
||||
* @netdev: Network interface device structure
|
||||
* @ring: Ring param structure
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_set_ringparam(struct net_device *netdev,
|
||||
struct ethtool_ringparam *ring)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct pch_gbe_tx_ring *txdr, *tx_old;
|
||||
struct pch_gbe_rx_ring *rxdr, *rx_old;
|
||||
int tx_ring_size, rx_ring_size;
|
||||
int err = 0;
|
||||
|
||||
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
|
||||
return -EINVAL;
|
||||
tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring);
|
||||
rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring);
|
||||
|
||||
if ((netif_running(adapter->netdev)))
|
||||
pch_gbe_down(adapter);
|
||||
tx_old = adapter->tx_ring;
|
||||
rx_old = adapter->rx_ring;
|
||||
|
||||
txdr = kzalloc(tx_ring_size, GFP_KERNEL);
|
||||
if (!txdr) {
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_tx;
|
||||
}
|
||||
rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
|
||||
if (!rxdr) {
|
||||
err = -ENOMEM;
|
||||
goto err_alloc_rx;
|
||||
}
|
||||
adapter->tx_ring = txdr;
|
||||
adapter->rx_ring = rxdr;
|
||||
|
||||
rxdr->count =
|
||||
clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
|
||||
rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE);
|
||||
|
||||
txdr->count =
|
||||
clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
|
||||
txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE);
|
||||
|
||||
if ((netif_running(adapter->netdev))) {
|
||||
/* Try to get new resources before deleting old */
|
||||
err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);
|
||||
if (err)
|
||||
goto err_setup_rx;
|
||||
err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);
|
||||
if (err)
|
||||
goto err_setup_tx;
|
||||
/* save the new, restore the old in order to free it,
|
||||
* then restore the new back again */
|
||||
#ifdef RINGFREE
|
||||
adapter->rx_ring = rx_old;
|
||||
adapter->tx_ring = tx_old;
|
||||
pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
|
||||
pch_gbe_free_tx_resources(adapter, adapter->tx_ring);
|
||||
kfree(tx_old);
|
||||
kfree(rx_old);
|
||||
adapter->rx_ring = rxdr;
|
||||
adapter->tx_ring = txdr;
|
||||
#else
|
||||
pch_gbe_free_rx_resources(adapter, rx_old);
|
||||
pch_gbe_free_tx_resources(adapter, tx_old);
|
||||
kfree(tx_old);
|
||||
kfree(rx_old);
|
||||
adapter->rx_ring = rxdr;
|
||||
adapter->tx_ring = txdr;
|
||||
#endif
|
||||
err = pch_gbe_up(adapter);
|
||||
}
|
||||
return err;
|
||||
|
||||
err_setup_tx:
|
||||
pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
|
||||
err_setup_rx:
|
||||
adapter->rx_ring = rx_old;
|
||||
adapter->tx_ring = tx_old;
|
||||
kfree(rxdr);
|
||||
err_alloc_rx:
|
||||
kfree(txdr);
|
||||
err_alloc_tx:
|
||||
if (netif_running(adapter->netdev))
|
||||
pch_gbe_up(adapter);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_pauseparam - Report pause parameters
|
||||
* @netdev: Network interface device structure
|
||||
* @pause: Pause parameters structure
|
||||
*/
|
||||
static void pch_gbe_get_pauseparam(struct net_device *netdev,
|
||||
struct ethtool_pauseparam *pause)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct pch_gbe_hw *hw = &adapter->hw;
|
||||
|
||||
pause->autoneg =
|
||||
((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE);
|
||||
|
||||
if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) {
|
||||
pause->rx_pause = 1;
|
||||
} else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) {
|
||||
pause->tx_pause = 1;
|
||||
} else if (hw->mac.fc == PCH_GBE_FC_FULL) {
|
||||
pause->rx_pause = 1;
|
||||
pause->tx_pause = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_set_pauseparam - Set pause paramters
|
||||
* @netdev: Network interface device structure
|
||||
* @pause: Pause parameters structure
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_set_pauseparam(struct net_device *netdev,
|
||||
struct ethtool_pauseparam *pause)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct pch_gbe_hw *hw = &adapter->hw;
|
||||
int ret = 0;
|
||||
|
||||
hw->mac.fc_autoneg = pause->autoneg;
|
||||
if ((pause->rx_pause) && (pause->tx_pause))
|
||||
hw->mac.fc = PCH_GBE_FC_FULL;
|
||||
else if ((pause->rx_pause) && (!pause->tx_pause))
|
||||
hw->mac.fc = PCH_GBE_FC_RX_PAUSE;
|
||||
else if ((!pause->rx_pause) && (pause->tx_pause))
|
||||
hw->mac.fc = PCH_GBE_FC_TX_PAUSE;
|
||||
else if ((!pause->rx_pause) && (!pause->tx_pause))
|
||||
hw->mac.fc = PCH_GBE_FC_NONE;
|
||||
|
||||
if (hw->mac.fc_autoneg == AUTONEG_ENABLE) {
|
||||
if ((netif_running(adapter->netdev))) {
|
||||
pch_gbe_down(adapter);
|
||||
ret = pch_gbe_up(adapter);
|
||||
} else {
|
||||
pch_gbe_reset(adapter);
|
||||
}
|
||||
} else {
|
||||
ret = pch_gbe_mac_force_mac_fc(hw);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off
|
||||
* @netdev: Network interface device structure
|
||||
* Returns
|
||||
* true(1): Checksum On
|
||||
* false(0): Checksum Off
|
||||
*/
|
||||
static u32 pch_gbe_get_rx_csum(struct net_device *netdev)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
return adapter->rx_csum;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_set_rx_csum - Turn receive checksum on or off
|
||||
* @netdev: Network interface device structure
|
||||
* @data: Checksum On[true] or Off[false]
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
adapter->rx_csum = data;
|
||||
if ((netif_running(netdev)))
|
||||
pch_gbe_reinit_locked(adapter);
|
||||
else
|
||||
pch_gbe_reset(adapter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_tx_csum - Report whether transmit checksums are turned on or off
|
||||
* @netdev: Network interface device structure
|
||||
* Returns
|
||||
* true(1): Checksum On
|
||||
* false(0): Checksum Off
|
||||
*/
|
||||
static u32 pch_gbe_get_tx_csum(struct net_device *netdev)
|
||||
{
|
||||
return (netdev->features & NETIF_F_HW_CSUM) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_set_tx_csum - Turn transmit checksums on or off
|
||||
* @netdev: Network interface device structure
|
||||
* @data: Checksum on[true] or off[false]
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
adapter->tx_csum = data;
|
||||
if (data)
|
||||
netdev->features |= NETIF_F_HW_CSUM;
|
||||
else
|
||||
netdev->features &= ~NETIF_F_HW_CSUM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_strings - Return a set of strings that describe the requested
|
||||
* objects
|
||||
* @netdev: Network interface device structure
|
||||
* @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]
|
||||
* @data: Pointer of read string data.
|
||||
*/
|
||||
static void pch_gbe_get_strings(struct net_device *netdev, u32 stringset,
|
||||
u8 *data)
|
||||
{
|
||||
u8 *p = data;
|
||||
int i;
|
||||
|
||||
switch (stringset) {
|
||||
case (u32) ETH_SS_STATS:
|
||||
for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
|
||||
memcpy(p, pch_gbe_gstrings_stats[i].string,
|
||||
ETH_GSTRING_LEN);
|
||||
p += ETH_GSTRING_LEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_get_ethtool_stats - Return statistics about the device
|
||||
* @netdev: Network interface device structure
|
||||
* @stats: Ethtool statue structure
|
||||
* @data: Pointer of read status area
|
||||
*/
|
||||
static void pch_gbe_get_ethtool_stats(struct net_device *netdev,
|
||||
struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter = netdev_priv(netdev);
|
||||
int i;
|
||||
const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats;
|
||||
char *hw_stats = (char *)&adapter->stats;
|
||||
|
||||
pch_gbe_update_stats(adapter);
|
||||
for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
|
||||
char *p = hw_stats + gstats->offset;
|
||||
data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p);
|
||||
gstats++;
|
||||
}
|
||||
}
|
||||
|
||||
static int pch_gbe_get_sset_count(struct net_device *netdev, int sset)
|
||||
{
|
||||
switch (sset) {
|
||||
case ETH_SS_STATS:
|
||||
return PCH_GBE_STATS_LEN;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct ethtool_ops pch_gbe_ethtool_ops = {
|
||||
.get_settings = pch_gbe_get_settings,
|
||||
.set_settings = pch_gbe_set_settings,
|
||||
.get_drvinfo = pch_gbe_get_drvinfo,
|
||||
.get_regs_len = pch_gbe_get_regs_len,
|
||||
.get_regs = pch_gbe_get_regs,
|
||||
.get_wol = pch_gbe_get_wol,
|
||||
.set_wol = pch_gbe_set_wol,
|
||||
.nway_reset = pch_gbe_nway_reset,
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_ringparam = pch_gbe_get_ringparam,
|
||||
.set_ringparam = pch_gbe_set_ringparam,
|
||||
.get_pauseparam = pch_gbe_get_pauseparam,
|
||||
.set_pauseparam = pch_gbe_set_pauseparam,
|
||||
.get_rx_csum = pch_gbe_get_rx_csum,
|
||||
.set_rx_csum = pch_gbe_set_rx_csum,
|
||||
.get_tx_csum = pch_gbe_get_tx_csum,
|
||||
.set_tx_csum = pch_gbe_set_tx_csum,
|
||||
.get_strings = pch_gbe_get_strings,
|
||||
.get_ethtool_stats = pch_gbe_get_ethtool_stats,
|
||||
.get_sset_count = pch_gbe_get_sset_count,
|
||||
};
|
||||
|
||||
void pch_gbe_set_ethtool_ops(struct net_device *netdev)
|
||||
{
|
||||
SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops);
|
||||
}
|
2473
drivers/net/pch_gbe/pch_gbe_main.c
Normal file
2473
drivers/net/pch_gbe/pch_gbe_main.c
Normal file
File diff suppressed because it is too large
Load Diff
499
drivers/net/pch_gbe/pch_gbe_param.c
Normal file
499
drivers/net/pch_gbe/pch_gbe_param.c
Normal file
@ -0,0 +1,499 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "pch_gbe.h"
|
||||
|
||||
#define OPTION_UNSET -1
|
||||
#define OPTION_DISABLED 0
|
||||
#define OPTION_ENABLED 1
|
||||
|
||||
/**
|
||||
* TxDescriptors - Transmit Descriptor Count
|
||||
* @Valid Range: PCH_GBE_MIN_TXD - PCH_GBE_MAX_TXD
|
||||
* @Default Value: PCH_GBE_DEFAULT_TXD
|
||||
*/
|
||||
static int TxDescriptors = OPTION_UNSET;
|
||||
module_param(TxDescriptors, int, 0);
|
||||
MODULE_PARM_DESC(TxDescriptors, "Number of transmit descriptors");
|
||||
|
||||
/**
|
||||
* RxDescriptors -Receive Descriptor Count
|
||||
* @Valid Range: PCH_GBE_MIN_RXD - PCH_GBE_MAX_RXD
|
||||
* @Default Value: PCH_GBE_DEFAULT_RXD
|
||||
*/
|
||||
static int RxDescriptors = OPTION_UNSET;
|
||||
module_param(RxDescriptors, int, 0);
|
||||
MODULE_PARM_DESC(RxDescriptors, "Number of receive descriptors");
|
||||
|
||||
/**
|
||||
* Speed - User Specified Speed Override
|
||||
* @Valid Range: 0, 10, 100, 1000
|
||||
* - 0: auto-negotiate at all supported speeds
|
||||
* - 10: only link at 10 Mbps
|
||||
* - 100: only link at 100 Mbps
|
||||
* - 1000: only link at 1000 Mbps
|
||||
* @Default Value: 0
|
||||
*/
|
||||
static int Speed = OPTION_UNSET;
|
||||
module_param(Speed, int, 0);
|
||||
MODULE_PARM_DESC(Speed, "Speed setting");
|
||||
|
||||
/**
|
||||
* Duplex - User Specified Duplex Override
|
||||
* @Valid Range: 0-2
|
||||
* - 0: auto-negotiate for duplex
|
||||
* - 1: only link at half duplex
|
||||
* - 2: only link at full duplex
|
||||
* @Default Value: 0
|
||||
*/
|
||||
static int Duplex = OPTION_UNSET;
|
||||
module_param(Duplex, int, 0);
|
||||
MODULE_PARM_DESC(Duplex, "Duplex setting");
|
||||
|
||||
#define HALF_DUPLEX 1
|
||||
#define FULL_DUPLEX 2
|
||||
|
||||
/**
|
||||
* AutoNeg - Auto-negotiation Advertisement Override
|
||||
* @Valid Range: 0x01-0x0F, 0x20-0x2F
|
||||
*
|
||||
* The AutoNeg value is a bit mask describing which speed and duplex
|
||||
* combinations should be advertised during auto-negotiation.
|
||||
* The supported speed and duplex modes are listed below
|
||||
*
|
||||
* Bit 7 6 5 4 3 2 1 0
|
||||
* Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10
|
||||
* Duplex Full Full Half Full Half
|
||||
*
|
||||
* @Default Value: 0x2F (copper)
|
||||
*/
|
||||
static int AutoNeg = OPTION_UNSET;
|
||||
module_param(AutoNeg, int, 0);
|
||||
MODULE_PARM_DESC(AutoNeg, "Advertised auto-negotiation setting");
|
||||
|
||||
#define PHY_ADVERTISE_10_HALF 0x0001
|
||||
#define PHY_ADVERTISE_10_FULL 0x0002
|
||||
#define PHY_ADVERTISE_100_HALF 0x0004
|
||||
#define PHY_ADVERTISE_100_FULL 0x0008
|
||||
#define PHY_ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */
|
||||
#define PHY_ADVERTISE_1000_FULL 0x0020
|
||||
#define PCH_AUTONEG_ADVERTISE_DEFAULT 0x2F
|
||||
|
||||
/**
|
||||
* FlowControl - User Specified Flow Control Override
|
||||
* @Valid Range: 0-3
|
||||
* - 0: No Flow Control
|
||||
* - 1: Rx only, respond to PAUSE frames but do not generate them
|
||||
* - 2: Tx only, generate PAUSE frames but ignore them on receive
|
||||
* - 3: Full Flow Control Support
|
||||
* @Default Value: Read flow control settings from the EEPROM
|
||||
*/
|
||||
static int FlowControl = OPTION_UNSET;
|
||||
module_param(FlowControl, int, 0);
|
||||
MODULE_PARM_DESC(FlowControl, "Flow Control setting");
|
||||
|
||||
/*
|
||||
* XsumRX - Receive Checksum Offload Enable/Disable
|
||||
* @Valid Range: 0, 1
|
||||
* - 0: disables all checksum offload
|
||||
* - 1: enables receive IP/TCP/UDP checksum offload
|
||||
* @Default Value: PCH_GBE_DEFAULT_RX_CSUM
|
||||
*/
|
||||
static int XsumRX = OPTION_UNSET;
|
||||
module_param(XsumRX, int, 0);
|
||||
MODULE_PARM_DESC(XsumRX, "Disable or enable Receive Checksum offload");
|
||||
|
||||
#define PCH_GBE_DEFAULT_RX_CSUM true /* trueorfalse */
|
||||
|
||||
/*
|
||||
* XsumTX - Transmit Checksum Offload Enable/Disable
|
||||
* @Valid Range: 0, 1
|
||||
* - 0: disables all checksum offload
|
||||
* - 1: enables transmit IP/TCP/UDP checksum offload
|
||||
* @Default Value: PCH_GBE_DEFAULT_TX_CSUM
|
||||
*/
|
||||
static int XsumTX = OPTION_UNSET;
|
||||
module_param(XsumTX, int, 0);
|
||||
MODULE_PARM_DESC(XsumTX, "Disable or enable Transmit Checksum offload");
|
||||
|
||||
#define PCH_GBE_DEFAULT_TX_CSUM true /* trueorfalse */
|
||||
|
||||
/**
|
||||
* pch_gbe_option - Force the MAC's flow control settings
|
||||
* @hw: Pointer to the HW structure
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
struct pch_gbe_option {
|
||||
enum { enable_option, range_option, list_option } type;
|
||||
char *name;
|
||||
char *err;
|
||||
int def;
|
||||
union {
|
||||
struct { /* range_option info */
|
||||
int min;
|
||||
int max;
|
||||
} r;
|
||||
struct { /* list_option info */
|
||||
int nr;
|
||||
const struct pch_gbe_opt_list { int i; char *str; } *p;
|
||||
} l;
|
||||
} arg;
|
||||
};
|
||||
|
||||
static const struct pch_gbe_opt_list speed_list[] = {
|
||||
{ 0, "" },
|
||||
{ SPEED_10, "" },
|
||||
{ SPEED_100, "" },
|
||||
{ SPEED_1000, "" }
|
||||
};
|
||||
|
||||
static const struct pch_gbe_opt_list dplx_list[] = {
|
||||
{ 0, "" },
|
||||
{ HALF_DUPLEX, "" },
|
||||
{ FULL_DUPLEX, "" }
|
||||
};
|
||||
|
||||
static const struct pch_gbe_opt_list an_list[] =
|
||||
#define AA "AutoNeg advertising "
|
||||
{{ 0x01, AA "10/HD" },
|
||||
{ 0x02, AA "10/FD" },
|
||||
{ 0x03, AA "10/FD, 10/HD" },
|
||||
{ 0x04, AA "100/HD" },
|
||||
{ 0x05, AA "100/HD, 10/HD" },
|
||||
{ 0x06, AA "100/HD, 10/FD" },
|
||||
{ 0x07, AA "100/HD, 10/FD, 10/HD" },
|
||||
{ 0x08, AA "100/FD" },
|
||||
{ 0x09, AA "100/FD, 10/HD" },
|
||||
{ 0x0a, AA "100/FD, 10/FD" },
|
||||
{ 0x0b, AA "100/FD, 10/FD, 10/HD" },
|
||||
{ 0x0c, AA "100/FD, 100/HD" },
|
||||
{ 0x0d, AA "100/FD, 100/HD, 10/HD" },
|
||||
{ 0x0e, AA "100/FD, 100/HD, 10/FD" },
|
||||
{ 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },
|
||||
{ 0x20, AA "1000/FD" },
|
||||
{ 0x21, AA "1000/FD, 10/HD" },
|
||||
{ 0x22, AA "1000/FD, 10/FD" },
|
||||
{ 0x23, AA "1000/FD, 10/FD, 10/HD" },
|
||||
{ 0x24, AA "1000/FD, 100/HD" },
|
||||
{ 0x25, AA "1000/FD, 100/HD, 10/HD" },
|
||||
{ 0x26, AA "1000/FD, 100/HD, 10/FD" },
|
||||
{ 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },
|
||||
{ 0x28, AA "1000/FD, 100/FD" },
|
||||
{ 0x29, AA "1000/FD, 100/FD, 10/HD" },
|
||||
{ 0x2a, AA "1000/FD, 100/FD, 10/FD" },
|
||||
{ 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },
|
||||
{ 0x2c, AA "1000/FD, 100/FD, 100/HD" },
|
||||
{ 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },
|
||||
{ 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
|
||||
{ 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }
|
||||
};
|
||||
|
||||
static const struct pch_gbe_opt_list fc_list[] = {
|
||||
{ PCH_GBE_FC_NONE, "Flow Control Disabled" },
|
||||
{ PCH_GBE_FC_RX_PAUSE, "Flow Control Receive Only" },
|
||||
{ PCH_GBE_FC_TX_PAUSE, "Flow Control Transmit Only" },
|
||||
{ PCH_GBE_FC_FULL, "Flow Control Enabled" }
|
||||
};
|
||||
|
||||
/**
|
||||
* pch_gbe_validate_option - Validate option
|
||||
* @value: value
|
||||
* @opt: option
|
||||
* @adapter: Board private structure
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
static int pch_gbe_validate_option(int *value,
|
||||
const struct pch_gbe_option *opt,
|
||||
struct pch_gbe_adapter *adapter)
|
||||
{
|
||||
if (*value == OPTION_UNSET) {
|
||||
*value = opt->def;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (opt->type) {
|
||||
case enable_option:
|
||||
switch (*value) {
|
||||
case OPTION_ENABLED:
|
||||
pr_debug("%s Enabled\n", opt->name);
|
||||
return 0;
|
||||
case OPTION_DISABLED:
|
||||
pr_debug("%s Disabled\n", opt->name);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case range_option:
|
||||
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
|
||||
pr_debug("%s set to %i\n", opt->name, *value);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case list_option: {
|
||||
int i;
|
||||
const struct pch_gbe_opt_list *ent;
|
||||
|
||||
for (i = 0; i < opt->arg.l.nr; i++) {
|
||||
ent = &opt->arg.l.p[i];
|
||||
if (*value == ent->i) {
|
||||
if (ent->str[0] != '\0')
|
||||
pr_debug("%s\n", ent->str);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
pr_debug("Invalid %s value specified (%i) %s\n",
|
||||
opt->name, *value, opt->err);
|
||||
*value = opt->def;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_check_copper_options - Range Checking for Link Options, Copper Version
|
||||
* @adapter: Board private structure
|
||||
*/
|
||||
static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter)
|
||||
{
|
||||
struct pch_gbe_hw *hw = &adapter->hw;
|
||||
int speed, dplx;
|
||||
|
||||
{ /* Speed */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = list_option,
|
||||
.name = "Speed",
|
||||
.err = "parameter ignored",
|
||||
.def = 0,
|
||||
.arg = { .l = { .nr = (int)ARRAY_SIZE(speed_list),
|
||||
.p = speed_list } }
|
||||
};
|
||||
speed = Speed;
|
||||
pch_gbe_validate_option(&speed, &opt, adapter);
|
||||
}
|
||||
{ /* Duplex */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = list_option,
|
||||
.name = "Duplex",
|
||||
.err = "parameter ignored",
|
||||
.def = 0,
|
||||
.arg = { .l = { .nr = (int)ARRAY_SIZE(dplx_list),
|
||||
.p = dplx_list } }
|
||||
};
|
||||
dplx = Duplex;
|
||||
pch_gbe_validate_option(&dplx, &opt, adapter);
|
||||
}
|
||||
|
||||
{ /* Autoneg */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = list_option,
|
||||
.name = "AutoNeg",
|
||||
.err = "parameter ignored",
|
||||
.def = PCH_AUTONEG_ADVERTISE_DEFAULT,
|
||||
.arg = { .l = { .nr = (int)ARRAY_SIZE(an_list),
|
||||
.p = an_list} }
|
||||
};
|
||||
if (speed || dplx) {
|
||||
pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n");
|
||||
hw->phy.autoneg_advertised = opt.def;
|
||||
} else {
|
||||
hw->phy.autoneg_advertised = AutoNeg;
|
||||
pch_gbe_validate_option(
|
||||
(int *)(&hw->phy.autoneg_advertised),
|
||||
&opt, adapter);
|
||||
}
|
||||
}
|
||||
|
||||
switch (speed + dplx) {
|
||||
case 0:
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 1;
|
||||
if ((speed || dplx))
|
||||
pr_debug("Speed and duplex autonegotiation enabled\n");
|
||||
hw->mac.link_speed = SPEED_10;
|
||||
hw->mac.link_duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case HALF_DUPLEX:
|
||||
pr_debug("Half Duplex specified without Speed\n");
|
||||
pr_debug("Using Autonegotiation at Half Duplex only\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 1;
|
||||
hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
|
||||
PHY_ADVERTISE_100_HALF;
|
||||
hw->mac.link_speed = SPEED_10;
|
||||
hw->mac.link_duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case FULL_DUPLEX:
|
||||
pr_debug("Full Duplex specified without Speed\n");
|
||||
pr_debug("Using Autonegotiation at Full Duplex only\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 1;
|
||||
hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL |
|
||||
PHY_ADVERTISE_100_FULL |
|
||||
PHY_ADVERTISE_1000_FULL;
|
||||
hw->mac.link_speed = SPEED_10;
|
||||
hw->mac.link_duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case SPEED_10:
|
||||
pr_debug("10 Mbps Speed specified without Duplex\n");
|
||||
pr_debug("Using Autonegotiation at 10 Mbps only\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 1;
|
||||
hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
|
||||
PHY_ADVERTISE_10_FULL;
|
||||
hw->mac.link_speed = SPEED_10;
|
||||
hw->mac.link_duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case SPEED_10 + HALF_DUPLEX:
|
||||
pr_debug("Forcing to 10 Mbps Half Duplex\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 0;
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
hw->mac.link_speed = SPEED_10;
|
||||
hw->mac.link_duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case SPEED_10 + FULL_DUPLEX:
|
||||
pr_debug("Forcing to 10 Mbps Full Duplex\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 0;
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
hw->mac.link_speed = SPEED_10;
|
||||
hw->mac.link_duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case SPEED_100:
|
||||
pr_debug("100 Mbps Speed specified without Duplex\n");
|
||||
pr_debug("Using Autonegotiation at 100 Mbps only\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 1;
|
||||
hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF |
|
||||
PHY_ADVERTISE_100_FULL;
|
||||
hw->mac.link_speed = SPEED_100;
|
||||
hw->mac.link_duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case SPEED_100 + HALF_DUPLEX:
|
||||
pr_debug("Forcing to 100 Mbps Half Duplex\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 0;
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
hw->mac.link_speed = SPEED_100;
|
||||
hw->mac.link_duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case SPEED_100 + FULL_DUPLEX:
|
||||
pr_debug("Forcing to 100 Mbps Full Duplex\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 0;
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
hw->mac.link_speed = SPEED_100;
|
||||
hw->mac.link_duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
pr_debug("1000 Mbps Speed specified without Duplex\n");
|
||||
goto full_duplex_only;
|
||||
case SPEED_1000 + HALF_DUPLEX:
|
||||
pr_debug("Half Duplex is not supported at 1000 Mbps\n");
|
||||
/* fall through */
|
||||
case SPEED_1000 + FULL_DUPLEX:
|
||||
full_duplex_only:
|
||||
pr_debug("Using Autonegotiation at 1000 Mbps Full Duplex only\n");
|
||||
hw->mac.autoneg = hw->mac.fc_autoneg = 1;
|
||||
hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL;
|
||||
hw->mac.link_speed = SPEED_1000;
|
||||
hw->mac.link_duplex = DUPLEX_FULL;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_check_options - Range Checking for Command Line Parameters
|
||||
* @adapter: Board private structure
|
||||
*/
|
||||
void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
|
||||
{
|
||||
struct pch_gbe_hw *hw = &adapter->hw;
|
||||
|
||||
{ /* Transmit Descriptor Count */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = range_option,
|
||||
.name = "Transmit Descriptors",
|
||||
.err = "using default of "
|
||||
__MODULE_STRING(PCH_GBE_DEFAULT_TXD),
|
||||
.def = PCH_GBE_DEFAULT_TXD,
|
||||
.arg = { .r = { .min = PCH_GBE_MIN_TXD } },
|
||||
.arg = { .r = { .max = PCH_GBE_MAX_TXD } }
|
||||
};
|
||||
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
|
||||
tx_ring->count = TxDescriptors;
|
||||
pch_gbe_validate_option(&tx_ring->count, &opt, adapter);
|
||||
tx_ring->count = roundup(tx_ring->count,
|
||||
PCH_GBE_TX_DESC_MULTIPLE);
|
||||
}
|
||||
{ /* Receive Descriptor Count */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = range_option,
|
||||
.name = "Receive Descriptors",
|
||||
.err = "using default of "
|
||||
__MODULE_STRING(PCH_GBE_DEFAULT_RXD),
|
||||
.def = PCH_GBE_DEFAULT_RXD,
|
||||
.arg = { .r = { .min = PCH_GBE_MIN_RXD } },
|
||||
.arg = { .r = { .max = PCH_GBE_MAX_RXD } }
|
||||
};
|
||||
struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
|
||||
rx_ring->count = RxDescriptors;
|
||||
pch_gbe_validate_option(&rx_ring->count, &opt, adapter);
|
||||
rx_ring->count = roundup(rx_ring->count,
|
||||
PCH_GBE_RX_DESC_MULTIPLE);
|
||||
}
|
||||
{ /* Checksum Offload Enable/Disable */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = enable_option,
|
||||
.name = "Checksum Offload",
|
||||
.err = "defaulting to Enabled",
|
||||
.def = PCH_GBE_DEFAULT_RX_CSUM
|
||||
};
|
||||
adapter->rx_csum = XsumRX;
|
||||
pch_gbe_validate_option((int *)(&adapter->rx_csum),
|
||||
&opt, adapter);
|
||||
}
|
||||
{ /* Checksum Offload Enable/Disable */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = enable_option,
|
||||
.name = "Checksum Offload",
|
||||
.err = "defaulting to Enabled",
|
||||
.def = PCH_GBE_DEFAULT_TX_CSUM
|
||||
};
|
||||
adapter->tx_csum = XsumTX;
|
||||
pch_gbe_validate_option((int *)(&adapter->tx_csum),
|
||||
&opt, adapter);
|
||||
}
|
||||
{ /* Flow Control */
|
||||
static const struct pch_gbe_option opt = {
|
||||
.type = list_option,
|
||||
.name = "Flow Control",
|
||||
.err = "reading default settings from EEPROM",
|
||||
.def = PCH_GBE_FC_DEFAULT,
|
||||
.arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list),
|
||||
.p = fc_list } }
|
||||
};
|
||||
hw->mac.fc = FlowControl;
|
||||
pch_gbe_validate_option((int *)(&hw->mac.fc),
|
||||
&opt, adapter);
|
||||
}
|
||||
|
||||
pch_gbe_check_copper_options(adapter);
|
||||
}
|
274
drivers/net/pch_gbe/pch_gbe_phy.c
Normal file
274
drivers/net/pch_gbe/pch_gbe_phy.c
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "pch_gbe.h"
|
||||
#include "pch_gbe_phy.h"
|
||||
|
||||
#define PHY_MAX_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
|
||||
|
||||
/* PHY 1000 MII Register/Bit Definitions */
|
||||
/* PHY Registers defined by IEEE */
|
||||
#define PHY_CONTROL 0x00 /* Control Register */
|
||||
#define PHY_STATUS 0x01 /* Status Regiser */
|
||||
#define PHY_ID1 0x02 /* Phy Id Register (word 1) */
|
||||
#define PHY_ID2 0x03 /* Phy Id Register (word 2) */
|
||||
#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
|
||||
#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
|
||||
#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Register */
|
||||
#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
|
||||
#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
|
||||
#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Register */
|
||||
#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Register */
|
||||
#define PHY_EXT_STATUS 0x0F /* Extended Status Register */
|
||||
#define PHY_PHYSP_CONTROL 0x10 /* PHY Specific Control Register */
|
||||
#define PHY_EXT_PHYSP_CONTROL 0x14 /* Extended PHY Specific Control Register */
|
||||
#define PHY_LED_CONTROL 0x18 /* LED Control Register */
|
||||
#define PHY_EXT_PHYSP_STATUS 0x1B /* Extended PHY Specific Status Register */
|
||||
|
||||
/* PHY Control Register */
|
||||
#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
|
||||
#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
|
||||
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
|
||||
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
|
||||
#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
|
||||
#define MII_CR_POWER_DOWN 0x0800 /* Power down */
|
||||
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
|
||||
#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
|
||||
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
|
||||
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
|
||||
#define MII_CR_SPEED_1000 0x0040
|
||||
#define MII_CR_SPEED_100 0x2000
|
||||
#define MII_CR_SPEED_10 0x0000
|
||||
|
||||
/* PHY Status Register */
|
||||
#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
|
||||
#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
|
||||
#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
|
||||
#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
|
||||
#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
|
||||
#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
|
||||
#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
|
||||
#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
|
||||
#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
|
||||
#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
|
||||
#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
|
||||
#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
|
||||
#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
|
||||
#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
|
||||
#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
|
||||
|
||||
/* Phy Id Register (word 2) */
|
||||
#define PHY_REVISION_MASK 0x000F
|
||||
|
||||
/* PHY Specific Control Register */
|
||||
#define PHYSP_CTRL_ASSERT_CRS_TX 0x0800
|
||||
|
||||
|
||||
/* Default value of PHY register */
|
||||
#define PHY_CONTROL_DEFAULT 0x1140 /* Control Register */
|
||||
#define PHY_AUTONEG_ADV_DEFAULT 0x01e0 /* Autoneg Advertisement */
|
||||
#define PHY_NEXT_PAGE_TX_DEFAULT 0x2001 /* Next Page TX */
|
||||
#define PHY_1000T_CTRL_DEFAULT 0x0300 /* 1000Base-T Control Register */
|
||||
#define PHY_PHYSP_CONTROL_DEFAULT 0x01EE /* PHY Specific Control Register */
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_get_id - Retrieve the PHY ID and revision
|
||||
* @hw: Pointer to the HW structure
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* Negative value: Failed.
|
||||
*/
|
||||
s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw)
|
||||
{
|
||||
struct pch_gbe_phy_info *phy = &hw->phy;
|
||||
s32 ret;
|
||||
u16 phy_id1;
|
||||
u16 phy_id2;
|
||||
|
||||
ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID1, &phy_id1);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID2, &phy_id2);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* PHY_ID1: [bit15-0:ID(21-6)]
|
||||
* PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision]
|
||||
*/
|
||||
phy->id = (u32)phy_id1;
|
||||
phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10));
|
||||
phy->revision = (u32) (phy_id2 & 0x000F);
|
||||
pr_debug("phy->id : 0x%08x phy->revision : 0x%08x\n",
|
||||
phy->id, phy->revision);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_read_reg_miic - Read MII control register
|
||||
* @hw: Pointer to the HW structure
|
||||
* @offset: Register offset to be read
|
||||
* @data: Pointer to the read data
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* -EINVAL: Invalid argument.
|
||||
*/
|
||||
s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data)
|
||||
{
|
||||
struct pch_gbe_phy_info *phy = &hw->phy;
|
||||
|
||||
if (offset > PHY_MAX_REG_ADDRESS) {
|
||||
pr_err("PHY Address %d is out of range\n", offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
*data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,
|
||||
offset, (u16)0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_write_reg_miic - Write MII control register
|
||||
* @hw: Pointer to the HW structure
|
||||
* @offset: Register offset to be read
|
||||
* @data: data to write to register at offset
|
||||
* Returns
|
||||
* 0: Successful.
|
||||
* -EINVAL: Invalid argument.
|
||||
*/
|
||||
s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data)
|
||||
{
|
||||
struct pch_gbe_phy_info *phy = &hw->phy;
|
||||
|
||||
if (offset > PHY_MAX_REG_ADDRESS) {
|
||||
pr_err("PHY Address %d is out of range\n", offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,
|
||||
offset, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_sw_reset - PHY software reset
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw)
|
||||
{
|
||||
u16 phy_ctrl;
|
||||
|
||||
pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &phy_ctrl);
|
||||
phy_ctrl |= MII_CR_RESET;
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, phy_ctrl);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_hw_reset - PHY hardware reset
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw)
|
||||
{
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT);
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_AUTONEG_ADV,
|
||||
PHY_AUTONEG_ADV_DEFAULT);
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_NEXT_PAGE_TX,
|
||||
PHY_NEXT_PAGE_TX_DEFAULT);
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT);
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL,
|
||||
PHY_PHYSP_CONTROL_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_power_up - restore link in case the phy was powered down
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
void pch_gbe_phy_power_up(struct pch_gbe_hw *hw)
|
||||
{
|
||||
u16 mii_reg;
|
||||
|
||||
mii_reg = 0;
|
||||
/* Just clear the power down bit to wake the phy back up */
|
||||
/* according to the manual, the phy will retain its
|
||||
* settings across a power-down/up cycle */
|
||||
pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
|
||||
mii_reg &= ~MII_CR_POWER_DOWN;
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_power_down - Power down PHY
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
void pch_gbe_phy_power_down(struct pch_gbe_hw *hw)
|
||||
{
|
||||
u16 mii_reg;
|
||||
|
||||
mii_reg = 0;
|
||||
/* Power down the PHY so no link is implied when interface is down *
|
||||
* The PHY cannot be powered down if any of the following is TRUE *
|
||||
* (a) WoL is enabled
|
||||
* (b) AMT is active
|
||||
*/
|
||||
pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg);
|
||||
mii_reg |= MII_CR_POWER_DOWN;
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_set_rgmii - RGMII interface setting
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
|
||||
{
|
||||
pch_gbe_phy_sw_reset(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_gbe_phy_init_setting - PHY initial setting
|
||||
* @hw: Pointer to the HW structure
|
||||
*/
|
||||
void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
|
||||
{
|
||||
struct pch_gbe_adapter *adapter;
|
||||
struct ethtool_cmd cmd;
|
||||
int ret;
|
||||
u16 mii_reg;
|
||||
|
||||
adapter = container_of(hw, struct pch_gbe_adapter, hw);
|
||||
ret = mii_ethtool_gset(&adapter->mii, &cmd);
|
||||
if (ret)
|
||||
pr_err("Error: mii_ethtool_gset\n");
|
||||
|
||||
cmd.speed = hw->mac.link_speed;
|
||||
cmd.duplex = hw->mac.link_duplex;
|
||||
cmd.advertising = hw->phy.autoneg_advertised;
|
||||
cmd.autoneg = hw->mac.autoneg;
|
||||
pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);
|
||||
ret = mii_ethtool_sset(&adapter->mii, &cmd);
|
||||
if (ret)
|
||||
pr_err("Error: mii_ethtool_sset\n");
|
||||
|
||||
pch_gbe_phy_sw_reset(hw);
|
||||
|
||||
pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg);
|
||||
mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;
|
||||
pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg);
|
||||
|
||||
}
|
37
drivers/net/pch_gbe/pch_gbe_phy.h
Normal file
37
drivers/net/pch_gbe/pch_gbe_phy.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _PCH_GBE_PHY_H_
|
||||
#define _PCH_GBE_PHY_H_
|
||||
|
||||
#define PCH_GBE_PHY_REGS_LEN 32
|
||||
#define PCH_GBE_PHY_RESET_DELAY_US 10
|
||||
#define PCH_GBE_MAC_IFOP_RGMII
|
||||
|
||||
s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw);
|
||||
s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data);
|
||||
s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data);
|
||||
void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_phy_power_up(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_phy_power_down(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw);
|
||||
void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw);
|
||||
|
||||
#endif /* _PCH_GBE_PHY_H_ */
|
Loading…
Reference in New Issue
Block a user