ESXi-5.5-U1

This commit is contained in:
unknown 2015-10-23 18:29:35 -04:00
parent 91e0d39c98
commit 89a4bb14d0
79 changed files with 21997 additions and 8736 deletions

View file

@ -251,13 +251,8 @@ typedef struct vmk_EthHdr {
typedef struct vmk_VLANHdr {
/** High four bits of the VLAN ID. */
vmk_uint8 vlanIDHigh:4;
/** This field has two different interpretations. */
union {
/** The MAC addresses are in canonical format. */
vmk_uint8 canonical:1;
/** The frame is eligible to be dropped in the presence of congestion. */
vmk_uint8 dropEligible:1;
};
/** Priority tag. */
vmk_uint8 priority:3;
/** Low eight bits of the VLAN ID. */

View file

@ -251,13 +251,8 @@ typedef struct vmk_EthHdr {
typedef struct vmk_VLANHdr {
/** High four bits of the VLAN ID. */
vmk_uint8 vlanIDHigh:4;
/** This field has two different interpretations. */
union {
/** The MAC addresses are in canonical format. */
vmk_uint8 canonical:1;
/** The frame is eligible to be dropped in the presence of congestion. */
vmk_uint8 dropEligible:1;
};
/** Priority tag. */
vmk_uint8 priority:3;
/** Low eight bits of the VLAN ID. */

View file

@ -1,6 +1,6 @@
#define BUILD_NUMBER "build-1604073"
#define BUILD_NUMBER_NUMERIC 1604073
#define BUILD_NUMBER_NUMERIC_STRING "1604073"
#define PRODUCT_BUILD_NUMBER "product-build-4509"
#define PRODUCT_BUILD_NUMBER_NUMERIC 4509
#define PRODUCT_BUILD_NUMBER_NUMERIC_STRING "4509"
#define BUILD_NUMBER "build-1623387"
#define BUILD_NUMBER_NUMERIC 1623387
#define BUILD_NUMBER_NUMERIC_STRING "1623387"
#define PRODUCT_BUILD_NUMBER "product-build-4950"
#define PRODUCT_BUILD_NUMBER_NUMERIC 4950
#define PRODUCT_BUILD_NUMBER_NUMERIC_STRING "4950"

View file

@ -1,8 +1,13 @@
The following assumes the files disclosed for this package have been
copied to the directory "/usr/vmware/src", and any commands that need to
be executed for the disclosure should be executed from this directory
on a "centos-5.3-x64" system (see the file "SYSTEMS.txt" for definition
of this system).
copied to the directory "/usr/vmware/src":
rm -rf /usr/vmware/src
mkdir /usr/vmware/src
cp * /usr/vmware/src
And any commands that need to be executed for the disclosure should be
executed from this directory on a "centos-5.3-x64" system (see the file
"SYSTEMS.txt" for definition of this system).
This package should be built on a "centos-5.3-x64" system. Please see the
"System Configurations" document for a definition of the configuration

26
machines.cfgx Normal file
View file

@ -0,0 +1,26 @@
<verify>
<virtual-infrastructure>
<address>10.111.110.45</address>
<username>root</username>
<password>password</password>
<vm type="build">
<id>centos-5.3-x64</id>
<realname>Rush-CentOS-5.3-x64</realname>
<os>linux</os>
<username>root</username>
<password>welcome</password>
</vm>
</virtual-infrastructure>
<virtual-infrastructure>
<address>10.111.110.98</address>
<username>root</username>
<password>welcome</password>
<vm type="install">
<id>BDE-Management-Server</id>
<realname>management-server</realname>
<os>linux</os>
<username>root</username>
<password>vmware</password>
</vm>
</virtual-infrastructure>
</verify>

26
vmkdrivers-gpl.odpx Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<disclosure>
<name>vmkdrivers</name>
<version>gpl</version>
<category>VMWsource</category>
<build>
<target>centos-5.3-x64</target>
<files>
<file>vmkdrivers-gpl.tgz</file>
<file>collect-drivers.sh</file>
<file>update-drivers.sh</file>
</files>
<process>
<execute>tar xzf vmkdrivers-gpl.tgz</execute>
<execute>sh ./build-vmkdrivers.sh</execute>
<execute>mv collect-drivers.sh BLD/build/collect-drivers.sh</execute>
<execute>cd BLD/build</execute>
<execute>./collect-drivers.sh</execute>
</process>
<deliveries>
<delivery dir="BLD/build">drivers</delivery>
<delivery>update-drivers.sh</delivery>
</deliveries>
<output>centos-5.3-x64</output>
</build>
</disclosure>

View file

@ -1,5 +1,5 @@
/*
* Portions Copyright 2008 - 2010 VMware, Inc.
* Portions Copyright 2008 - 2013 VMware, Inc.
*/
/*
* ahci.c - AHCI SATA support
@ -54,7 +54,7 @@
#endif
#define DRV_NAME "ahci"
#define DRV_VERSION "3.0-17vmw"
#define DRV_VERSION "3.0-18vmw"
#if defined(__VMKLNX__)
static int ahci_skip_host_reset = 0;
@ -634,6 +634,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
{ PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
{ PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */
{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Wellsburg RAID */
{ PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */
{ PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
{ PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
{ PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
@ -1968,7 +1971,6 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) {
#if defined(__VMKLNX__)
if ((irq_stat & PORT_IRQ_PHYRDY) && (ap->link.device[0].sdev)) {
vmklnx_scsi_device_hot_removed(ap->link.device[0].sdev);
ata_ehi_push_desc(host_ehi, "hotplug handled");
}
#endif

View file

@ -91,7 +91,7 @@
#include "bnx2_fw2.h"
#define DRV_MODULE_NAME "bnx2"
#define DRV_MODULE_VERSION "2.2.3h.v55.2"
#define DRV_MODULE_VERSION "2.2.3d.v55.2"
#define DRV_MODULE_RELDATE "Feb 12, 2013"
#define RUN_AT(x) (jiffies + (x))

View file

@ -15,7 +15,7 @@
#ifndef CNIC_REGISTER_H
#define CNIC_REGISTER_H
#define CNIC_REGISTER_MODULE_VERSION "1.72.2.v55.1"
#define CNIC_REGISTER_MODULE_VERSION "1.72.1.v50.1i"
#define CNIC_REGISTER_MODULE_RELDATE "February 06, 2013"
extern int cnic_register_adapter(const char * name, void *callback);
extern void *cnic_register_get_callback(const char * name);

View file

@ -15,7 +15,7 @@
#ifndef CNIC_REGISTER_H
#define CNIC_REGISTER_H
#define CNIC_REGISTER_MODULE_VERSION "1.72.2.v55.1"
#define CNIC_REGISTER_MODULE_VERSION "1.72.1.v50.1i"
#define CNIC_REGISTER_MODULE_RELDATE "February 06, 2013"
extern int cnic_register_adapter(const char * name, void *callback);
extern void *cnic_register_get_callback(const char * name);

View file

@ -997,6 +997,14 @@ static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw)
reg |= (1 << 28);
ew32(TARC(1), reg);
/*
* Disable IPv6 extension header parsing because some malformed
* IPv6 headers can hang the Rx.
*/
reg = er32(RFCTL);
reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
ew32(RFCTL, reg);
return;
}

View file

@ -1184,6 +1184,16 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
ew32(CTRL_EXT, reg);
}
/*
* Disable IPv6 extension header parsing because some malformed
* IPv6 headers can hang the Rx.
*/
if (hw->mac.type <= e1000_82573) {
reg = er32(RFCTL);
reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
ew32(RFCTL, reg);
}
/* PCI-Ex Control Registers */
switch (hw->mac.type) {

View file

@ -2785,6 +2785,21 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
ew32(STATUS, reg);
}
/*
* work-around descriptor data corruption issue during nfs v2 udp
* traffic,just disable the nfs filtering capability
*/
reg = er32(RFCTL);
reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
/*
* Disable IPv6 extension header parsing because some
* malformed IPv6 headers can hang the Rx.
*/
if (hw->mac.type == e1000_ich8lan)
reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
ew32(RFCTL, reg);
return;
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -45,29 +45,29 @@
#define E1000_RAR_ENTRIES_82575 16
#define E1000_RAR_ENTRIES_82576 24
#define E1000_RAR_ENTRIES_82580 24
#define E1000_RAR_ENTRIES_I350 32
#define E1000_SW_SYNCH_MB 0x00000100
#define E1000_STAT_DEV_RST_SET 0x00100000
#define E1000_CTRL_DEV_RST 0x20000000
#define E1000_RAR_ENTRIES_I350 32
struct e1000_adv_data_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
union {
u32 data;
struct {
u32 datalen :16; /* Data buffer length */
u32 rsvd :4;
u32 dtyp :4; /* Descriptor type */
u32 dcmd :8; /* Descriptor command */
u32 datalen:16; /* Data buffer length */
u32 rsvd:4;
u32 dtyp:4; /* Descriptor type */
u32 dcmd:8; /* Descriptor command */
} config;
} lower;
union {
u32 data;
struct {
u32 status :4; /* Descriptor status */
u32 idx :4;
u32 popts :6; /* Packet Options */
u32 paylen :18; /* Payload length */
u32 status:4; /* Descriptor status */
u32 idx:4;
u32 popts:6; /* Packet Options */
u32 paylen:18; /* Payload length */
} options;
} upper;
};
@ -92,23 +92,23 @@ struct e1000_adv_context_desc {
union {
u32 ip_config;
struct {
u32 iplen :9;
u32 maclen :7;
u32 vlan_tag :16;
u32 iplen:9;
u32 maclen:7;
u32 vlan_tag:16;
} fields;
} ip_setup;
u32 seq_num;
union {
u64 l4_config;
struct {
u32 mkrloc :9;
u32 tucmd :11;
u32 dtyp :4;
u32 adv :8;
u32 rsvd :4;
u32 idx :4;
u32 l4len :8;
u32 mss :16;
u32 mkrloc:9;
u32 tucmd:11;
u32 dtyp:4;
u32 adv:8;
u32 rsvd:4;
u32 idx:4;
u32 l4len:8;
u32 mss:16;
} fields;
} l4_setup;
};
@ -142,7 +142,8 @@ struct e1000_adv_context_desc {
#define E1000_MRQC_ENABLE_RSS_8Q 0x00000002
#define E1000_VMRCTL_MIRROR_PORT_SHIFT 8
#define E1000_VMRCTL_MIRROR_DSTPORT_MASK (7 << E1000_VMRCTL_MIRROR_PORT_SHIFT)
#define E1000_VMRCTL_MIRROR_DSTPORT_MASK (7 << \
E1000_VMRCTL_MIRROR_PORT_SHIFT)
#define E1000_VMRCTL_POOL_MIRROR_ENABLE (1 << 0)
#define E1000_VMRCTL_UPLINK_MIRROR_ENABLE (1 << 1)
#define E1000_VMRCTL_DOWNLINK_MIRROR_ENABLE (1 << 2)
@ -192,8 +193,8 @@ union e1000_adv_rx_desc {
__le32 data;
struct {
__le16 pkt_info; /*RSS type, Pkt type*/
__le16 hdr_info; /* Split Header,
* header buffer len*/
/* Split Header, header buffer len */
__le16 hdr_info;
} hs_rss;
} lo_dword;
union {
@ -290,14 +291,15 @@ union e1000_adv_tx_desc {
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on packet */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */
#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on pkt */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp pkt */
#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED prsnt in WB */
#define E1000_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
#define E1000_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/
/* 1st & Last TSO-full iSCSI PDU*/
#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800
#define E1000_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
@ -319,7 +321,8 @@ struct e1000_adv_tx_context_desc {
#define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000
#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000 /* Req requires Markers and CRC */
/* Req requires Markers and CRC */
#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
/* Adv ctxt IPSec SA IDX mask */
@ -328,14 +331,14 @@ struct e1000_adv_tx_context_desc {
#define E1000_ADVTXD_IPSEC_ESP_LEN_MASK 0x000000FF
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. wbk flushing */
/* Tx Queue Arbitration Priority 0=low, 1=high */
#define E1000_TXDCTL_PRIORITY 0x08000000
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
#define E1000_RXDCTL_SWFLSH 0x04000000 /* Rx Desc. write-back flushing */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
#define E1000_RXDCTL_SWFLSH 0x04000000 /* Rx Desc. wbk flushing */
/* Direct Cache Access (DCA) definitions */
#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
@ -346,12 +349,15 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header ena */
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload ena */
#define E1000_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx Desc Relax Order */
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
#define E1000_DCA_TXCTRL_DESC_RRO_EN (1 << 9) /* Tx rd Desc Relax Order */
#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
#define E1000_DCA_TXCTRL_DATA_RRO_EN (1 << 13) /* Tx rd data Relax Order */
#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
@ -387,10 +393,10 @@ struct e1000_adv_tx_context_desc {
#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000
#define E1000_NVM_APME_82575 0x0400
#define MAX_NUM_VFS 8
#define MAX_NUM_VFS 7
#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof cntrl */
#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof cntrl */
#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
#define E1000_DTXSWC_LLE_SHIFT 16
@ -417,6 +423,15 @@ struct e1000_adv_tx_context_desc {
#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
#define E1000_VMOLR_VPE 0x00800000 /* VLAN promiscuous enable */
#define E1000_VMOLR_UPE 0x20000000 /* Unicast promisuous enable */
#define E1000_DVMOLR_HIDVLAN 0x20000000 /* Vlan hiding enable */
#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */
#define E1000_PBRWAC_WALPB 0x00000007 /* Wrap around event on LAN Rx PB */
#define E1000_PBRWAC_PBE 0x00000008 /* Rx packet buffer empty */
#define E1000_VLVF_ARRAY_SIZE 32
#define E1000_VLVF_VLANID_MASK 0x00000FFF
#define E1000_VLVF_POOLSEL_SHIFT 12
@ -435,17 +450,60 @@ struct e1000_adv_tx_context_desc {
#define E1000_RPLOLR_STRVLAN 0x40000000
#define E1000_RPLOLR_STRCRC 0x80000000
#define E1000_TCTL_EXT_COLD 0x000FFC00
#define E1000_TCTL_EXT_COLD_SHIFT 10
#define E1000_DTXCTL_8023LL 0x0004
#define E1000_DTXCTL_VLAN_ADDED 0x0008
#define E1000_DTXCTL_OOS_ENABLE 0x0010
#define E1000_DTXCTL_MDP_EN 0x0020
#define E1000_DTXCTL_SPOOF_INT 0x0040
#define E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT (1 << 14)
#define ALL_QUEUES 0xFFFF
/* RX packet buffer size defines */
/* Rx packet buffer size defines */
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf);
void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
u16 e1000_rxpbs_adjust_82580(u32 data);
s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data);
s32 e1000_set_eee_i350(struct e1000_hw *);
s32 e1000_set_eee_i354(struct e1000_hw *);
s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *);
#define E1000_I2C_THERMAL_SENSOR_ADDR 0xF8
#define E1000_EMC_INTERNAL_DATA 0x00
#define E1000_EMC_INTERNAL_THERM_LIMIT 0x20
#define E1000_EMC_DIODE1_DATA 0x01
#define E1000_EMC_DIODE1_THERM_LIMIT 0x19
#define E1000_EMC_DIODE2_DATA 0x23
#define E1000_EMC_DIODE2_THERM_LIMIT 0x1A
#define E1000_EMC_DIODE3_DATA 0x2A
#define E1000_EMC_DIODE3_THERM_LIMIT 0x30
s32 e1000_get_thermal_sensor_data_generic(struct e1000_hw *hw);
s32 e1000_init_thermal_sensor_thresh_generic(struct e1000_hw *hw);
/* I2C SDA and SCL timing parameters for standard mode */
#define E1000_I2C_T_HD_STA 4
#define E1000_I2C_T_LOW 5
#define E1000_I2C_T_HIGH 4
#define E1000_I2C_T_SU_STA 5
#define E1000_I2C_T_HD_DATA 5
#define E1000_I2C_T_SU_DATA 1
#define E1000_I2C_T_RISE 1
#define E1000_I2C_T_FALL 1
#define E1000_I2C_T_SU_STO 4
#define E1000_I2C_T_BUF 5
s32 e1000_set_i2c_bb(struct e1000_hw *hw);
s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data);
s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data);
void e1000_i2c_bus_clear(struct e1000_hw *hw);
#endif /* _E1000_82575_H_ */

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -168,14 +168,39 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82580_SERDES:
case E1000_DEV_ID_82580_SGMII:
case E1000_DEV_ID_82580_COPPER_DUAL:
case E1000_DEV_ID_82580_QUAD_FIBER:
case E1000_DEV_ID_DH89XXCC_SGMII:
case E1000_DEV_ID_DH89XXCC_SERDES:
case E1000_DEV_ID_DH89XXCC_BACKPLANE:
case E1000_DEV_ID_DH89XXCC_SFP:
mac->type = e1000_82580;
break;
case E1000_DEV_ID_I350_COPPER:
case E1000_DEV_ID_I350_FIBER:
case E1000_DEV_ID_I350_SERDES:
case E1000_DEV_ID_I350_SGMII:
case E1000_DEV_ID_I350_DA4:
mac->type = e1000_i350;
break;
case E1000_DEV_ID_I210_COPPER_FLASHLESS:
case E1000_DEV_ID_I210_SERDES_FLASHLESS:
case E1000_DEV_ID_I210_COPPER:
case E1000_DEV_ID_I210_COPPER_OEM1:
case E1000_DEV_ID_I210_COPPER_IT:
case E1000_DEV_ID_I210_FIBER:
case E1000_DEV_ID_I210_SERDES:
case E1000_DEV_ID_I210_SGMII:
mac->type = e1000_i210;
break;
case E1000_DEV_ID_I211_COPPER:
mac->type = e1000_i211;
break;
case E1000_DEV_ID_I354_BACKPLANE_1GBPS:
case E1000_DEV_ID_I354_SGMII:
case E1000_DEV_ID_I354_BACKPLANE_2_5GBPS:
mac->type = e1000_i354;
break;
default:
/* Should never have loaded on this device */
ret_val = -E1000_ERR_MAC_INIT;
@ -232,8 +257,13 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_82576:
case e1000_82580:
case e1000_i350:
case e1000_i354:
e1000_init_function_pointers_82575(hw);
break;
case e1000_i210:
case e1000_i211:
e1000_init_function_pointers_i210(hw);
break;
default:
DEBUGOUT("Hardware not supported\n");
ret_val = -E1000_ERR_CONFIG;
@ -618,20 +648,6 @@ s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
return E1000_SUCCESS;
}
/**
* e1000_mta_set - Sets multicast table bit
* @hw: pointer to the HW structure
* @hash_value: Multicast hash value.
*
* This sets the bit in the multicast table corresponding to the
* hash value. This is a function pointer entry point called by drivers.
**/
void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
{
if (hw->mac.ops.mta_set)
hw->mac.ops.mta_set(hw, hash_value);
}
/**
* e1000_hash_mc_addr - Determines address location in multicast table
* @hw: pointer to the HW structure
@ -672,14 +688,10 @@ bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
* It also does alignment considerations to do the writes in most efficient
* way. Also fills up the sum of the buffer in *buffer parameter.
**/
s32 e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length,
s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
u16 offset, u8 *sum)
{
if (hw->mac.ops.mng_host_if_write)
return hw->mac.ops.mng_host_if_write(hw, buffer, length,
offset, sum);
return E1000_NOT_IMPLEMENTED;
return e1000_mng_host_if_write_generic(hw, buffer, length, offset, sum);
}
/**
@ -692,10 +704,7 @@ s32 e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length,
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr)
{
if (hw->mac.ops.mng_write_cmd_header)
return hw->mac.ops.mng_write_cmd_header(hw, hdr);
return E1000_NOT_IMPLEMENTED;
return e1000_mng_write_cmd_header_generic(hw, hdr);
}
/**
@ -708,27 +717,9 @@ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
s32 e1000_mng_enable_host_if(struct e1000_hw * hw)
s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
{
if (hw->mac.ops.mng_enable_host_if)
return hw->mac.ops.mng_enable_host_if(hw);
return E1000_NOT_IMPLEMENTED;
}
/**
* e1000_wait_autoneg - Waits for autonegotiation completion
* @hw: pointer to the HW structure
*
* Waits for autoneg to complete. Currently no func pointer exists and all
* implementations are handled in the generic version of this function.
**/
s32 e1000_wait_autoneg(struct e1000_hw *hw)
{
if (hw->mac.ops.wait_autoneg)
return hw->mac.ops.wait_autoneg(hw);
return E1000_SUCCESS;
return e1000_mng_enable_host_if_generic(hw);
}
/**
@ -961,18 +952,34 @@ s32 e1000_read_mac_addr(struct e1000_hw *hw)
}
/**
* e1000_read_pba_num - Read device part number
* e1000_read_pba_string - Read device part number string
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
* @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in pba_num.
* Currently no func pointer exists and all implementations are handled in the
* generic version of this function.
**/
s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *pba_num)
s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size)
{
return e1000_read_pba_num_generic(hw, pba_num);
return e1000_read_pba_string_generic(hw, pba_num, pba_num_size);
}
/**
* e1000_read_pba_length - Read device part number string length
* @hw: pointer to the HW structure
* @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number length from the EEPROM and
* stores the value in pba_num.
* Currently no func pointer exists and all implementations are handled in the
* generic version of this function.
**/
s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size)
{
return e1000_read_pba_length_generic(hw, pba_num_size);
}
/**
@ -1098,6 +1105,18 @@ void e1000_power_down_phy(struct e1000_hw *hw)
hw->phy.ops.power_down(hw);
}
/**
* e1000_power_up_fiber_serdes_link - Power up serdes link
* @hw: pointer to the HW structure
*
* Power on the optics and PCS.
**/
void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw)
{
if (hw->mac.ops.power_up_serdes)
hw->mac.ops.power_up_serdes(hw);
}
/**
* e1000_shutdown_fiber_serdes_link - Remove link during power down
* @hw: pointer to the HW structure
@ -1110,3 +1129,31 @@ void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw)
hw->mac.ops.shutdown_serdes(hw);
}
/**
* e1000_get_thermal_sensor_data - Gathers thermal sensor data
* @hw: pointer to hardware structure
*
* Updates the temperatures in mac.thermal_sensor_data
**/
s32 e1000_get_thermal_sensor_data(struct e1000_hw *hw)
{
if (hw->mac.ops.get_thermal_sensor_data)
return hw->mac.ops.get_thermal_sensor_data(hw);
return E1000_SUCCESS;
}
/**
* e1000_init_thermal_sensor_thresh - Sets thermal sensor thresholds
* @hw: pointer to hardware structure
*
* Sets the thermal sensor thresholds according to the NVM map
**/
s32 e1000_init_thermal_sensor_thresh(struct e1000_hw *hw)
{
if (hw->mac.ops.init_thermal_sensor_thresh)
return hw->mac.ops.init_thermal_sensor_thresh(hw);
return E1000_SUCCESS;
}

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -33,8 +33,11 @@
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
extern void e1000_rx_fifo_flush_82575(struct e1000_hw *hw);
extern void e1000_init_function_pointers_vf(struct e1000_hw *hw);
extern void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw);
extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw);
extern void e1000_init_function_pointers_i210(struct e1000_hw *hw);
s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr);
s32 e1000_set_mac_type(struct e1000_hw *hw);
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
s32 e1000_init_mac_params(struct e1000_hw *hw);
@ -49,15 +52,13 @@ s32 e1000_check_for_link(struct e1000_hw *hw);
s32 e1000_reset_hw(struct e1000_hw *hw);
s32 e1000_init_hw(struct e1000_hw *hw);
s32 e1000_setup_link(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
s32 e1000_disable_pcie_master(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
void e1000_mta_set(struct e1000_hw *hw, u32 hash_value);
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
void e1000_update_mc_addr_list(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count);
void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count);
s32 e1000_setup_led(struct e1000_hw *hw);
s32 e1000_cleanup_led(struct e1000_hw *hw);
s32 e1000_check_reset_block(struct e1000_hw *hw);
@ -71,8 +72,8 @@ s32 e1000_get_cable_length(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting(struct e1000_hw *hw);
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset,
u8 data);
s32 e1000_get_phy_info(struct e1000_hw *hw);
void e1000_release_phy(struct e1000_hw *hw);
s32 e1000_acquire_phy(struct e1000_hw *hw);
@ -81,27 +82,29 @@ s32 e1000_phy_commit(struct e1000_hw *hw);
void e1000_power_up_phy(struct e1000_hw *hw);
void e1000_power_down_phy(struct e1000_hw *hw);
s32 e1000_read_mac_addr(struct e1000_hw *hw);
s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *part_num);
s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size);
s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size);
void e1000_reload_nvm(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum(struct e1000_hw *hw);
s32 e1000_validate_nvm_checksum(struct e1000_hw *hw);
s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_wait_autoneg(struct e1000_hw *hw);
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
bool e1000_check_mng_mode(struct e1000_hw *hw);
bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
s32 e1000_mng_host_if_write(struct e1000_hw *hw,
u8 *buffer, u16 length, u16 offset, u8 *sum);
s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
u16 offset, u8 *sum);
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw,
u8 *buffer, u16 length);
s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
s32 e1000_get_thermal_sensor_data(struct e1000_hw *hw);
s32 e1000_init_thermal_sensor_thresh(struct e1000_hw *hw);
/*
* TBI_ACCEPT macro definition:
@ -134,7 +137,8 @@ s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw,
/* The carrier extension symbol, as received by the NIC. */
#define CARRIER_EXTENSION 0x0F
#define TBI_ACCEPT(a, status, errors, length, last_byte, min_frame_size, max_frame_size) \
#define TBI_ACCEPT(a, status, errors, length, last_byte, \
min_frame_size, max_frame_size) \
(e1000_tbi_sbp_enabled_82543(a) && \
(((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
((last_byte) == CARRIER_EXTENSION) && \
@ -144,4 +148,10 @@ s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw,
(((length) > min_frame_size) && \
((length) <= (max_frame_size + VLAN_TAG_SIZE + 1)))))
#ifndef E1000_MAX
#define E1000_MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef E1000_DIVIDE_ROUND_UP
#define E1000_DIVIDE_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) /* ceil(a/b) */
#endif
#endif /* _E1000_API_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -50,10 +50,29 @@ struct e1000_hw;
#define E1000_DEV_ID_82580_SERDES 0x1510
#define E1000_DEV_ID_82580_SGMII 0x1511
#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527
#define E1000_DEV_ID_I350_COPPER 0x1521
#define E1000_DEV_ID_I350_FIBER 0x1522
#define E1000_DEV_ID_I350_SERDES 0x1523
#define E1000_DEV_ID_I350_SGMII 0x1524
#define E1000_DEV_ID_I350_DA4 0x1546
#define E1000_DEV_ID_I210_COPPER 0x1533
#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534
#define E1000_DEV_ID_I210_COPPER_IT 0x1535
#define E1000_DEV_ID_I210_FIBER 0x1536
#define E1000_DEV_ID_I210_SERDES 0x1537
#define E1000_DEV_ID_I210_SGMII 0x1538
#define E1000_DEV_ID_I210_COPPER_FLASHLESS 0x157B
#define E1000_DEV_ID_I210_SERDES_FLASHLESS 0x157C
#define E1000_DEV_ID_I211_COPPER 0x1539
#define E1000_DEV_ID_I354_BACKPLANE_1GBPS 0x1F40
#define E1000_DEV_ID_I354_SGMII 0x1F41
#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS 0x1F45
#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438
#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
#define E1000_DEV_ID_DH89XXCC_SFP 0x0440
#define E1000_REVISION_0 0
#define E1000_REVISION_1 1
#define E1000_REVISION_2 2
@ -76,6 +95,9 @@ enum e1000_mac_type {
e1000_82576,
e1000_82580,
e1000_i350,
e1000_i354,
e1000_i210,
e1000_i211,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
};
@ -92,6 +114,7 @@ enum e1000_nvm_type {
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_flash_hw,
e1000_nvm_invm,
e1000_nvm_flash_sw
};
@ -112,6 +135,7 @@ enum e1000_phy_type {
e1000_phy_ife,
e1000_phy_82580,
e1000_phy_vf,
e1000_phy_i210,
};
enum e1000_bus_type {
@ -185,6 +209,15 @@ enum e1000_serdes_link_state {
e1000_serdes_link_forced_up
};
#ifndef __le16
#define __le16 u16
#endif
#ifndef __le32
#define __le32 u32
#endif
#ifndef __le64
#define __le64 u64
#endif
/* Receive Descriptor */
struct e1000_rx_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
@ -221,6 +254,10 @@ union e1000_rx_desc_extended {
};
#define MAX_PS_BUFFERS 4
/* Number of packet split data buffers (not including the header buffer) */
#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
struct {
@ -245,7 +282,8 @@ union e1000_rx_desc_packet_split {
} middle;
struct {
__le16 header_status;
__le16 length[3]; /* length of buffers 1-3 */
/* length of buffers 1-3 */
__le16 length[PS_PAGE_BUFFERS];
} upper;
__le64 reserved;
} wb; /* writeback */
@ -400,6 +438,10 @@ struct e1000_hw_stats {
u64 scvpc;
u64 hrmpc;
u64 doosync;
u64 o2bgptc;
u64 o2bspc;
u64 b2ospc;
u64 b2ogprc;
};
@ -454,13 +496,13 @@ struct e1000_host_mng_command_info {
#include "e1000_manage.h"
#include "e1000_mbx.h"
/* Function pointers for the MAC. */
struct e1000_mac_operations {
/* Function pointers for the MAC. */
s32 (*init_params)(struct e1000_hw *);
s32 (*id_led_init)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *hw);
s32 (*cleanup_led)(struct e1000_hw *);
void (*clear_hw_cntrs)(struct e1000_hw *);
void (*clear_vfta)(struct e1000_hw *);
@ -473,22 +515,35 @@ struct e1000_mac_operations {
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
void (*shutdown_serdes)(struct e1000_hw *);
void (*power_up_serdes)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
s32 (*setup_led)(struct e1000_hw *);
void (*write_vfta)(struct e1000_hw *, u32, u32);
void (*mta_set)(struct e1000_hw *, u32);
void (*config_collision_dist)(struct e1000_hw *);
void (*rar_set)(struct e1000_hw *, u8*, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
s32 (*validate_mdi_setting)(struct e1000_hw *);
s32 (*mng_host_if_write)(struct e1000_hw *, u8*, u16, u16, u8*);
s32 (*mng_write_cmd_header)(struct e1000_hw *hw,
struct e1000_host_mng_command_header*);
s32 (*mng_enable_host_if)(struct e1000_hw *);
s32 (*wait_autoneg)(struct e1000_hw *);
s32 (*get_thermal_sensor_data)(struct e1000_hw *);
s32 (*init_thermal_sensor_thresh)(struct e1000_hw *);
s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
void (*release_swfw_sync)(struct e1000_hw *, u16);
};
/* When to use various PHY register access functions:
*
* Func Caller
* Function Does Does When to use
* ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* X_reg L,P,A n/a for simple PHY reg accesses
* X_reg_locked P,A L for multiple accesses of different regs
* on different pages
* X_reg_page A L,P for multiple accesses of different regs
* on the same page
*
* Where X=[read|write], L=locking, P=sets page, A=register access
*
*/
struct e1000_phy_operations {
s32 (*init_params)(struct e1000_hw *);
s32 (*acquire)(struct e1000_hw *);
@ -499,18 +554,24 @@ struct e1000_phy_operations {
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_info)(struct e1000_hw *);
s32 (*set_page)(struct e1000_hw *, u16);
s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_page)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_reg)(struct e1000_hw *, u32, u16);
s32 (*write_reg_locked)(struct e1000_hw *, u32, u16);
s32 (*write_reg_page)(struct e1000_hw *, u32, u16);
void (*power_up)(struct e1000_hw *);
void (*power_down)(struct e1000_hw *);
s32 (*read_i2c_byte)(struct e1000_hw *, u8, u8, u8 *);
s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
};
/* Function pointers for the NVM. */
struct e1000_nvm_operations {
s32 (*init_params)(struct e1000_hw *);
s32 (*acquire)(struct e1000_hw *);
@ -523,10 +584,23 @@ struct e1000_nvm_operations {
s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
};
#define E1000_MAX_SENSORS 3
struct e1000_thermal_diode_data {
u8 location;
u8 temp;
u8 caution_thresh;
u8 max_op_thresh;
};
struct e1000_thermal_sensor_data {
struct e1000_thermal_diode_data sensor[E1000_MAX_SENSORS];
};
struct e1000_mac_info {
struct e1000_mac_operations ops;
u8 addr[6];
u8 perm_addr[6];
u8 addr[ETH_ADDR_LEN];
u8 perm_addr[ETH_ADDR_LEN];
enum e1000_mac_type type;
@ -554,6 +628,7 @@ struct e1000_mac_info {
u8 forced_speed_duplex;
bool adaptive_ifs;
bool has_fwsm;
bool arc_subsystem_valid;
bool asf_firmware_present;
bool autoneg;
@ -563,6 +638,7 @@ struct e1000_mac_info {
enum e1000_serdes_link_state serdes_link_state;
bool serdes_has_link;
bool tx_pkt_filtering;
struct e1000_thermal_sensor_data thermal_sensor_data;
};
struct e1000_phy_info {
@ -627,6 +703,7 @@ struct e1000_fc_info {
u32 high_water; /* Flow control high-water mark */
u32 low_water; /* Flow control low-water mark */
u16 pause_time; /* Flow control pause timer */
u16 refresh_time; /* Flow control refresh timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
enum e1000_fc_mode current_mode; /* FC mode in effect */
@ -664,6 +741,13 @@ struct e1000_mbx_info {
struct e1000_dev_spec_82575 {
bool sgmii_active;
bool global_device_reset;
bool eee_disable;
bool module_plugged;
bool clear_semaphore_once;
u32 mtu;
struct sfp_e1000_flags eth_flags;
u8 media_port;
bool media_changed;
};
struct e1000_dev_spec_vf {
@ -671,7 +755,6 @@ struct e1000_dev_spec_vf {
u32 v2p_mailbox;
};
struct e1000_hw {
void *back;
@ -701,6 +784,7 @@ struct e1000_hw {
};
#include "e1000_82575.h"
#include "e1000_i210.h"
/* These functions must be implemented by drivers */
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);

View file

@ -0,0 +1,909 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include "e1000_api.h"
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
static void e1000_release_nvm_i210(struct e1000_hw *hw);
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw);
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
/**
* e1000_acquire_nvm_i210 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
* Acquire the necessary semaphores for exclusive access to the EEPROM.
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw)
{
s32 ret_val;
DEBUGFUNC("e1000_acquire_nvm_i210");
ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
return ret_val;
}
/**
* e1000_release_nvm_i210 - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit,
* then release the semaphores acquired.
**/
static void e1000_release_nvm_i210(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_release_nvm_i210");
e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}
/**
* e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Acquire the SW/FW semaphore to access the PHY or NVM. The mask
* will also specify which port we're acquiring the lock for.
**/
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
u32 swmask = mask;
u32 fwmask = mask << 16;
s32 ret_val = E1000_SUCCESS;
s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
DEBUGFUNC("e1000_acquire_swfw_sync_i210");
while (i < timeout) {
if (e1000_get_hw_semaphore_i210(hw)) {
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
if (!(swfw_sync & (fwmask | swmask)))
break;
/*
* Firmware currently using resource (fwmask)
* or other software thread using resource (swmask)
*/
e1000_put_hw_semaphore_generic(hw);
msec_delay_irq(5);
i++;
}
if (i == timeout) {
DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync |= swmask;
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
e1000_put_hw_semaphore_generic(hw);
out:
return ret_val;
}
/**
* e1000_release_swfw_sync_i210 - Release SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Release the SW/FW semaphore used to access the PHY or NVM. The mask
* will also specify which port we're releasing the lock for.
**/
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
DEBUGFUNC("e1000_release_swfw_sync_i210");
while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
; /* Empty */
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
swfw_sync &= ~mask;
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
e1000_put_hw_semaphore_generic(hw);
}
/**
* e1000_get_hw_semaphore_i210 - Acquire hardware semaphore
* @hw: pointer to the HW structure
*
* Acquire the HW semaphore to access the PHY or NVM
**/
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
{
u32 swsm;
s32 timeout = hw->nvm.word_size + 1;
s32 i = 0;
DEBUGFUNC("e1000_get_hw_semaphore_i210");
/* Get the SW semaphore */
while (i < timeout) {
swsm = E1000_READ_REG(hw, E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
usec_delay(50);
i++;
}
if (i == timeout) {
/* In rare circumstances, the SW semaphore may already be held
* unintentionally. Clear the semaphore once before giving up.
*/
if (hw->dev_spec._82575.clear_semaphore_once) {
hw->dev_spec._82575.clear_semaphore_once = false;
e1000_put_hw_semaphore_generic(hw);
for (i = 0; i < timeout; i++) {
swsm = E1000_READ_REG(hw, E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
usec_delay(50);
}
}
/* If we do not have the semaphore here, we have to give up. */
if (i == timeout) {
DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
return -E1000_ERR_NVM;
}
}
/* Get the FW semaphore. */
for (i = 0; i < timeout; i++) {
swsm = E1000_READ_REG(hw, E1000_SWSM);
E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
/* Semaphore acquired if bit latched */
if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
break;
usec_delay(50);
}
if (i == timeout) {
/* Release semaphores */
e1000_put_hw_semaphore_generic(hw);
DEBUGOUT("Driver can't access the NVM\n");
return -E1000_ERR_NVM;
}
return E1000_SUCCESS;
}
/**
* e1000_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the Shadow Ram to read
* @words: number of words to read
* @data: word read from the Shadow Ram
*
* Reads a 16 bit word from the Shadow Ram using the EERD register.
* Uses necessary synchronization semaphores.
**/
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = E1000_SUCCESS;
u16 i, count;
DEBUGFUNC("e1000_read_nvm_srrd_i210");
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to read in bursts than synchronizing access for each word. */
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
status = e1000_read_nvm_eerd(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status != E1000_SUCCESS)
break;
}
return status;
}
/**
* e1000_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow RAM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow RAM
*
* Writes data to Shadow RAM at offset using EEWR register.
*
* If e1000_update_nvm_checksum is not called after this function , the
* data will not be committed to FLASH and also Shadow RAM will most likely
* contain an invalid checksum.
*
* If error code is returned, data and Shadow RAM may be inconsistent - buffer
* partially written.
**/
s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = E1000_SUCCESS;
u16 i, count;
DEBUGFUNC("e1000_write_nvm_srwr_i210");
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to write in bursts than synchronizing access for each word. */
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
status = e1000_write_nvm_srwr(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status != E1000_SUCCESS)
break;
}
return status;
}
/**
* e1000_write_nvm_srwr - Write to Shadow Ram using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow Ram to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow Ram
*
* Writes data to Shadow Ram at offset using EEWR register.
*
* If e1000_update_nvm_checksum is not called after this function , the
* Shadow Ram will most likely contain an invalid checksum.
**/
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, k, eewr = 0;
u32 attempts = 100000;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_write_nvm_srwr");
/*
* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
(data[i] << E1000_NVM_RW_REG_DATA) |
E1000_NVM_RW_REG_START;
E1000_WRITE_REG(hw, E1000_SRWR, eewr);
for (k = 0; k < attempts; k++) {
if (E1000_NVM_RW_REG_DONE &
E1000_READ_REG(hw, E1000_SRWR)) {
ret_val = E1000_SUCCESS;
break;
}
usec_delay(5);
}
if (ret_val != E1000_SUCCESS) {
DEBUGOUT("Shadow RAM write EEWR timed out\n");
break;
}
}
out:
return ret_val;
}
/** e1000_read_invm_word_i210 - Reads OTP
* @hw: pointer to the HW structure
* @address: the word address (aka eeprom offset) to read
* @data: pointer to the data read
*
* Reads 16-bit words from the OTP. Return error when the word is not
* stored in OTP.
**/
static s32 e1000_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
{
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
u32 invm_dword;
u16 i;
u8 record_type, word_address;
DEBUGFUNC("e1000_read_invm_word_i210");
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
/* Get record type */
record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
break;
if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
if (word_address == address) {
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
DEBUGOUT2("Read INVM Word 0x%02x = %x",
address, *data);
status = E1000_SUCCESS;
break;
}
}
}
if (status != E1000_SUCCESS)
DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address);
return status;
}
/** e1000_read_invm_i210 - Read invm wrapper function for I210/I211
* @hw: pointer to the HW structure
* @address: the word address (aka eeprom offset) to read
* @data: pointer to the data read
*
* Wrapper function to return data formerly found in the NVM.
**/
static s32 e1000_read_invm_i210(struct e1000_hw *hw, u16 offset,
u16 E1000_UNUSEDARG words, u16 *data)
{
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_invm_i210");
/* Only the MAC addr is required to be present in the iNVM */
switch (offset) {
case NVM_MAC_ADDR:
ret_val = e1000_read_invm_word_i210(hw, (u8)offset, &data[0]);
ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+1,
&data[1]);
ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+2,
&data[2]);
if (ret_val != E1000_SUCCESS)
DEBUGOUT("MAC Addr not found in iNVM\n");
break;
case NVM_INIT_CTRL_2:
ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = NVM_INIT_CTRL_2_DEFAULT_I211;
ret_val = E1000_SUCCESS;
}
break;
case NVM_INIT_CTRL_4:
ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = NVM_INIT_CTRL_4_DEFAULT_I211;
ret_val = E1000_SUCCESS;
}
break;
case NVM_LED_1_CFG:
ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = NVM_LED_1_CFG_DEFAULT_I211;
ret_val = E1000_SUCCESS;
}
break;
case NVM_LED_0_2_CFG:
ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = NVM_LED_0_2_CFG_DEFAULT_I211;
ret_val = E1000_SUCCESS;
}
break;
case NVM_ID_LED_SETTINGS:
ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = ID_LED_RESERVED_FFFF;
ret_val = E1000_SUCCESS;
}
break;
case NVM_SUB_DEV_ID:
*data = hw->subsystem_device_id;
break;
case NVM_SUB_VEN_ID:
*data = hw->subsystem_vendor_id;
break;
case NVM_DEV_ID:
*data = hw->device_id;
break;
case NVM_VEN_ID:
*data = hw->vendor_id;
break;
default:
DEBUGOUT1("NVM word 0x%02x is not mapped.\n", offset);
*data = NVM_RESERVED_WORD;
break;
}
return ret_val;
}
/**
* e1000_read_invm_version - Reads iNVM version and image type
* @hw: pointer to the HW structure
* @invm_ver: version structure for the version read
*
* Reads iNVM version and image type.
**/
s32 e1000_read_invm_version(struct e1000_hw *hw,
struct e1000_fw_version *invm_ver)
{
u32 *record = NULL;
u32 *next_record = NULL;
u32 i = 0;
u32 invm_dword = 0;
u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
E1000_INVM_RECORD_SIZE_IN_BYTES);
u32 buffer[E1000_INVM_SIZE];
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
u16 version = 0;
DEBUGFUNC("e1000_read_invm_version");
/* Read iNVM memory */
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
buffer[i] = invm_dword;
}
/* Read version number */
for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have first version location used */
if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
version = 0;
status = E1000_SUCCESS;
break;
}
/* Check if we have second version location used */
else if ((i == 1) &&
((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
status = E1000_SUCCESS;
break;
}
/*
* Check if we have odd version location
* used and it is the last one used
*/
else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
(i != 1))) {
version = (*next_record & E1000_INVM_VER_FIELD_TWO)
>> 13;
status = E1000_SUCCESS;
break;
}
/*
* Check if we have even version location
* used and it is the last one used
*/
else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
((*record & 0x3) == 0)) {
version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
status = E1000_SUCCESS;
break;
}
}
if (status == E1000_SUCCESS) {
invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
>> E1000_INVM_MAJOR_SHIFT;
invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
}
/* Read Image Type */
for (i = 1; i < invm_blocks; i++) {
record = &buffer[invm_blocks - i];
next_record = &buffer[invm_blocks - i + 1];
/* Check if we have image type in first location used */
if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
invm_ver->invm_img_type = 0;
status = E1000_SUCCESS;
break;
}
/* Check if we have image type in first location used */
else if ((((*record & 0x3) == 0) &&
((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
((((*record & 0x3) != 0) && (i != 1)))) {
invm_ver->invm_img_type =
(*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
status = E1000_SUCCESS;
break;
}
}
return status;
}
/**
* e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 status = E1000_SUCCESS;
s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
DEBUGFUNC("e1000_validate_nvm_checksum_i210");
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
/*
* Replace the read function with semaphore grabbing with
* the one that skips this for a while.
* We have semaphore taken already here.
*/
read_op_ptr = hw->nvm.ops.read;
hw->nvm.ops.read = e1000_read_nvm_eerd;
status = e1000_validate_nvm_checksum_generic(hw);
/* Revert original read operation. */
hw->nvm.ops.read = read_op_ptr;
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
return status;
}
/**
* e1000_update_nvm_checksum_i210 - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM. Next commit EEPROM data onto the Flash.
**/
s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 checksum = 0;
u16 i, nvm_data;
DEBUGFUNC("e1000_update_nvm_checksum_i210");
/*
* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
ret_val = e1000_read_nvm_eerd(hw, 0, 1, &nvm_data);
if (ret_val != E1000_SUCCESS) {
DEBUGOUT("EEPROM read failed\n");
goto out;
}
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
/*
* Do not use hw->nvm.ops.write, hw->nvm.ops.read
* because we do not want to take the synchronization
* semaphores twice here.
*/
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = e1000_read_nvm_eerd(hw, i, 1, &nvm_data);
if (ret_val) {
hw->nvm.ops.release(hw);
DEBUGOUT("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = e1000_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
&checksum);
if (ret_val != E1000_SUCCESS) {
hw->nvm.ops.release(hw);
DEBUGOUT("NVM Write Error while updating checksum.\n");
goto out;
}
hw->nvm.ops.release(hw);
ret_val = e1000_update_flash_i210(hw);
} else {
ret_val = E1000_ERR_SWFW_SYNC;
}
out:
return ret_val;
}
/**
* e1000_get_flash_presence_i210 - Check if flash device is detected.
* @hw: pointer to the HW structure
*
**/
bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
{
u32 eec = 0;
bool ret_val = false;
DEBUGFUNC("e1000_get_flash_presence_i210");
eec = E1000_READ_REG(hw, E1000_EECD);
if (eec & E1000_EECD_FLASH_DETECTED_I210)
ret_val = true;
return ret_val;
}
/**
* e1000_update_flash_i210 - Commit EEPROM to the flash
* @hw: pointer to the HW structure
*
**/
s32 e1000_update_flash_i210(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u32 flup;
DEBUGFUNC("e1000_update_flash_i210");
ret_val = e1000_pool_flash_update_done_i210(hw);
if (ret_val == -E1000_ERR_NVM) {
DEBUGOUT("Flash update time out\n");
goto out;
}
flup = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD_I210;
E1000_WRITE_REG(hw, E1000_EECD, flup);
ret_val = e1000_pool_flash_update_done_i210(hw);
if (ret_val == E1000_SUCCESS)
DEBUGOUT("Flash update complete\n");
else
DEBUGOUT("Flash update time out\n");
out:
return ret_val;
}
/**
* e1000_pool_flash_update_done_i210 - Pool FLUDONE status.
* @hw: pointer to the HW structure
*
**/
s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
{
s32 ret_val = -E1000_ERR_NVM;
u32 i, reg;
DEBUGFUNC("e1000_pool_flash_update_done_i210");
for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
reg = E1000_READ_REG(hw, E1000_EECD);
if (reg & E1000_EECD_FLUDONE_I210) {
ret_val = E1000_SUCCESS;
break;
}
usec_delay(5);
}
return ret_val;
}
/**
* e1000_init_nvm_params_i210 - Initialize i210 NVM function pointers
* @hw: pointer to the HW structure
*
* Initialize the i210/i211 NVM parameters and function pointers.
**/
static s32 e1000_init_nvm_params_i210(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
struct e1000_nvm_info *nvm = &hw->nvm;
DEBUGFUNC("e1000_init_nvm_params_i210");
ret_val = e1000_init_nvm_params_82575(hw);
nvm->ops.acquire = e1000_acquire_nvm_i210;
nvm->ops.release = e1000_release_nvm_i210;
nvm->ops.valid_led_default = e1000_valid_led_default_i210;
if (e1000_get_flash_presence_i210(hw)) {
hw->nvm.type = e1000_nvm_flash_hw;
nvm->ops.read = e1000_read_nvm_srrd_i210;
nvm->ops.write = e1000_write_nvm_srwr_i210;
nvm->ops.validate = e1000_validate_nvm_checksum_i210;
nvm->ops.update = e1000_update_nvm_checksum_i210;
} else {
hw->nvm.type = e1000_nvm_invm;
nvm->ops.read = e1000_read_invm_i210;
nvm->ops.write = NULL;
nvm->ops.validate = NULL;
nvm->ops.update = NULL;
}
return ret_val;
}
/**
* e1000_init_function_pointers_i210 - Init func ptrs.
* @hw: pointer to the HW structure
*
* Called to initialize all function pointers and parameters.
**/
void e1000_init_function_pointers_i210(struct e1000_hw *hw)
{
e1000_init_function_pointers_82575(hw);
hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
return;
}
/**
* e1000_valid_led_default_i210 - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
*
* Read the EEPROM for the current default LED configuration. If the
* LED configuration is not valid, set to a valid LED configuration.
**/
static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
{
s32 ret_val;
DEBUGFUNC("e1000_valid_led_default_i210");
ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
switch (hw->phy.media_type) {
case e1000_media_type_internal_serdes:
*data = ID_LED_DEFAULT_I210_SERDES;
break;
case e1000_media_type_copper:
default:
*data = ID_LED_DEFAULT_I210;
break;
}
}
out:
return ret_val;
}
/**
* __e1000_access_xmdio_reg - Read/write XMDIO register
* @hw: pointer to the HW structure
* @address: XMDIO address to program
* @dev_addr: device address to program
* @data: pointer to value to read/write from/to the XMDIO address
* @read: boolean flag to indicate read or write
**/
static s32 __e1000_access_xmdio_reg(struct e1000_hw *hw, u16 address,
u8 dev_addr, u16 *data, bool read)
{
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("__e1000_access_xmdio_reg");
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
if (ret_val)
return ret_val;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
if (ret_val)
return ret_val;
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
dev_addr);
if (ret_val)
return ret_val;
if (read)
ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
else
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
if (ret_val)
return ret_val;
/* Recalibrate the device back to 0 */
ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
if (ret_val)
return ret_val;
return ret_val;
}
/**
* e1000_read_xmdio_reg - Read XMDIO register
* @hw: pointer to the HW structure
* @addr: XMDIO address to program
* @dev_addr: device address to program
* @data: value to be read from the EMI address
**/
s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
{
DEBUGFUNC("e1000_read_xmdio_reg");
return __e1000_access_xmdio_reg(hw, addr, dev_addr, data, true);
}
/**
* e1000_write_xmdio_reg - Write XMDIO register
* @hw: pointer to the HW structure
* @addr: XMDIO address to program
* @dev_addr: device address to program
* @data: value to be written to the XMDIO address
**/
s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
{
DEBUGFUNC("e1000_read_xmdio_reg");
return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, false);
}

View file

@ -0,0 +1,91 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_I210_H_
#define _E1000_I210_H_
bool e1000_get_flash_presence_i210(struct e1000_hw *hw);
s32 e1000_update_flash_i210(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw);
s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw);
s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_invm_version(struct e1000_hw *hw,
struct e1000_fw_version *invm_ver);
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
u16 *data);
s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
u16 data);
#define E1000_STM_OPCODE 0xDB00
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
(u8)((invm_dword) & 0x7)
#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
(u8)(((invm_dword) & 0x0000FE00) >> 9)
#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
(u16)(((invm_dword) & 0xFFFF0000) >> 16)
enum E1000_INVM_STRUCTURE_TYPE {
E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00,
E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01,
E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02,
E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03,
E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04,
E1000_INVM_INVALIDATED_STRUCTURE = 0x0F,
};
#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
#define E1000_INVM_ULT_BYTES_SIZE 8
#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
#define E1000_INVM_VER_FIELD_ONE 0x1FF8
#define E1000_INVM_VER_FIELD_TWO 0x7FE000
#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
#define E1000_INVM_MAJOR_MASK 0x3F0
#define E1000_INVM_MINOR_MASK 0xF
#define E1000_INVM_MAJOR_SHIFT 4
#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_OFF2))
#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_ON2))
/* NVM offset defaults for I211 devices */
#define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243
#define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -28,10 +28,6 @@
#ifndef _E1000_MAC_H_
#define _E1000_MAC_H_
/*
* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
void e1000_init_mac_ops_generic(struct e1000_hw *hw);
s32 e1000_blink_led_generic(struct e1000_hw *hw);
s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw);
@ -58,6 +54,7 @@ s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_setup_led_generic(struct e1000_hw *hw);
s32 e1000_setup_link_generic(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw *hw);
s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
@ -65,12 +62,8 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr);
void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw);
void e1000_clear_vfta_generic(struct e1000_hw *hw);
void e1000_config_collision_dist_generic(struct e1000_hw *hw);
void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count);
void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value);
void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw);
void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
void e1000_reset_adaptive_generic(struct e1000_hw *hw);
void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -27,8 +27,6 @@
#include "e1000_api.h"
static u8 e1000_calculate_checksum(u8 *buffer, u32 length);
/**
* e1000_calculate_checksum - Calculate checksum for buffer
* @buffer: pointer to EEPROM
@ -37,7 +35,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length);
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
u8 e1000_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
@ -66,17 +64,20 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
{
u32 hicr;
s32 ret_val = E1000_SUCCESS;
u8 i;
DEBUGFUNC("e1000_mng_enable_host_if_generic");
if (!hw->mac.arc_subsystem_valid) {
DEBUGOUT("ARC subsystem not valid.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if ((hicr & E1000_HICR_EN) == 0) {
if (!(hicr & E1000_HICR_EN)) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* check the previous command is completed */
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
@ -88,12 +89,10 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
DEBUGOUT("Previous command timeout failed .\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
out:
return ret_val;
return E1000_SUCCESS;
}
/**
@ -105,18 +104,17 @@ out:
**/
bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
{
u32 fwsm;
u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
DEBUGFUNC("e1000_check_mng_mode_generic");
fwsm = E1000_READ_REG(hw, E1000_FWSM);
return (fwsm & E1000_FWSM_MODE_MASK) ==
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
}
/**
* e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on TX
* e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on Tx
* @hw: pointer to the HW structure
*
* Enables packet filtering on transmit packets if manageability is enabled
@ -129,102 +127,50 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
u32 offset;
s32 ret_val, hdr_csum, csum;
u8 i, len;
bool tx_filter = true;
DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
hw->mac.tx_pkt_filtering = true;
/* No manageability, no filtering */
if (!hw->mac.ops.check_mng_mode(hw)) {
tx_filter = false;
goto out;
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/*
* If we can't read from the host interface for whatever
/* If we can't read from the host interface for whatever
* reason, disable filtering.
*/
ret_val = hw->mac.ops.mng_enable_host_if(hw);
ret_val = e1000_mng_enable_host_if_generic(hw);
if (ret_val != E1000_SUCCESS) {
tx_filter = false;
goto out;
hw->mac.tx_pkt_filtering = false;
return hw->mac.tx_pkt_filtering;
}
/* Read in the header. Length and offset are in dwords. */
len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
for (i = 0; i < len; i++) {
*(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
E1000_HOST_IF,
for (i = 0; i < len; i++)
*(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
offset + i);
}
hdr_csum = hdr->checksum;
hdr->checksum = 0;
csum = e1000_calculate_checksum((u8 *)hdr,
E1000_MNG_DHCP_COOKIE_LENGTH);
/*
* If either the checksums or signature don't match, then
/* If either the checksums or signature don't match, then
* the cookie area isn't considered valid, in which case we
* take the safe route of assuming Tx filtering is enabled.
*/
if (hdr_csum != csum)
goto out;
if (hdr->signature != E1000_IAMT_SIGNATURE)
goto out;
if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
hw->mac.tx_pkt_filtering = true;
return hw->mac.tx_pkt_filtering;
}
/* Cookie area is valid, make the final check for filtering. */
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
tx_filter = false;
hw->mac.tx_pkt_filtering = false;
out:
hw->mac.tx_pkt_filtering = tx_filter;
return tx_filter;
}
/**
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val)
goto out;
/* Populate the host interface with the contents of "buffer". */
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
goto out;
/* Write the manageability command header */
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
if (ret_val)
goto out;
/* Tell the ARC a new command is pending. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
out:
return ret_val;
return hw->mac.tx_pkt_filtering;
}
/**
@ -274,17 +220,14 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
u8 *tmp;
u8 *bufptr = buffer;
u32 data = 0;
s32 ret_val = E1000_SUCCESS;
u16 remaining, i, j, prev_bytes;
DEBUGFUNC("e1000_mng_host_if_write_generic");
/* sum = only sum of the data and it is not checksum */
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
ret_val = -E1000_ERR_PARAM;
goto out;
}
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
return -E1000_ERR_PARAM;
tmp = (u8 *)&data;
prev_bytes = offset & 0x3;
@ -307,8 +250,7 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
/* Calculate length in DWORDs */
length >>= 2;
/*
* The device driver writes the relevant command block into the
/* The device driver writes the relevant command block into the
* ram area.
*/
for (i = 0; i < length; i++) {
@ -329,55 +271,286 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
data);
}
out:
return ret_val;
return E1000_SUCCESS;
}
/**
* e1000_enable_mng_pass_thru - Enable processing of ARP's
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = e1000_mng_enable_host_if_generic(hw);
if (ret_val)
return ret_val;
/* Populate the host interface with the contents of "buffer". */
ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
return ret_val;
/* Write the manageability command header */
ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
if (ret_val)
return ret_val;
/* Tell the ARC a new command is pending. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
return E1000_SUCCESS;
}
/**
* e1000_enable_mng_pass_thru - Check if management passthrough is needed
* @hw: pointer to the HW structure
*
* Verifies the hardware needs to allow ARPs to be processed by the host.
* Verifies the hardware needs to leave interface enabled so that frames can
* be directed to and from the management interface.
**/
bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
bool ret_val = false;
DEBUGFUNC("e1000_enable_mng_pass_thru");
if (!hw->mac.asf_firmware_present)
goto out;
return false;
manc = E1000_READ_REG(hw, E1000_MANC);
if (!(manc & E1000_MANC_RCV_TCO_EN) ||
!(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
goto out;
if (!(manc & E1000_MANC_RCV_TCO_EN))
return false;
if (hw->mac.arc_subsystem_valid) {
if (hw->mac.has_fwsm) {
fwsm = E1000_READ_REG(hw, E1000_FWSM);
factps = E1000_READ_REG(hw, E1000_FACTPS);
if (!(factps & E1000_FACTPS_MNGCG) &&
((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
ret_val = true;
goto out;
}
} else {
if ((manc & E1000_MANC_SMBUS_EN) &&
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
return true;
} else if ((manc & E1000_MANC_SMBUS_EN) &&
!(manc & E1000_MANC_ASF_EN)) {
ret_val = true;
goto out;
}
return true;
}
out:
return ret_val;
return false;
}
/**
* e1000_host_interface_command - Writes buffer to host interface
* @hw: pointer to the HW structure
* @buffer: contains a command to write
* @length: the byte length of the buffer, must be multiple of 4 bytes
*
* Writes a buffer to the Host Interface. Upon success, returns E1000_SUCCESS
* else returns E1000_ERR_HOST_INTERFACE_COMMAND.
**/
s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
{
u32 hicr, i;
DEBUGFUNC("e1000_host_interface_command");
if (!(hw->mac.arc_subsystem_valid)) {
DEBUGOUT("Hardware doesn't support host interface command.\n");
return E1000_SUCCESS;
}
if (!hw->mac.asf_firmware_present) {
DEBUGOUT("Firmware is not present.\n");
return E1000_SUCCESS;
}
if (length == 0 || length & 0x3 ||
length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
DEBUGOUT("Buffer length failure.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_EN)) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Calculate length in DWORDs */
length >>= 2;
/* The device driver writes the relevant command block
* into the ram area.
*/
for (i = 0; i < length; i++)
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
*((u32 *)buffer + i));
/* Setting this bit tells the ARC that a new command is pending. */
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_C))
break;
msec_delay(1);
}
/* Check command successful completion. */
if (i == E1000_HI_COMMAND_TIMEOUT ||
(!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
DEBUGOUT("Command has failed with no status valid.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
for (i = 0; i < length; i++)
*((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
E1000_HOST_IF,
i);
return E1000_SUCCESS;
}
/**
* e1000_load_firmware - Writes proxy FW code buffer to host interface
* and execute.
* @hw: pointer to the HW structure
* @buffer: contains a firmware to write
* @length: the byte length of the buffer, must be multiple of 4 bytes
*
* Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
* in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
**/
s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
{
u32 hicr, hibba, fwsm, icr, i;
DEBUGFUNC("e1000_load_firmware");
if (hw->mac.type < e1000_i210) {
DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
return -E1000_ERR_CONFIG;
}
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_EN)) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
return -E1000_ERR_CONFIG;
}
if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
return -E1000_ERR_CONFIG;
}
if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
DEBUGOUT("Buffer length failure.\n");
return -E1000_ERR_INVALID_ARGUMENT;
}
/* Clear notification from ROM-FW by reading ICR register */
icr = E1000_READ_REG(hw, E1000_ICR_V2);
/* Reset ROM-FW */
hicr = E1000_READ_REG(hw, E1000_HICR);
hicr |= E1000_HICR_FW_RESET_ENABLE;
E1000_WRITE_REG(hw, E1000_HICR, hicr);
hicr |= E1000_HICR_FW_RESET;
E1000_WRITE_REG(hw, E1000_HICR, hicr);
E1000_WRITE_FLUSH(hw);
/* Wait till MAC notifies about its readiness after ROM-FW reset */
for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
icr = E1000_READ_REG(hw, E1000_ICR_V2);
if (icr & E1000_ICR_MNG)
break;
msec_delay(1);
}
/* Check for timeout */
if (i == E1000_HI_COMMAND_TIMEOUT) {
DEBUGOUT("FW reset failed.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Wait till MAC is ready to accept new FW code */
for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
fwsm = E1000_READ_REG(hw, E1000_FWSM);
if ((fwsm & E1000_FWSM_FW_VALID) &&
((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
E1000_FWSM_HI_EN_ONLY_MODE))
break;
msec_delay(1);
}
/* Check for timeout */
if (i == E1000_HI_COMMAND_TIMEOUT) {
DEBUGOUT("FW reset failed.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Calculate length in DWORDs */
length >>= 2;
/* The device driver writes the relevant FW code block
* into the ram area in DWORDs via 1kB ram addressing window.
*/
for (i = 0; i < length; i++) {
if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
/* Point to correct 1kB ram window */
hibba = E1000_HI_FW_BASE_ADDRESS +
((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
(i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
*((u32 *)buffer + i));
}
/* Setting this bit tells the ARC that a new FW is ready to execute. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_C))
break;
msec_delay(1);
}
/* Check for successful FW start. */
if (i == E1000_HI_COMMAND_TIMEOUT) {
DEBUGOUT("New FW did not start within timeout period.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
return E1000_SUCCESS;
}

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -38,6 +38,9 @@ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw,
u8 *buffer, u16 length);
bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
u8 e1000_calculate_checksum(u8 *buffer, u32 length);
s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length);
s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length);
enum e1000_mng_mode {
e1000_mng_mode_none = 0,
@ -51,6 +54,8 @@ enum e1000_mng_mode {
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_FWSM_FW_VALID 0x00008000
#define E1000_FWSM_HI_EN_ONLY_MODE 0x4
#define E1000_MNG_IAMT_MODE 0x3
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
@ -66,8 +71,11 @@ enum e1000_mng_mode {
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI cmd limit */
#define E1000_HI_FW_BASE_ADDRESS 0x10000
#define E1000_HI_FW_MAX_LENGTH (64 * 1024) /* Num of bytes */
#define E1000_HI_FW_BLOCK_DWORD_LENGTH 256 /* Num of DWORDs per page */
#define E1000_HICR_MEMORY_BASE_EN 0x200 /* MB Enable bit - RO */
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
/* Driver sets this bit when done to put command in RAM */
#define E1000_HICR_C 0x02

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -465,7 +465,10 @@ s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
{
struct e1000_mbx_info *mbx = &hw->mbx;
if (hw->mac.type == e1000_82576) {
switch (hw->mac.type) {
case e1000_82576:
case e1000_i350:
case e1000_i354:
mbx->timeout = 0;
mbx->usec_delay = 0;
@ -484,8 +487,8 @@ s32 e1000_init_mbx_params_pf(struct e1000_hw *hw)
mbx->stats.reqs = 0;
mbx->stats.acks = 0;
mbx->stats.rsts = 0;
}
default:
return E1000_SUCCESS;
}
}

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -47,14 +47,14 @@
* PF. The reverse is true if it is E1000_PF_*.
* Message ACK's are the value or'd with 0xF0000000
*/
#define E1000_VT_MSGTYPE_ACK 0x80000000 /* Messages below or'd with
* this are the ACK */
#define E1000_VT_MSGTYPE_NACK 0x40000000 /* Messages below or'd with
* this are the NACK */
#define E1000_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
clear to send requests */
/* Msgs below or'd with this are the ACK */
#define E1000_VT_MSGTYPE_ACK 0x80000000
/* Msgs below or'd with this are the NACK */
#define E1000_VT_MSGTYPE_NACK 0x40000000
/* Indicates that VF is still clear to send requests */
#define E1000_VT_MSGTYPE_CTS 0x20000000
#define E1000_VT_MSGINFO_SHIFT 16
/* bits 23:16 are used for exra info for certain messages */
/* bits 23:16 are used for extra info for certain messages */
#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_RESET 0x01 /* VF requests reset */
@ -64,8 +64,8 @@
#define E1000_VF_SET_MULTICAST_OVERFLOW (0x80 << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */
#define E1000_VF_SET_VLAN_ADD (0x01 << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LPE */
#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.ROPE/MPME*/
#define E1000_VF_SET_LPE 0x05 /* reqs to set VMOLR.LPE */
#define E1000_VF_SET_PROMISC 0x06 /* reqs to clear VMOLR.ROPE/MPME*/
#define E1000_VF_SET_PROMISC_UNICAST (0x01 << E1000_VT_MSGINFO_SHIFT)
#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT)

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -27,7 +27,6 @@
#include "e1000_api.h"
static void e1000_stop_nvm(struct e1000_hw *hw);
static void e1000_reload_nvm_generic(struct e1000_hw *hw);
/**
@ -170,7 +169,6 @@ s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
s32 ret_val = -E1000_ERR_NVM;
DEBUGFUNC("e1000_poll_eerd_eewr_done");
@ -180,15 +178,13 @@ s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
else
reg = E1000_READ_REG(hw, E1000_EEWR);
if (reg & E1000_NVM_RW_REG_DONE) {
ret_val = E1000_SUCCESS;
break;
}
if (reg & E1000_NVM_RW_REG_DONE)
return E1000_SUCCESS;
usec_delay(5);
}
return ret_val;
return -E1000_ERR_NVM;
}
/**
@ -203,7 +199,6 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
{
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_acquire_nvm_generic");
@ -222,10 +217,10 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
DEBUGOUT("Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM;
return -E1000_ERR_NVM;
}
return ret_val;
return E1000_SUCCESS;
}
/**
@ -303,21 +298,20 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 ret_val = E1000_SUCCESS;
u16 timeout = 0;
u8 spi_stat_reg;
DEBUGFUNC("e1000_ready_nvm_eeprom");
if (nvm->type == e1000_nvm_eeprom_spi) {
u16 timeout = NVM_MAX_RETRY_SPI;
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(1);
timeout = NVM_MAX_RETRY_SPI;
/*
* Read "Status Register" repeatedly until the LSB is cleared.
/* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out.
@ -336,12 +330,70 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
if (!timeout) {
DEBUGOUT("SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM;
goto out;
return -E1000_ERR_NVM;
}
}
out:
return E1000_SUCCESS;
}
/**
* e1000_read_nvm_spi - Read EEPROM's using SPI
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM.
**/
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i = 0;
s32 ret_val;
u16 word_in;
u8 read_opcode = NVM_READ_OPCODE_SPI;
DEBUGFUNC("e1000_read_nvm_spi");
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
return -E1000_ERR_NVM;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
e1000_standby_nvm(hw);
if ((nvm->address_bits == 8) && (offset >= 128))
read_opcode |= NVM_A8_OPCODE_SPI;
/* Send the READ command (opcode + addr) */
e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
/* Read the data. SPI NVMs increment the address with each byte
* read and will roll over if reading beyond the end. This allows
* us to read the whole NVM from any offset
*/
for (i = 0; i < words; i++) {
word_in = e1000_shift_in_eec_bits(hw, 16);
data[i] = (word_in >> 8) | (word_in << 8);
}
release:
nvm->ops.release(hw);
return ret_val;
}
@ -362,15 +414,13 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
DEBUGFUNC("e1000_read_nvm_eerd");
/*
* A check for invalid values: offset too large, too many words,
/* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
return -E1000_ERR_NVM;
}
for (i = 0; i < words; i++) {
@ -386,7 +436,6 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
E1000_NVM_RW_REG_DATA);
}
out:
return ret_val;
}
@ -405,32 +454,32 @@ out:
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val;
s32 ret_val = -E1000_ERR_NVM;
u16 widx = 0;
DEBUGFUNC("e1000_write_nvm_spi");
/*
* A check for invalid values: offset too large, too many words,
/* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
return -E1000_ERR_NVM;
}
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = e1000_ready_nvm_eeprom(hw);
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto release;
return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val) {
nvm->ops.release(hw);
return ret_val;
}
e1000_standby_nvm(hw);
@ -440,8 +489,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
e1000_standby_nvm(hw);
/*
* Some SPI eeproms use the 8th address bit embedded in the
/* Some SPI eeproms use the 8th address bit embedded in the
* opcode
*/
if ((nvm->address_bits == 8) && (offset >= 128))
@ -464,49 +512,186 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
break;
}
}
msec_delay(10);
nvm->ops.release(hw);
}
msec_delay(10);
release:
nvm->ops.release(hw);
out:
return ret_val;
}
/**
* e1000_read_pba_num_generic - Read device part number
* e1000_read_pba_string_generic - Read device part number
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
* @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in pba_num.
**/
s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num)
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size)
{
s32 ret_val;
u16 nvm_data;
u16 pba_ptr;
u16 offset;
u16 length;
DEBUGFUNC("e1000_read_pba_num_generic");
DEBUGFUNC("e1000_read_pba_string_generic");
if (pba_num == NULL) {
DEBUGOUT("PBA string buffer was null\n");
return -E1000_ERR_INVALID_ARGUMENT;
}
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
return ret_val;
}
*pba_num = (u32)(nvm_data << 16);
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*pba_num |= nvm_data;
out:
return ret_val;
}
/* if nvm_data is not ptr guard the PBA must be in legacy format which
* means pba_ptr is actually our second data word for the PBA number
* and we can decode it into an ascii string
*/
if (nvm_data != NVM_PBA_PTR_GUARD) {
DEBUGOUT("NVM PBA number is not stored as string\n");
/* make sure callers buffer is big enough to store the PBA */
if (pba_num_size < E1000_PBANUM_LENGTH) {
DEBUGOUT("PBA string buffer too small\n");
return E1000_ERR_NO_SPACE;
}
/* extract hex string from data and pba_ptr */
pba_num[0] = (nvm_data >> 12) & 0xF;
pba_num[1] = (nvm_data >> 8) & 0xF;
pba_num[2] = (nvm_data >> 4) & 0xF;
pba_num[3] = nvm_data & 0xF;
pba_num[4] = (pba_ptr >> 12) & 0xF;
pba_num[5] = (pba_ptr >> 8) & 0xF;
pba_num[6] = '-';
pba_num[7] = 0;
pba_num[8] = (pba_ptr >> 4) & 0xF;
pba_num[9] = pba_ptr & 0xF;
/* put a null character on the end of our string */
pba_num[10] = '\0';
/* switch all the data but the '-' to hex char */
for (offset = 0; offset < 10; offset++) {
if (pba_num[offset] < 0xA)
pba_num[offset] += '0';
else if (pba_num[offset] < 0x10)
pba_num[offset] += 'A' - 0xA;
}
return E1000_SUCCESS;
}
ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
return ret_val;
}
if (length == 0xFFFF || length == 0) {
DEBUGOUT("NVM PBA number section invalid length\n");
return -E1000_ERR_NVM_PBA_SECTION;
}
/* check if pba_num buffer is big enough */
if (pba_num_size < (((u32)length * 2) - 1)) {
DEBUGOUT("PBA string buffer too small\n");
return -E1000_ERR_NO_SPACE;
}
/* trim pba length from start of string */
pba_ptr++;
length--;
for (offset = 0; offset < length; offset++) {
ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
return ret_val;
}
pba_num[offset * 2] = (u8)(nvm_data >> 8);
pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
}
pba_num[offset * 2] = '\0';
return E1000_SUCCESS;
}
/**
* e1000_read_pba_length_generic - Read device part number length
* @hw: pointer to the HW structure
* @pba_num_size: size of part number buffer
*
* Reads the product board assembly (PBA) number length from the EEPROM and
* stores the value in pba_num_size.
**/
s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
{
s32 ret_val;
u16 nvm_data;
u16 pba_ptr;
u16 length;
DEBUGFUNC("e1000_read_pba_length_generic");
if (pba_num_size == NULL) {
DEBUGOUT("PBA buffer size was null\n");
return -E1000_ERR_INVALID_ARGUMENT;
}
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
return ret_val;
}
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
return ret_val;
}
/* if data is not ptr guard the PBA must be in legacy format */
if (nvm_data != NVM_PBA_PTR_GUARD) {
*pba_num_size = E1000_PBANUM_LENGTH;
return E1000_SUCCESS;
}
ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
return ret_val;
}
if (length == 0xFFFF || length == 0) {
DEBUGOUT("NVM PBA number section invalid length\n");
return -E1000_ERR_NVM_PBA_SECTION;
}
/* Convert from length in u16 values to u8 chars, add 1 for NULL,
* and subtract 2 because length field is included in length.
*/
*pba_num_size = ((u32)length * 2) - 1;
return E1000_SUCCESS;
}
/**
* e1000_read_mac_addr_generic - Read device MAC address
* @hw: pointer to the HW structure
@ -545,7 +730,7 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
**/
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
@ -555,19 +740,17 @@ s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
return ret_val;
}
checksum += nvm_data;
}
if (checksum != (u16) NVM_SUM) {
DEBUGOUT("NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM;
goto out;
return -E1000_ERR_NVM;
}
out:
return ret_val;
return E1000_SUCCESS;
}
/**
@ -590,7 +773,7 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error while updating checksum.\n");
goto out;
return ret_val;
}
checksum += nvm_data;
}
@ -599,7 +782,6 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
if (ret_val)
DEBUGOUT("NVM Write Error while updating checksum.\n");
out:
return ret_val;
}
@ -623,3 +805,110 @@ static void e1000_reload_nvm_generic(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw);
}
/**
* e1000_get_fw_version - Get firmware version information
* @hw: pointer to the HW structure
* @fw_vers: pointer to output version structure
*
* unsupported/not present features return 0 in version structure
**/
void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
{
u16 eeprom_verh, eeprom_verl, etrack_test, fw_version;
u8 q, hval, rem, result;
u16 comb_verh, comb_verl, comb_offset;
memset(fw_vers, 0, sizeof(struct e1000_fw_version));
/* basic eeprom version numbers, bits used vary by part and by tool
* used to create the nvm images */
/* Check which data format we have */
hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
switch (hw->mac.type) {
case e1000_i211:
e1000_read_invm_version(hw, fw_vers);
return;
case e1000_82575:
case e1000_82576:
case e1000_82580:
/* Use this format, unless EETRACK ID exists,
* then use alternate format
*/
if ((etrack_test & NVM_MAJOR_MASK) != NVM_ETRACK_VALID) {
hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
>> NVM_MAJOR_SHIFT;
fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK)
>> NVM_MINOR_SHIFT;
fw_vers->eep_build = (fw_version & NVM_IMAGE_ID_MASK);
goto etrack_id;
}
break;
case e1000_i210:
if (!(e1000_get_flash_presence_i210(hw))) {
e1000_read_invm_version(hw, fw_vers);
return;
}
/* fall through */
case e1000_i350:
case e1000_i354:
/* find combo image version */
hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
if ((comb_offset != 0x0) &&
(comb_offset != NVM_VER_INVALID)) {
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
+ 1), 1, &comb_verh);
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
1, &comb_verl);
/* get Option Rom version if it exists and is valid */
if ((comb_verh && comb_verl) &&
((comb_verh != NVM_VER_INVALID) &&
(comb_verl != NVM_VER_INVALID))) {
fw_vers->or_valid = true;
fw_vers->or_major =
comb_verl >> NVM_COMB_VER_SHFT;
fw_vers->or_build =
(comb_verl << NVM_COMB_VER_SHFT)
| (comb_verh >> NVM_COMB_VER_SHFT);
fw_vers->or_patch =
comb_verh & NVM_COMB_VER_MASK;
}
}
break;
default:
return;
}
hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
>> NVM_MAJOR_SHIFT;
/* check for old style version format in newer images*/
if ((fw_version & NVM_NEW_DEC_MASK) == 0x0) {
eeprom_verl = (fw_version & NVM_COMB_VER_MASK);
} else {
eeprom_verl = (fw_version & NVM_MINOR_MASK)
>> NVM_MINOR_SHIFT;
}
/* Convert minor value to hex before assigning to output struct
* Val to be converted will not be higher than 99, per tool output
*/
q = eeprom_verl / NVM_HEX_CONV;
hval = q * NVM_HEX_TENS;
rem = eeprom_verl % NVM_HEX_CONV;
result = hval + rem;
fw_vers->eep_minor = result;
etrack_id:
if ((etrack_test & NVM_MAJOR_MASK) == NVM_ETRACK_VALID) {
hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT)
| eeprom_verl;
}
return;
}

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -28,22 +28,43 @@
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
struct e1000_fw_version {
u32 etrack_id;
u16 eep_major;
u16 eep_minor;
u16 eep_build;
u8 invm_major;
u8 invm_minor;
u8 invm_img_type;
bool or_valid;
u16 or_major;
u16 or_build;
u16 or_patch;
};
void e1000_init_nvm_ops_generic(struct e1000_hw *hw);
s32 e1000_acquire_nvm_generic(struct e1000_hw *hw);
s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num);
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size);
s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size);
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data);
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw);
s32 e1000_write_nvm_eewr(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw);
void e1000_release_nvm_generic(struct e1000_hw *hw);
void e1000_get_fw_version(struct e1000_hw *hw,
struct e1000_fw_version *fw_vers);
#define E1000_STM_OPCODE 0xDB00

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -41,6 +41,7 @@
#include "kcompat.h"
#define usec_delay(x) udelay(x)
#define usec_delay_irq(x) udelay(x)
#ifndef msec_delay
#define msec_delay(x) do { \
/* Don't mdelay in interrupt context! */ \
@ -70,7 +71,11 @@
#define DEBUGOUT(S)
#define DEBUGOUT1(S, A...)
#ifdef DEBUG_FUNC
#define DEBUGFUNC(F) DEBUGOUT(F "\n")
#else
#define DEBUGFUNC(F)
#endif
#define DEBUGOUT2 DEBUGOUT1
#define DEBUGOUT3 DEBUGOUT2
#define DEBUGOUT7 DEBUGOUT3

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -28,7 +28,6 @@
#ifndef _E1000_PHY_H_
#define _E1000_PHY_H_
void e1000_init_phy_ops_generic(struct e1000_hw *hw);
s32 e1000_check_downshift_generic(struct e1000_hw *hw);
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
@ -36,71 +35,92 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw);
s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
s32 e1000_get_cable_length_m88(struct e1000_hw *hw);
s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw);
s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw);
s32 e1000_get_cfg_done_generic(struct e1000_hw *hw);
s32 e1000_get_phy_id(struct e1000_hw *hw);
s32 e1000_get_phy_info_igp(struct e1000_hw *hw);
s32 e1000_get_phy_info_m88(struct e1000_hw *hw);
s32 e1000_get_phy_info_ife(struct e1000_hw *hw);
s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw);
void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw);
s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw);
s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page);
s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active);
s32 e1000_setup_copper_link_generic(struct e1000_hw *hw);
s32 e1000_wait_autoneg_generic(struct e1000_hw *hw);
s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
s32 e1000_determine_phy_address(struct e1000_hw *hw);
s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
void e1000_power_up_phy_copper(struct e1000_hw *hw);
void e1000_power_down_phy_copper(struct e1000_hw *hw);
s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data);
s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data);
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
s32 e1000_check_polarity_82577(struct e1000_hw *hw);
s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data);
s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
bool line_override);
bool e1000_is_mphy_ready(struct e1000_hw *hw);
#define E1000_MAX_PHY_ADDR 4
#define E1000_MAX_PHY_ADDR 8
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
/* GS40G - I210 PHY defines */
#define GS40G_PAGE_SELECT 0x16
#define GS40G_PAGE_SHIFT 16
#define GS40G_OFFSET_MASK 0xFFFF
#define GS40G_PAGE_2 0x20000
#define GS40G_MAC_REG2 0x15
#define GS40G_MAC_LB 0x4140
#define GS40G_MAC_SPEED_1G 0X0006
#define GS40G_COPPER_SPEC 0x0010
#define GS40G_CS_POWER_DOWN 0x0002
#define HV_INTC_FC_PAGE_START 768
#define I82578_ADDR_REG 29
#define I82577_ADDR_REG 16
#define I82577_CFG_REG 22
#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15)
#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */
#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift */
#define I82577_CTRL_REG 23
/* 82577 specific PHY registers */
@ -114,16 +134,29 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define I82577_PHY_STATUS2_MDIX 0x0800
#define I82577_PHY_STATUS2_SPEED_MASK 0x0300
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
#define I82577_PHY_STATUS2_SPEED_100MBPS 0x0100
/* I82577 PHY Control 2 */
#define I82577_PHY_CTRL2_AUTO_MDIX 0x0400
#define I82577_PHY_CTRL2_FORCE_MDI_MDIX 0x0200
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
#define I82577_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
#define I82577_PHY_CTRL2_MDIX_CFG_MASK 0x0600
/* I82577 PHY Diagnostics Status */
#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
/* 82580 PHY Power Management */
#define E1000_82580_PHY_POWER_MGMT 0xE14
#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */
#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */
#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */
#define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect */
#define E1000_MPHY_DIS_ACCESS 0x80000000 /* disable_access bit */
#define E1000_MPHY_ENA_ACCESS 0x40000000 /* enable_access bit */
#define E1000_MPHY_BUSY 0x00010000 /* busy bit */
#define E1000_MPHY_ADDRESS_FNC_OVERRIDE 0x20000000 /* fnc_override bit */
#define E1000_MPHY_ADDRESS_MASK 0x0000FFFF /* address mask */
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
@ -132,10 +165,6 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
/* Enable flexible speed on link-up */
#define IGP01E1000_GMII_FLEX_SPD 0x0010
#define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */
#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
@ -153,13 +182,10 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course=15:13, Fine=12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define IGP03E1000_PHY_MISC_CTRL 0x1B
#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
@ -168,11 +194,12 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */
#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */
#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */
#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Ctrl */
#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Ctrl */
#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
/* IFE PHY Extended Status Control */
@ -181,7 +208,6 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
/* IFE PHY Special Control */
#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
#define IFE_PSC_FORCE_POLARITY 0x0020
#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100
/* IFE PHY Special Control and LED Control */
#define IFE_PSCL_PROBE_MODE 0x0020
@ -191,6 +217,30 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
/* IFE PHY MDIX Control */
#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto, 0=disable */
/* SFP modules ID memory locations */
#define E1000_SFF_IDENTIFIER_OFFSET 0x00
#define E1000_SFF_IDENTIFIER_SFF 0x02
#define E1000_SFF_IDENTIFIER_SFP 0x03
#define E1000_SFF_ETH_FLAGS_OFFSET 0x06
/* Flags for SFP modules compatible with ETH up to 1Gb */
struct sfp_e1000_flags {
u8 e1000_base_sx:1;
u8 e1000_base_lx:1;
u8 e1000_base_cx:1;
u8 e1000_base_t:1;
u8 e100_base_lx:1;
u8 e100_base_fx:1;
u8 e10_base_bx10:1;
u8 e10_base_px:1;
};
/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
#define E1000_SFF_VENDOR_OUI_TYCO 0x00407600
#define E1000_SFF_VENDOR_OUI_FTL 0x00906500
#define E1000_SFF_VENDOR_OUI_AVAGO 0x00176A00
#define E1000_SFF_VENDOR_OUI_INTEL 0x001B2100
#endif

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -29,7 +29,6 @@
#define _E1000_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
@ -39,14 +38,19 @@
#define E1000_MDICNFG 0x00E04 /* MDI Config - RW */
#define E1000_REGISTER_SET_SIZE 0x20000 /* CSR Size */
#define E1000_EEPROM_INIT_CTRL_WORD_2 0x0F /* EEPROM Init Ctrl Word 2 */
#define E1000_EEPROM_PCIE_CTRL_WORD_2 0x28 /* EEPROM PCIe Ctrl Word 2 */
#define E1000_BARCTRL 0x5BBC /* BAR ctrl reg */
#define E1000_BARCTRL_FLSIZE 0x0700 /* BAR ctrl Flsize */
#define E1000_BARCTRL_CSRSIZE 0x2000 /* BAR ctrl CSR size */
#define E1000_MPHY_ADDR_CTRL 0x0024 /* GbE MPHY Address Control */
#define E1000_MPHY_DATA 0x0E10 /* GBE MPHY Data */
#define E1000_MPHY_STAT 0x0E0C /* GBE MPHY Statistics */
#define E1000_PPHY_CTRL 0x5b48 /* PCIe PHY Control */
#define E1000_I350_BARCTRL 0x5BFC /* BAR ctrl reg */
#define E1000_I350_DTXMXPKTSZ 0x355C /* Maximum sent packet size reg*/
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FEXT 0x0002C /* Future Extended - RW */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
@ -73,9 +77,9 @@
#define E1000_TCTL 0x00400 /* Tx Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
#define E1000_TBT 0x00448 /* Tx Burst Timer - RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_LEDMUX 0x08130 /* LED MUX Control */
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
@ -83,29 +87,37 @@
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
#define E1000_I2CBB_EN 0x00000100 /* I2C - Bit Bang Enable */
#define E1000_I2C_CLK_OUT 0x00000200 /* I2C- Clock */
#define E1000_I2C_DATA_OUT 0x00000400 /* I2C- Data Out */
#define E1000_I2C_DATA_OE_N 0x00000800 /* I2C- Data Output Enable */
#define E1000_I2C_DATA_IN 0x00001000 /* I2C- Data In */
#define E1000_I2C_CLK_OE_N 0x00002000 /* I2C- Clock Output Enable */
#define E1000_I2C_CLK_IN 0x00004000 /* I2C- Clock In */
#define E1000_I2C_CLK_STRETCH_DIS 0x00008000 /* I2C- Dis Clk Stretching */
#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */
#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_VPDDIAG 0x01060 /* VPD Diagnostic - RO */
#define E1000_ICR_V2 0x01500 /* Interrupt Cause - new location - RC */
#define E1000_ICS_V2 0x01504 /* Interrupt Cause Set - new location - WO */
#define E1000_IMS_V2 0x01508 /* Interrupt Mask Set/Read - new location - RW */
#define E1000_IMC_V2 0x0150C /* Interrupt Mask Clear - new location - WO */
#define E1000_IAM_V2 0x01510 /* Interrupt Ack Auto Mask - new location - RW */
#define E1000_ICR_V2 0x01500 /* Intr Cause - new location - RC */
#define E1000_ICS_V2 0x01504 /* Intr Cause Set - new location - WO */
#define E1000_IMS_V2 0x01508 /* Intr Mask Set/Read - new location - RW */
#define E1000_IMC_V2 0x0150C /* Intr Mask Clear - new location - WO */
#define E1000_IAM_V2 0x01510 /* Intr Ack Auto Mask - new location - RW */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
#define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */
#define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */
#define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */
#define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */
#define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */
#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
/* Split and Replication Rx Control - RW */
@ -116,11 +128,72 @@
#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */
#define E1000_PBDIAG 0x02458 /* Packet Buffer Diagnostic - RW */
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
#define E1000_IRPBS 0x02404 /* Same as RXPBS, renamed for newer adapters - RW */
#define E1000_IRPBS 0x02404 /* Same as RXPBS, renamed for newer Si - RW */
#define E1000_PBRWAC 0x024E8 /* Rx packet buffer wrap around counter - RO */
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
/*
* Convenience macros
#define E1000_EMIADD 0x10 /* Extended Memory Indirect Address */
#define E1000_EMIDATA 0x11 /* Extended Memory Indirect Data */
#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
#define E1000_I210_FLMNGCTL 0x12038
#define E1000_I210_FLMNGDATA 0x1203C
#define E1000_I210_FLMNGCNT 0x12040
#define E1000_I210_FLSWCTL 0x12048
#define E1000_I210_FLSWDATA 0x1204C
#define E1000_I210_FLSWCNT 0x12050
#define E1000_I210_FLA 0x1201C
#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
/* QAV Tx mode control register */
#define E1000_I210_TQAVCTRL 0x3570
/* QAV Tx mode control register bitfields masks */
/* QAV enable */
#define E1000_TQAVCTRL_MODE (1 << 0)
/* Fetching arbitration type */
#define E1000_TQAVCTRL_FETCH_ARB (1 << 4)
/* Fetching timer enable */
#define E1000_TQAVCTRL_FETCH_TIMER_ENABLE (1 << 5)
/* Launch arbitration type */
#define E1000_TQAVCTRL_LAUNCH_ARB (1 << 8)
/* Launch timer enable */
#define E1000_TQAVCTRL_LAUNCH_TIMER_ENABLE (1 << 9)
/* SP waits for SR enable */
#define E1000_TQAVCTRL_SP_WAIT_SR (1 << 10)
/* Fetching timer correction */
#define E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET 16
#define E1000_TQAVCTRL_FETCH_TIMER_DELTA \
(0xFFFF << E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET)
/* High credit registers where _n can be 0 or 1. */
#define E1000_I210_TQAVHC(_n) (0x300C + 0x40 * (_n))
/* Queues fetch arbitration priority control register */
#define E1000_I210_TQAVARBCTRL 0x3574
/* Queues priority masks where _n and _p can be 0-3. */
#define E1000_TQAVARBCTRL_QUEUE_PRI(_n, _p) ((_p) << (2 * _n))
/* QAV Tx mode control registers where _n can be 0 or 1. */
#define E1000_I210_TQAVCC(_n) (0x3004 + 0x40 * (_n))
/* QAV Tx mode control register bitfields masks */
#define E1000_TQAVCC_IDLE_SLOPE 0xFFFF /* Idle slope */
#define E1000_TQAVCC_KEEP_CREDITS (1 << 30) /* Keep credits opt enable */
#define E1000_TQAVCC_QUEUE_MODE (1 << 31) /* SP vs. SR Tx mode */
/* Good transmitted packets counter registers */
#define E1000_PQGPTC(_n) (0x010014 + (0x100 * (_n)))
/* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */
#define E1000_I210_TXPBS_SIZE(_n, _s) ((_s) << (6 * _n))
#define E1000_MMDAC 13 /* MMD Access Control */
#define E1000_MMDAAD 14 /* MMD Access Address/Data */
/* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
@ -168,40 +241,42 @@
#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100))
#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
(0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
(0x054E4 + ((_i - 16) * 8)))
#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8))
#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8))
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
#define E1000_PBSLAC 0x03100 /* Packet Buffer Slave Access Control */
#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Packet Buffer DWORD (_n) */
#define E1000_PBSLAC 0x03100 /* Pkt Buffer Slave Access Control */
#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Pkt Buffer DWORD */
#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
#define E1000_ITPBS 0x03404 /* Same as TXPBS, renamed for newer adpaters - RW */
/* Same as TXPBS, renamed for newer Si - RW */
#define E1000_ITPBS 0x03404
#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
#define E1000_TDPUMB 0x0357C /* DMA Tx Descriptor uC Mail Box - RW */
#define E1000_TDPUAD 0x03580 /* DMA Tx Descriptor uC Addr Command - RW */
#define E1000_TDPUWD 0x03584 /* DMA Tx Descriptor uC Data Write - RW */
#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */
#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */
#define E1000_TDPUMB 0x0357C /* DMA Tx Desc uC Mail Box - RW */
#define E1000_TDPUAD 0x03580 /* DMA Tx Desc uC Addr Command - RW */
#define E1000_TDPUWD 0x03584 /* DMA Tx Desc uC Data Write - RW */
#define E1000_TDPURD 0x03588 /* DMA Tx Desc uC Data Read - RW */
#define E1000_TDPUCTL 0x0358C /* DMA Tx Desc uC Control - RW */
#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */
#define E1000_DTXTCPFLGL 0x0359C /* DMA Tx Control flag low - RW */
#define E1000_DTXTCPFLGH 0x035A0 /* DMA Tx Control flag high - RW */
#define E1000_DTXMXSZRQ 0x03540 /* DMA Tx Max Total Allow Size Requests - RW */
/* DMA Tx Max Total Allow Size Reqs - RW */
#define E1000_DTXMXSZRQ 0x03540
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
@ -270,55 +345,71 @@
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */
#define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */
#define E1000_LSECTXPKTP 0x04308 /* LinkSec Protected Tx Packet Count - OutPktsProtected */
#define E1000_LSECTXOCTE 0x0430C /* LinkSec Encrypted Tx Octets Count - OutOctetsEncrypted */
#define E1000_LSECTXOCTP 0x04310 /* LinkSec Protected Tx Octets Count - OutOctetsProtected */
#define E1000_LSECRXUT 0x04314 /* LinkSec Untagged non-Strict Rx Packet Count - InPktsUntagged/InPktsNoTag */
#define E1000_LSECRXOCTD 0x0431C /* LinkSec Rx Octets Decrypted Count - InOctetsDecrypted */
#define E1000_LSECRXOCTV 0x04320 /* LinkSec Rx Octets Validated - InOctetsValidated */
#define E1000_LSECRXBAD 0x04324 /* LinkSec Rx Bad Tag - InPktsBadTag */
#define E1000_LSECRXNOSCI 0x04328 /* LinkSec Rx Packet No SCI Count - InPktsNoSci */
#define E1000_LSECRXUNSCI 0x0432C /* LinkSec Rx Packet Unknown SCI Count - InPktsUnknownSci */
#define E1000_LSECRXUNCH 0x04330 /* LinkSec Rx Unchecked Packets Count - InPktsUnchecked */
#define E1000_LSECRXDELAY 0x04340 /* LinkSec Rx Delayed Packet Count - InPktsDelayed */
#define E1000_LSECRXLATE 0x04350 /* LinkSec Rx Late Packets Count - InPktsLate */
#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* LinkSec Rx Packet OK Count - InPktsOk */
#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* LinkSec Rx Invalid Count - InPktsInvalid */
#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* LinkSec Rx Not Valid Count - InPktsNotValid */
#define E1000_LSECRXUNSA 0x043C0 /* LinkSec Rx Unused SA Count - InPktsUnusedSa */
#define E1000_LSECRXNUSA 0x043D0 /* LinkSec Rx Not Using SA Count - InPktsNotUsingSa */
#define E1000_LSECTXCAP 0x0B000 /* LinkSec Tx Capabilities Register - RO */
#define E1000_LSECRXCAP 0x0B300 /* LinkSec Rx Capabilities Register - RO */
#define E1000_LSECTXCTRL 0x0B004 /* LinkSec Tx Control - RW */
#define E1000_LSECRXCTRL 0x0B304 /* LinkSec Rx Control - RW */
#define E1000_LSECTXSCL 0x0B008 /* LinkSec Tx SCI Low - RW */
#define E1000_LSECTXSCH 0x0B00C /* LinkSec Tx SCI High - RW */
#define E1000_LSECTXSA 0x0B010 /* LinkSec Tx SA0 - RW */
#define E1000_LSECTXPN0 0x0B018 /* LinkSec Tx SA PN 0 - RW */
#define E1000_LSECTXPN1 0x0B01C /* LinkSec Tx SA PN 1 - RW */
#define E1000_LSECRXSCL 0x0B3D0 /* LinkSec Rx SCI Low - RW */
#define E1000_LSECRXSCH 0x0B3E0 /* LinkSec Rx SCI High - RW */
#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 0 - WO */
#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 1 - WO */
#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
/*
* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
/* Virtualization statistical counters */
#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n)))
#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n)))
#define E1000_PFVFGORC(_n) (0x010018 + (0x100 * (_n)))
#define E1000_PFVFGOTC(_n) (0x010034 + (0x100 * (_n)))
#define E1000_PFVFMPRC(_n) (0x010038 + (0x100 * (_n)))
#define E1000_PFVFGPRLBC(_n) (0x010040 + (0x100 * (_n)))
#define E1000_PFVFGPTLBC(_n) (0x010044 + (0x100 * (_n)))
#define E1000_PFVFGORLBC(_n) (0x010048 + (0x100 * (_n)))
#define E1000_PFVFGOTLBC(_n) (0x010050 + (0x100 * (_n)))
/* LinkSec */
#define E1000_LSECTXUT 0x04300 /* Tx Untagged Pkt Cnt */
#define E1000_LSECTXPKTE 0x04304 /* Encrypted Tx Pkts Cnt */
#define E1000_LSECTXPKTP 0x04308 /* Protected Tx Pkt Cnt */
#define E1000_LSECTXOCTE 0x0430C /* Encrypted Tx Octets Cnt */
#define E1000_LSECTXOCTP 0x04310 /* Protected Tx Octets Cnt */
#define E1000_LSECRXUT 0x04314 /* Untagged non-Strict Rx Pkt Cnt */
#define E1000_LSECRXOCTD 0x0431C /* Rx Octets Decrypted Count */
#define E1000_LSECRXOCTV 0x04320 /* Rx Octets Validated */
#define E1000_LSECRXBAD 0x04324 /* Rx Bad Tag */
#define E1000_LSECRXNOSCI 0x04328 /* Rx Packet No SCI Count */
#define E1000_LSECRXUNSCI 0x0432C /* Rx Packet Unknown SCI Count */
#define E1000_LSECRXUNCH 0x04330 /* Rx Unchecked Packets Count */
#define E1000_LSECRXDELAY 0x04340 /* Rx Delayed Packet Count */
#define E1000_LSECRXLATE 0x04350 /* Rx Late Packets Count */
#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* Rx Pkt OK Cnt */
#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* Rx Invalid Cnt */
#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* Rx Not Valid Cnt */
#define E1000_LSECRXUNSA 0x043C0 /* Rx Unused SA Count */
#define E1000_LSECRXNUSA 0x043D0 /* Rx Not Using SA Count */
#define E1000_LSECTXCAP 0x0B000 /* Tx Capabilities Register - RO */
#define E1000_LSECRXCAP 0x0B300 /* Rx Capabilities Register - RO */
#define E1000_LSECTXCTRL 0x0B004 /* Tx Control - RW */
#define E1000_LSECRXCTRL 0x0B304 /* Rx Control - RW */
#define E1000_LSECTXSCL 0x0B008 /* Tx SCI Low - RW */
#define E1000_LSECTXSCH 0x0B00C /* Tx SCI High - RW */
#define E1000_LSECTXSA 0x0B010 /* Tx SA0 - RW */
#define E1000_LSECTXPN0 0x0B018 /* Tx SA PN 0 - RW */
#define E1000_LSECTXPN1 0x0B01C /* Tx SA PN 1 - RW */
#define E1000_LSECRXSCL 0x0B3D0 /* Rx SCI Low - RW */
#define E1000_LSECRXSCH 0x0B3E0 /* Rx SCI High - RW */
/* LinkSec Tx 128-bit Key 0 - WO */
#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n)))
/* LinkSec Tx 128-bit Key 1 - WO */
#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n)))
#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* Rx SAs - RW */
#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* Rx SAs - RW */
/* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
* key - RW.
*/
#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
#define E1000_SSVPC 0x041A0 /* Switch Security Violation Packet Count */
#define E1000_SSVPC 0x041A0 /* Switch Security Violation Pkt Cnt */
#define E1000_IPSCTRL 0xB430 /* IpSec Control Register */
#define E1000_IPSRXCMD 0x0B408 /* IPSec Rx Command Register - RW */
#define E1000_IPSRXIDX 0x0B400 /* IPSec Rx Index - RW */
#define E1000_IPSRXIPADDR(_n) (0x0B420+ (0x04 * (_n))) /* IPSec Rx IPv4/v6 Address - RW */
#define E1000_IPSRXKEY(_n) (0x0B410 + (0x04 * (_n))) /* IPSec Rx 128-bit Key - RW */
/* IPSec Rx IPv4/v6 Address - RW */
#define E1000_IPSRXIPADDR(_n) (0x0B420 + (0x04 * (_n)))
/* IPSec Rx 128-bit Key - RW */
#define E1000_IPSRXKEY(_n) (0x0B410 + (0x04 * (_n)))
#define E1000_IPSRXSALT 0x0B404 /* IPSec Rx Salt - RW */
#define E1000_IPSRXSPI 0x0B40C /* IPSec Rx SPI - RW */
#define E1000_IPSTXKEY(_n) (0x0B460 + (0x04 * (_n))) /* IPSec Tx 128-bit Key - RW */
/* IPSec Tx 128-bit Key - RW */
#define E1000_IPSTXKEY(_n) (0x0B460 + (0x04 * (_n)))
#define E1000_IPSTXSALT 0x0B454 /* IPSec Tx Salt - RW */
#define E1000_IPSTXIDX 0x0B450 /* IPSec Tx SA IDX - RW */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
@ -341,16 +432,17 @@
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Pg - RW */
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_RA2 0x054E0 /* 2nd half of receive address array - RW Array */
#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
#define E1000_CIAA 0x05B88 /* Config Indirect Access Address - RW */
#define E1000_CIAD 0x05B8C /* Config Indirect Access Data - RW */
#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
@ -367,14 +459,18 @@
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
#define E1000_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flexible Host Filter Table */
#define E1000_FHFT_EXT(_n) (0x09A00 + (_n * 0x100)) /* Ext Flexible Host Filter Table */
#define E1000_HIBBA 0x8F40 /* Host Interface Buffer Base Address */
/* Flexible Host Filter Table */
#define E1000_FHFT(_n) (0x09000 + ((_n) * 0x100))
/* Ext Flexible Host Filter Table */
#define E1000_FHFT_EXT(_n) (0x09A00 + ((_n) * 0x100))
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
/* Management Decision Filters */
#define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
#define E1000_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
@ -387,30 +483,22 @@
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_SWSM2 0x05B58 /* Driver-only SW semaphore (not used by BOOT agents) */
/* Driver-only SW semaphore (not used by BOOT agents) */
#define E1000_SWSM2 0x05B58
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
#define E1000_UFUSE 0x05B78 /* UFUSE - RO */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Interface Control */
#define E1000_FWSTS 0x08F0C /* FW Status */
/* RSS registers */
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt Rx VLAN Priority - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Allocation Register
* (_i) - RW */
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10)) /* MSI-X Table entry addr
* low reg - RW */
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10)) /* MSI-X Table entry addr
* upper reg - RW */
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10)) /* MSI-X Table entry
* message reg - RW */
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10)) /* MSI-X Table entry
* vector ctrl reg - RW */
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate INT Rx VLAN Priority -RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Alloc Reg -RW */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
@ -424,20 +512,30 @@
#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */
#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
#define E1000_VMRCTL 0X05D80 /* Virtual Mirror Rule Control */
#define E1000_VMRVLAN 0x05D90 /* Virtual Mirror Rule VLAN */
#define E1000_VMRVM 0x05DA0 /* Virtual Mirror Rule VM */
#define E1000_MDFB 0x03558 /* Malicious Driver free block */
#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */
#define E1000_TXSWC 0x05ACC /* Tx Switch Control */
#define E1000_SCCRL 0x05DB0 /* Storm Control Control */
#define E1000_BSCTRH 0x05DB8 /* Broadcast Storm Control Threshold */
#define E1000_MSCTRH 0x05DBC /* Multicast Storm Control Threshold */
/* These act per VF so an array friendly macro is used */
#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n)))
#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
#define E1000_VFVMBMEM(_n) (0x00800 + (_n))
#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
* Filter - RW */
/* VLAN Virtual Machine Filter - RW */
#define E1000_VLVF(_n) (0x05D00 + (4 * (_n)))
#define E1000_VMVIR(_n) (0x03700 + (4 * (_n)))
/* Time Sync */
#define E1000_DVMOLR(_n) (0x0C038 + (0x40 * (_n))) /* DMA VM offload */
#define E1000_VTCTRL(_n) (0x10000 + (0x100 * (_n))) /* VT Control */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
@ -450,8 +548,12 @@
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_TIMADJL 0x0B60C /* Time sync time adjustment offset Low - RW */
#define E1000_TIMADJH 0x0B610 /* Time sync time adjustment offset High - RW */
#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
/* Filtering Registers */
#define E1000_SAQF(_n) (0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
@ -467,17 +569,28 @@
#define E1000_RTRPCS 0x2474 /* Rx packet plane control and status */
#define E1000_RTRUP2TC 0x05AC4 /* Rx User Priority to Traffic Class */
#define E1000_RTTUP2TC 0x0418 /* Transmit User Priority to Traffic Class */
#define E1000_RTTDTCRC(_n) (0x3610 + ((_n) * 4)) /* Tx Desc plane TC Rate-scheduler config */
#define E1000_RTTPTCRC(_n) (0x3480 + ((_n) * 4)) /* Tx Packet plane TC Rate-Scheduler Config */
#define E1000_RTRPTCRC(_n) (0x2480 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler Config */
#define E1000_RTTDTCRS(_n) (0x3630 + ((_n) * 4)) /* Tx Desc Plane TC Rate-Scheduler Status */
#define E1000_RTTDTCRM(_n) (0x3650 + ((_n) * 4)) /* Tx Desc Plane TC Rate-Scheduler MMW */
#define E1000_RTTPTCRS(_n) (0x34A0 + ((_n) * 4)) /* Tx Packet plane TC Rate-Scheduler Status */
#define E1000_RTTPTCRM(_n) (0x34C0 + ((_n) * 4)) /* Tx Packet plane TC Rate-scheduler MMW */
#define E1000_RTRPTCRS(_n) (0x24A0 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler Status */
#define E1000_RTRPTCRM(_n) (0x24C0 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler MMW */
#define E1000_RTTDVMRM(_n) (0x3670 + ((_n) * 4)) /* Tx Desc plane VM Rate-Scheduler MMW*/
#define E1000_RTTBCNRM(_n) (0x3690 + ((_n) * 4)) /* Tx BCN Rate-Scheduler MMW */
/* Tx Desc plane TC Rate-scheduler config */
#define E1000_RTTDTCRC(_n) (0x3610 + ((_n) * 4))
/* Tx Packet plane TC Rate-Scheduler Config */
#define E1000_RTTPTCRC(_n) (0x3480 + ((_n) * 4))
/* Rx Packet plane TC Rate-Scheduler Config */
#define E1000_RTRPTCRC(_n) (0x2480 + ((_n) * 4))
/* Tx Desc Plane TC Rate-Scheduler Status */
#define E1000_RTTDTCRS(_n) (0x3630 + ((_n) * 4))
/* Tx Desc Plane TC Rate-Scheduler MMW */
#define E1000_RTTDTCRM(_n) (0x3650 + ((_n) * 4))
/* Tx Packet plane TC Rate-Scheduler Status */
#define E1000_RTTPTCRS(_n) (0x34A0 + ((_n) * 4))
/* Tx Packet plane TC Rate-scheduler MMW */
#define E1000_RTTPTCRM(_n) (0x34C0 + ((_n) * 4))
/* Rx Packet plane TC Rate-Scheduler Status */
#define E1000_RTRPTCRS(_n) (0x24A0 + ((_n) * 4))
/* Rx Packet plane TC Rate-Scheduler MMW */
#define E1000_RTRPTCRM(_n) (0x24C0 + ((_n) * 4))
/* Tx Desc plane VM Rate-Scheduler MMW*/
#define E1000_RTTDVMRM(_n) (0x3670 + ((_n) * 4))
/* Tx BCN Rate-Scheduler MMW */
#define E1000_RTTBCNRM(_n) (0x3690 + ((_n) * 4))
#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select */
#define E1000_RTTDVMRC 0x3608 /* Tx Desc Plane VM Rate-Scheduler Config */
#define E1000_RTTDVMRS 0x360C /* Tx Desc Plane VM Rate-Scheduler Status */
@ -498,10 +611,36 @@
#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */
#define E1000_DMCTLX 0x02514 /* Time to Lx Request */
#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */
#define E1000_DMCCNT 0x05DD4 /* Current RX Count */
#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */
#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */
#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
/* PCIe Parity Status Register */
#define E1000_PCIEERRSTS 0x05BA8
#define E1000_PROXYS 0x5F64 /* Proxying Status */
#define E1000_PROXYFC 0x5F60 /* Proxying Filter Control */
/* Thermal sensor configuration and status registers */
#define E1000_THMJT 0x08100 /* Junction Temperature */
#define E1000_THLOWTC 0x08104 /* Low Threshold Control */
#define E1000_THMIDTC 0x08108 /* Mid Threshold Control */
#define E1000_THHIGHTC 0x0810C /* High Threshold Control */
#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
/* Energy Efficient Ethernet "EEE" registers */
#define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */
#define E1000_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
#define E1000_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/
#define E1000_EEE_SU 0x0E34 /* EEE Setup */
#define E1000_TLPIC 0x4148 /* EEE Tx LPI Count - TLPIC */
#define E1000_RLPIC 0x414C /* EEE Rx LPI Count - RLPIC */
/* OS2BMC Registers */
#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */
#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
#endif

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -25,15 +25,13 @@
*******************************************************************************/
/* Linux PRO/1000 Ethernet Driver main header file */
#ifndef _IGB_H_
#define _IGB_H_
#ifdef IGB_LRO
#include <net/tcp.h>
#endif
#include <linux/kobject.h>
#ifdef __VMKLNX__
#define NODE_ADDRESS_SIZE 6
@ -52,12 +50,6 @@
#include <linux/ethtool.h>
#endif
#ifdef SIOCSHWTSTAMP
#include <linux/clocksource.h>
#include <linux/timecompare.h>
#include <linux/net_tstamp.h>
#endif
struct igb_adapter;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
@ -67,33 +59,37 @@ struct igb_adapter;
#include <linux/dca.h>
#endif
#ifndef SIOCSHWTSTAMP
#undef IGB_PER_PKT_TIMESTAMP
#endif
#include "kcompat.h"
#ifdef HAVE_SCTP
#include <linux/sctp.h>
#endif
#include "e1000_api.h"
#include "e1000_82575.h"
#include "e1000_manage.h"
#include "e1000_mbx.h"
#define IGB_ERR(args...) printk(KERN_ERR "igb: " args)
/* Disable Netqueue for 1G driver */
#if defined( __VMKLNX__)
#ifdef __VMKNETDDI_QUEUEOPS__
#undef __VMKNETDDI_QUEUEOPS__
#endif
#endif /* defined(__VMKLNX__) */
#define PFX "igb: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
__FUNCTION__ , ## args))
#ifdef HAVE_PTP_1588_CLOCK
#include <linux/clocksource.h>
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#endif /* HAVE_PTP_1588_CLOCK */
/* Interrupt defines */
#define IGB_START_ITR 648 /* ~6000 ints/sec */
#define IGB_4K_ITR 980
#define IGB_20K_ITR 196
#define IGB_70K_ITR 56
/* Interrupt modes, as used by the IntMode paramter */
#define IGB_INT_MODE_LEGACY 0
@ -102,6 +98,7 @@ struct igb_adapter;
/* TX/RX descriptor defines */
#define IGB_DEFAULT_TXD 256
#define IGB_DEFAULT_TX_WORK 128
#define IGB_MIN_TXD 80
#define IGB_MAX_TXD 4096
@ -113,7 +110,7 @@ struct igb_adapter;
#define IGB_MAX_ITR_USECS 8191 /* 120 irq/sec */
#define NON_Q_VECTORS 1
#define MAX_Q_VECTORS 8
#define MAX_Q_VECTORS 10
/* Transmit and receive queues */
#define IGB_MAX_RX_QUEUES 16
@ -121,10 +118,13 @@ struct igb_adapter;
#define IGB_MAX_VF_MC_ENTRIES 30
#define IGB_MAX_VF_FUNCTIONS 8
#define IGB_MAX_VFTA_ENTRIES 128
#define IGB_82576_VF_DEV_ID 0x10CA
#define IGB_I350_VF_DEV_ID 0x1520
#define IGB_MAX_UTA_ENTRIES 128
#define MAX_EMULATION_MAC_ADDRS 16
#define OUI_LEN 3
#define IGB_MAX_VMDQ_QUEUES 8
struct vf_data_storage {
unsigned char vf_mac_addresses[ETH_ALEN];
@ -136,11 +136,20 @@ struct vf_data_storage {
u32 uta_table_copy[IGB_MAX_UTA_ENTRIES];
u32 flags;
unsigned long last_nack;
#ifdef IFLA_VF_MAX
u16 pf_vlan; /* When set, guest VLAN config not allowed. */
u16 pf_qos;
u16 tx_rate;
#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
bool spoofchk_enabled;
#endif
#endif
};
#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */
#define IGB_VF_FLAG_UNI_PROMISC 0x00000002 /* VF has unicast promisc */
#define IGB_VF_FLAG_MULTI_PROMISC 0x00000004 /* VF has multicast promisc */
#define IGB_VF_FLAG_PF_SET_MAC 0x00000008 /* PF has set MAC address */
/* RX descriptor control thresholds.
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
@ -153,25 +162,33 @@ struct vf_data_storage {
* descriptors until either it has this many to write back, or the
* ITR timer expires.
*/
#define IGB_RX_PTHRESH (hw->mac.type <= e1000_82576 ? 16 : 8)
#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : 8)
#define IGB_RX_HTHRESH 8
#define IGB_RX_WTHRESH 1
#define IGB_TX_PTHRESH 8
#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
#define IGB_TX_HTHRESH 1
#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \
adapter->msix_entries) ? 1 : 16)
#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
adapter->msix_entries) ? 1 : 4)
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
/* NOTE: netdev_alloc_skb reserves 16 bytes, NET_IP_ALIGN means we
* reserve 2 more, and skb_shared_info adds an additional 384 more,
* this adds roughly 448 bytes of extra data meaning the smallest
* allocation we could have is 1K.
* i.e. RXBUFFER_512 --> size-1024 slab
*/
/* Supported Rx Buffer Sizes */
#define IGB_RXBUFFER_64 64 /* Used for packet split */
#define IGB_RXBUFFER_128 128 /* Used for packet split */
#define IGB_RXBUFFER_1024 1024
#define IGB_RXBUFFER_256 256
#define IGB_RXBUFFER_2048 2048
#define IGB_RXBUFFER_4096 4096
#define IGB_RXBUFFER_8192 8192
#define IGB_RXBUFFER_16384 16384
#define IGB_RX_HDR_LEN IGB_RXBUFFER_256
#if MAX_SKB_FRAGS < 8
#define IGB_RX_BUFSZ ALIGN(MAX_JUMBO_FRAME_SIZE / MAX_SKB_FRAGS, 1024)
#else
#define IGB_RX_BUFSZ IGB_RXBUFFER_2048
#endif
/* Packet Buffer allocations */
#define IGB_PBA_BYTES_SHIFT 0xA
@ -180,13 +197,11 @@ struct vf_data_storage {
#define IGB_FC_PAUSE_TIME 0x0680 /* 858 usec */
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
#define IGB_TX_QUEUE_WAKE 32
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define AUTO_ALL_MODES 0
#define IGB_EEPROM_APME 0x0400
#define AUTO_ALL_MODES 0
#ifndef IGB_MASTER_SLAVE
/* Switch to override PHY master/slave setting */
@ -195,68 +210,67 @@ struct vf_data_storage {
#define IGB_MNG_VLAN_NONE -1
#ifdef IGB_LRO
#define IGB_LRO_MAX 32 /*Maximum number of LRO descriptors*/
#define IGB_LRO_GLOBAL 10
struct igb_cb {
#ifdef HAVE_VLAN_RX_REGISTER
u16 vid; /* VLAN tag */
#endif
};
#define IGB_CB(skb) ((struct igb_cb *)(skb)->cb)
struct igb_lro_stats {
u32 flushed;
u32 coal;
u32 recycled;
enum igb_tx_flags {
/* cmd_type flags */
IGB_TX_FLAGS_VLAN = 0x01,
IGB_TX_FLAGS_TSO = 0x02,
IGB_TX_FLAGS_TSTAMP = 0x04,
/* olinfo flags */
IGB_TX_FLAGS_IPV4 = 0x10,
IGB_TX_FLAGS_CSUM = 0x20,
};
struct igb_lro_desc {
struct hlist_node lro_node;
struct sk_buff *skb;
u32 source_ip;
u32 dest_ip;
u16 source_port;
u16 dest_port;
u16 vlan_tag;
u16 len;
u32 next_seq;
u32 ack_seq;
u16 window;
u16 mss;
u16 opt_bytes;
u16 psh:1;
u32 tsval;
u32 tsecr;
u32 append_cnt;
};
/* VLAN info */
#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
#define IGB_TX_FLAGS_VLAN_SHIFT 16
struct igb_lro_list {
struct hlist_head active;
struct hlist_head free;
int active_cnt;
struct igb_lro_stats stats;
};
/*
* The largest size we can write to the descriptor is 65535. In order to
* maintain a power of two alignment we have to limit ourselves to 32K.
*/
#define IGB_MAX_TXD_PWR 15
#define IGB_MAX_DATA_PER_TXD (1 << IGB_MAX_TXD_PWR)
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IGB_MAX_DATA_PER_TXD)
#ifndef MAX_SKB_FRAGS
#define DESC_NEEDED 4
#elif (MAX_SKB_FRAGS < 16)
#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4)
#else
#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
#endif
#endif /* IGB_LRO */
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct igb_buffer {
struct sk_buff *skb;
dma_addr_t dma;
union {
/* TX */
struct {
struct igb_tx_buffer {
union e1000_adv_tx_desc *next_to_watch;
unsigned long time_stamp;
u16 length;
u16 next_to_watch;
u16 mapped_as_page;
struct sk_buff *skb;
unsigned int bytecount;
u16 gso_segs;
};
__be16 protocol;
DEFINE_DMA_UNMAP_ADDR(dma);
DEFINE_DMA_UNMAP_LEN(len);
u32 tx_flags;
};
#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
/* RX */
struct {
unsigned long page_offset;
struct igb_rx_buffer {
dma_addr_t dma;
#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
struct sk_buff *skb;
#else
struct page *page;
dma_addr_t page_dma;
};
u32 page_offset;
#endif
};
};
struct igb_tx_queue_stats {
@ -271,61 +285,64 @@ struct igb_rx_queue_stats {
u64 drops;
u64 csum_err;
u64 alloc_failed;
u64 ipv4_packets; /* IPv4 headers processed */
u64 ipv4e_packets; /* IPv4E headers with extensions processed */
u64 ipv6_packets; /* IPv6 headers processed */
u64 ipv6e_packets; /* IPv6E headers with extensions processed */
u64 tcp_packets; /* TCP headers processed */
u64 udp_packets; /* UDP headers processed */
u64 sctp_packets; /* SCTP headers processed */
u64 nfs_packets; /* NFS headers processe */
};
struct igb_q_vector {
struct igb_adapter *adapter; /* backlink */
struct igb_ring *rx_ring;
struct igb_ring *tx_ring;
struct napi_struct napi;
u32 eims_value;
u16 cpu;
u16 itr_val;
u8 set_itr;
void __iomem *itr_register;
#ifdef IGB_LRO
struct igb_lro_list *lrolist; /* LRO list for queue vector*/
#endif
char name[IFNAMSIZ + 9];
#ifndef HAVE_NETDEV_NAPI_LIST
struct net_device poll_dev;
#endif
struct igb_ring_container {
struct igb_ring *ring; /* pointer to linked list of rings */
unsigned int total_bytes; /* total bytes processed this int */
unsigned int total_packets; /* total packets processed this int */
u16 work_limit; /* total work allowed per interrupt */
u8 count; /* total number of rings in vector */
u8 itr; /* current ITR setting for ring */
};
struct igb_ring {
struct igb_q_vector *q_vector; /* backlink to q_vector */
struct net_device *netdev; /* back pointer to net_device */
struct pci_dev *pdev; /* pci device for dma mapping */
dma_addr_t dma; /* phys address of the ring */
struct device *dev; /* device for dma mapping */
union { /* array of buffer info structs */
struct igb_tx_buffer *tx_buffer_info;
struct igb_rx_buffer *rx_buffer_info;
};
#ifdef HAVE_PTP_1588_CLOCK
unsigned long last_rx_timestamp;
#endif /* HAVE_PTP_1588_CLOCK */
void *desc; /* descriptor ring memory */
unsigned long flags; /* ring specific flags */
void __iomem *tail; /* pointer to ring tail register */
dma_addr_t dma; /* phys address of the ring */
unsigned int size; /* length of desc. ring in bytes */
u16 count; /* number of desc. in the ring */
u16 next_to_use;
u8 queue_index; /* logical index of the ring*/
u8 reg_idx; /* physical index of the ring */
/* everything past this point are written often */
u16 next_to_clean;
u8 queue_index;
u8 reg_idx;
void __iomem *head;
void __iomem *tail;
struct igb_buffer *buffer_info; /* array of buffer info structs */
unsigned int total_bytes;
unsigned int total_packets;
u32 flags;
u16 next_to_use;
u16 next_to_alloc;
union {
/* TX */
struct {
struct igb_tx_queue_stats tx_stats;
bool detect_tx_hung;
};
/* RX */
struct {
struct igb_rx_queue_stats rx_stats;
u32 rx_buffer_len;
#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
u16 rx_buffer_len;
#else
struct sk_buff *skb;
#endif
#ifdef __VMKNETDDI_QUEUEOPS__
u8 mac_addr[NODE_ADDRESS_SIZE];
u8 active;
@ -333,89 +350,180 @@ struct igb_ring {
#endif
};
};
#ifdef CONFIG_IGB_VMDQ_NETDEV
struct net_device *vmdq_netdev;
int vqueue_index; /* queue index for virtual netdev */
#endif
} ____cacheline_internodealigned_in_smp;
struct igb_q_vector {
struct igb_adapter *adapter; /* backlink */
int cpu; /* CPU for DCA */
u32 eims_value; /* EIMS mask value */
u16 itr_val;
u8 set_itr;
void __iomem *itr_register;
struct igb_ring_container rx, tx;
struct napi_struct napi;
char name[IFNAMSIZ + 9];
#ifndef HAVE_NETDEV_NAPI_LIST
struct net_device poll_dev;
#endif
/* for dynamic allocation of rings associated with this q_vector */
struct igb_ring ring[0] ____cacheline_internodealigned_in_smp;
};
#define IGB_RING_FLAG_RX_CSUM 0x00000001 /* RX CSUM enabled */
#define IGB_RING_FLAG_RX_SCTP_CSUM 0x00000002 /* SCTP CSUM offload enabled */
#ifdef IGB_LRO
#define IGB_RING_FLAG_RX_LRO 0x00000004 /* LRO enabled */
#endif /* IGB_LRO */
enum e1000_ring_flags_t {
#ifndef HAVE_NDO_SET_FEATURES
IGB_RING_FLAG_RX_CSUM,
#endif
IGB_RING_FLAG_RX_SCTP_CSUM,
IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
IGB_RING_FLAG_TX_CTX_IDX,
IGB_RING_FLAG_TX_DETECT_HANG,
};
#define IGB_RING_FLAG_TX_CTX_IDX 0x00000001 /* HW requires context index */
struct igb_mac_addr {
u8 addr[ETH_ALEN];
u16 queue;
u16 state; /* bitmask */
};
#define IGB_MAC_STATE_DEFAULT 0x1
#define IGB_MAC_STATE_MODIFIED 0x2
#define IGB_MAC_STATE_IN_USE 0x4
#define IGB_ADVTXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS)
#define IGB_TXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS)
#define E1000_RX_DESC_ADV(R, i) \
(&(((union e1000_adv_rx_desc *)((R).desc))[i]))
#define E1000_TX_DESC_ADV(R, i) \
(&(((union e1000_adv_tx_desc *)((R).desc))[i]))
#define E1000_TX_CTXTDESC_ADV(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
#define IGB_RX_DESC(R, i) \
(&(((union e1000_adv_rx_desc *)((R)->desc))[i]))
#define IGB_TX_DESC(R, i) \
(&(((union e1000_adv_tx_desc *)((R)->desc))[i]))
#define IGB_TX_CTXTDESC(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R)->desc))[i]))
#ifdef CONFIG_IGB_VMDQ_NETDEV
#define netdev_ring(ring) \
((ring->vmdq_netdev ? ring->vmdq_netdev : ring->netdev))
#define ring_queue_index(ring) \
((ring->vmdq_netdev ? ring->vqueue_index : ring->queue_index))
#else
#define netdev_ring(ring) (ring->netdev)
#define ring_queue_index(ring) (ring->queue_index)
#endif /* CONFIG_IGB_VMDQ_NETDEV */
/* igb_test_staterr - tests bits within Rx descriptor status and error fields */
static inline __le32 igb_test_staterr(union e1000_adv_rx_desc *rx_desc,
const u32 stat_err_bits)
{
return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits);
}
/* igb_desc_unused - calculate if we have unused descriptors */
static inline int igb_desc_unused(struct igb_ring *ring)
static inline u16 igb_desc_unused(const struct igb_ring *ring)
{
if (ring->next_to_clean > ring->next_to_use)
return ring->next_to_clean - ring->next_to_use - 1;
u16 ntc = ring->next_to_clean;
u16 ntu = ring->next_to_use;
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
}
#ifdef CONFIG_BQL
static inline struct netdev_queue *txring_txq(const struct igb_ring *tx_ring)
{
return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
}
#endif /* CONFIG_BQL */
// #ifdef EXT_THERMAL_SENSOR_SUPPORT
// #ifdef IGB_PROCFS
struct igb_therm_proc_data
{
struct e1000_hw *hw;
struct e1000_thermal_diode_data *sensor_data;
};
// #endif /* IGB_PROCFS */
// #endif /* EXT_THERMAL_SENSOR_SUPPORT */
#ifdef IGB_HWMON
#define IGB_HWMON_TYPE_LOC 0
#define IGB_HWMON_TYPE_TEMP 1
#define IGB_HWMON_TYPE_CAUTION 2
#define IGB_HWMON_TYPE_MAX 3
struct hwmon_attr {
struct device_attribute dev_attr;
struct e1000_hw *hw;
struct e1000_thermal_diode_data *sensor;
char name[12];
};
struct hwmon_buff {
struct device *device;
struct hwmon_attr *hwmon_list;
unsigned int n_hwmon;
};
#endif /* IGB_HWMON */
/* board specific private data structure */
struct igb_adapter {
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
#ifdef HAVE_VLAN_RX_REGISTER
/* vlgrp must be first member of structure */
struct vlan_group *vlgrp;
#else
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
#endif
struct net_device *netdev;
unsigned long state;
unsigned int flags;
unsigned int num_q_vectors;
struct msix_entry *msix_entries;
/* TX */
u16 tx_work_limit;
u32 tx_timeout_count;
int num_tx_queues;
struct igb_ring *tx_ring[IGB_MAX_TX_QUEUES];
/* RX */
int num_rx_queues;
struct igb_ring *rx_ring[IGB_MAX_RX_QUEUES];
struct timer_list watchdog_timer;
struct timer_list dma_err_timer;
struct timer_list phy_info_timer;
u16 mng_vlan_id;
u32 bd_number;
u32 wol;
u32 en_mng_pt;
u16 link_speed;
u16 link_duplex;
u8 port_num;
/* Interrupt Throttle Rate */
u32 rx_itr_setting;
u32 tx_itr_setting;
u16 tx_itr;
u16 rx_itr;
struct work_struct reset_task;
struct work_struct watchdog_task;
struct work_struct dma_err_task;
bool fc_autoneg;
u8 tx_timeout_factor;
#ifdef ETHTOOL_PHYS_ID
struct timer_list blink_timer;
unsigned long led_status;
#endif
/* TX */
struct igb_ring *tx_ring[IGB_MAX_TX_QUEUES];
unsigned long tx_queue_len;
u32 tx_timeout_count;
/* RX */
struct igb_ring *rx_ring[IGB_MAX_RX_QUEUES];
int num_tx_queues;
int num_rx_queues;
u32 max_frame_size;
u32 min_frame_size;
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
struct net_device_stats net_stats;
#endif
#ifdef IGB_LRO
struct igb_lro_stats lro_stats;
#endif
#ifdef SIOCSHWTSTAMP
struct cyclecounter cycles;
struct timecounter clock;
struct timecompare compare;
struct hwtstamp_config hwtstamp_config;
#endif
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
@ -431,51 +539,170 @@ struct igb_adapter {
int msg_enable;
unsigned int num_q_vectors;
struct igb_q_vector *q_vector[MAX_Q_VECTORS];
struct msix_entry *msix_entries;
u32 eims_enable_mask;
u32 eims_other;
/* to not mess up cache alignment, always add to the bottom */
unsigned long state;
unsigned int flags;
u32 eeprom_wol;
u32 *config_space;
#ifdef HAVE_TX_MQ
struct igb_ring *multi_tx_table[IGB_MAX_TX_QUEUES];
#endif /* HAVE_TX_MQ */
u16 tx_ring_count;
u16 rx_ring_count;
#ifdef __VMKNETDDI_QUEUEOPS__
u32 n_rx_queues_allocated;
u32 n_tx_queues_allocated;
/* A place to salt away the RAR table before resetting the adapter
* during change MTU
*/
#endif
struct vf_data_storage *vf_data;
#ifdef IFLA_VF_MAX
int vf_rate_link_speed;
#endif
u32 lli_port;
u32 lli_size;
unsigned int vfs_allocated_count;
/* Malicious Driver Detection flag. Valid only when SR-IOV is enabled */
bool mdd;
int int_mode;
u32 rss_queues;
u32 vmdq_pools;
u16 fw_version;
char fw_version[32];
u32 wvbr;
struct igb_mac_addr *mac_table;
#ifdef CONFIG_IGB_VMDQ_NETDEV
struct net_device *vmdq_netdev[IGB_MAX_VMDQ_QUEUES];
#endif
int vferr_refcount;
int dmac;
u32 *shadow_vfta;
/* External Thermal Sensor support flag */
bool ets;
#ifdef IGB_HWMON
struct hwmon_buff igb_hwmon_buff;
#else /* IGB_HWMON */
struct proc_dir_entry *eth_dir;
struct proc_dir_entry *info_dir;
struct proc_dir_entry *therm_dir[E1000_MAX_SENSORS];
struct igb_therm_proc_data therm_data[E1000_MAX_SENSORS];
bool old_lsc;
#endif /* IGB_HWMON */
u32 etrack_id;
#ifdef __VMKLNX__
u16 SmbTblLen;
u32 SmbTblAddr;
#endif /* __VMKLNX__ */
#ifdef HAVE_PTP_1588_CLOCK
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
struct delayed_work ptp_overflow_work;
struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb;
unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check;
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
u32 tx_hwtstamp_timeouts;
u32 rx_hwtstamp_cleared;
#endif /* HAVE_PTP_1588_CLOCK */
unsigned long link_check_timeout;
int devrc;
u16 eee_advert;
};
#ifdef CONFIG_IGB_VMDQ_NETDEV
struct igb_vmdq_adapter {
#ifdef HAVE_VLAN_RX_REGISTER
/* vlgrp must be first member of structure */
struct vlan_group *vlgrp;
#else
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
#endif
struct igb_adapter *real_adapter;
struct net_device *vnetdev;
struct net_device_stats net_stats;
struct igb_ring *tx_ring;
struct igb_ring *rx_ring;
};
#endif
#define IGB_FLAG_HAS_MSI (1 << 0)
#define IGB_FLAG_MSI_ENABLE (1 << 1)
#define IGB_FLAG_DCA_ENABLED (1 << 3)
#define IGB_FLAG_LLI_PUSH (1 << 4)
#define IGB_FLAG_QUAD_PORT_A (1 << 5)
#define IGB_FLAG_QUEUE_PAIRS (1 << 6)
#define IGB_FLAG_DCA_ENABLED (1 << 1)
#define IGB_FLAG_LLI_PUSH (1 << 2)
#define IGB_FLAG_QUAD_PORT_A (1 << 3)
#define IGB_FLAG_QUEUE_PAIRS (1 << 4)
#define IGB_FLAG_EEE (1 << 5)
#define IGB_FLAG_DMAC (1 << 6)
#define IGB_FLAG_DETECT_BAD_DMA (1 << 7)
#define IGB_FLAG_PTP (1 << 8)
#define IGB_FLAG_RSS_FIELD_IPV4_UDP (1 << 9)
#define IGB_FLAG_RSS_FIELD_IPV6_UDP (1 << 10)
#define IGB_FLAG_WOL_SUPPORTED (1 << 11)
#define IGB_FLAG_NEED_LINK_UPDATE (1 << 12)
#define IGB_FLAG_LOOPBACK_ENABLE (1 << 13)
#define IGB_FLAG_MEDIA_RESET (1 << 14)
#define IGB_MIN_TXPBSIZE 20408
#define IGB_TX_BUF_4096 4096
#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coal Flush */
/* DMA Coalescing defines */
#define IGB_DMAC_DISABLE 0
#define IGB_DMAC_MIN 250
#define IGB_DMAC_500 500
#define IGB_DMAC_EN_DEFAULT 1000
#define IGB_DMAC_2000 2000
#define IGB_DMAC_3000 3000
#define IGB_DMAC_4000 4000
#define IGB_DMAC_5000 5000
#define IGB_DMAC_6000 6000
#define IGB_DMAC_7000 7000
#define IGB_DMAC_8000 8000
#define IGB_DMAC_9000 9000
#define IGB_DMAC_MAX 10000
#define IGB_82576_TSYNC_SHIFT 19
#define IGB_82580_TSYNC_SHIFT 24
#define IGB_TS_HDR_LEN 16
/* CEM Support */
#define FW_HDR_LEN 0x4
#define FW_CMD_DRV_INFO 0xDD
#define FW_CMD_DRV_INFO_LEN 0x5
#define FW_CMD_RESERVED 0X0
#define FW_RESP_SUCCESS 0x1
#define FW_UNUSED_VER 0x0
#define FW_MAX_RETRIES 3
#define FW_STATUS_SUCCESS 0x1
#define FW_FAMILY_DRV_VER 0Xffffffff
#define IGB_MAX_LINK_TRIES 20
struct e1000_fw_hdr {
u8 cmd;
u8 buf_len;
union
{
u8 cmd_resv;
u8 ret_status;
} cmd_or_resp;
u8 checksum;
};
#pragma pack(push,1)
struct e1000_fw_drv_info {
struct e1000_fw_hdr hdr;
u8 port_num;
u32 drv_version;
u16 pad; /* end spacing to ensure length is mult. of dword */
u8 pad2; /* end spacing to ensure length is mult. of dword2 */
};
#pragma pack(pop)
enum e1000_state_t {
__IGB_TESTING,
__IGB_RESETTING,
@ -498,17 +725,139 @@ extern void igb_configure_tx_ring(struct igb_adapter *, struct igb_ring *);
extern void igb_configure_rx_ring(struct igb_adapter *, struct igb_ring *);
extern void igb_setup_tctl(struct igb_adapter *);
extern void igb_setup_rctl(struct igb_adapter *);
extern netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *, struct igb_ring *);
extern netdev_tx_t igb_xmit_frame_ring(struct sk_buff *, struct igb_ring *);
extern void igb_unmap_and_free_tx_resource(struct igb_ring *,
struct igb_buffer *);
extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
struct igb_tx_buffer *);
extern void igb_alloc_rx_buffers(struct igb_ring *, u16);
extern void igb_clean_rx_ring(struct igb_ring *);
extern void igb_update_stats(struct igb_adapter *);
extern bool igb_has_link(struct igb_adapter *adapter);
extern void igb_set_ethtool_ops(struct net_device *);
extern void igb_check_options(struct igb_adapter *);
extern void igb_power_up_link(struct igb_adapter *);
#ifdef HAVE_PTP_1588_CLOCK
extern void igb_ptp_init(struct igb_adapter *adapter);
extern void igb_ptp_stop(struct igb_adapter *adapter);
extern void igb_ptp_reset(struct igb_adapter *adapter);
extern void igb_ptp_tx_work(struct work_struct *work);
extern void igb_ptp_rx_hang(struct igb_adapter *adapter);
extern void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter);
extern void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector,
struct sk_buff *skb);
extern void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
unsigned char *va,
struct sk_buff *skb);
static inline void igb_ptp_rx_hwtstamp(struct igb_ring *rx_ring,
union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb)
{
if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb);
skb_pull(skb, IGB_TS_HDR_LEN);
#endif
return;
}
if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TS))
igb_ptp_rx_rgtstamp(rx_ring->q_vector, skb);
/* Update the last_rx_timestamp timer in order to enable watchdog check
* for error case of latched timestamp on a dropped packet.
*/
rx_ring->last_rx_timestamp = jiffies;
}
extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
struct ifreq *ifr, int cmd);
#endif /* HAVE_PTP_1588_CLOCK */
#ifdef ETHTOOL_OPS_COMPAT
extern int ethtool_ioctl(struct ifreq *);
#endif
extern int igb_write_mc_addr_list(struct net_device *netdev);
extern int igb_add_mac_filter(struct igb_adapter *adapter, u8 *addr, u16 queue);
extern int igb_del_mac_filter(struct igb_adapter *adapter, u8* addr, u16 queue);
extern int igb_available_rars(struct igb_adapter *adapter);
extern s32 igb_vlvf_set(struct igb_adapter *, u32, bool, u32);
extern void igb_configure_vt_default_pool(struct igb_adapter *adapter);
extern void igb_enable_vlan_tags(struct igb_adapter *adapter);
#ifndef HAVE_VLAN_RX_REGISTER
extern void igb_vlan_mode(struct net_device *, u32);
#endif
#define E1000_PCS_CFG_IGN_SD 1
#ifdef IGB_HWMON
void igb_sysfs_exit(struct igb_adapter *adapter);
int igb_sysfs_init(struct igb_adapter *adapter);
#else
int igb_procfs_init(struct igb_adapter* adapter);
void igb_procfs_exit(struct igb_adapter* adapter);
int igb_procfs_topdir_init(void);
void igb_procfs_topdir_exit(void);
#endif /* IGB_HWMON */
/* ESX igb CIM IOCTL definition */
#define SIOCINTELCIM 0x89F8
#define INTELCIM_ENUMDIAGS 0x01 /* enumerate diagnostics */
#define INTELCIM_RUNDIAG 0x02 /* run diagnostics */
#define INTELCIM_FNDSMB 0x03 /* Find SMBIOS entry and size */
#define INTELCIM_GETSMBTBL 0x04 /* get SMBIOS tables */
#define INTELCIM_WRITEMEM 0x05 /* write data from user space to memory */
#define INTELCIM_READMEM 0x06 /* read data from memory to user space */
#define INTELCIM_GET_PCIE_ERROR_INFO 0x07
#define INTELCIM_GET_PCI_LINK_STATUS 0x08
#define SM_ADDR_HIGH 0x000FFFFF
#define SM_ADDR_LOW 0x000F0000
static const unsigned char sm_anchor[4] = "_SM_";
struct smbios_table {
u8 AnchorString[4];
u8 EntryPointChecksum;
u8 EntryPointLength;
u8 SmMajorVersion;
u8 SmMinorVersion;
u16 MaxStructureSize;
u8 EntryPointRevision;
u8 FormattedArea[5];
u8 IntermediateAnchorString[5];
u8 IntermediateChecksum;
u16 TableLength;
u32 TableAddress;
u16 NumberSmStructures;
u8 SmBcdRevision;
} __attribute__((__packed__));
struct intelcim_mem_buf {
u64 addr;
u32 len; /* Length in bytes */
u8 data[0];
} __attribute__((__packed__));
struct intelcim_pcie_error_info
{
u32 num_regs; /* Number of dwords */
u32 data[0];
} __attribute__((__packed__));
struct igb_intelcim_ioctl_req {
u32 cmd;
union {
struct ethtool_gstrings gstrings;
struct ethtool_test test;
struct smbios_table tbl;
u8 smbios[0];
struct intelcim_mem_buf buf;
struct intelcim_pcie_error_info info;
u16 link_status;
} cmd_req;
} __attribute__((packed));
int igb_intelcim_ioctl(struct net_device *netdev, struct ifreq *ifr);
#endif /* _IGB_H_ */

View file

@ -0,0 +1,29 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include "igb.h"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,242 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include "igb.h"
#include "e1000_82575.h"
#include "e1000_hw.h"
#ifdef IGB_HWMON
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sysfs.h>
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/hwmon.h>
#include <linux/pci.h>
/* hwmon callback functions */
static ssize_t igb_hwmon_show_location(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
return sprintf(buf, "loc%u\n",
igb_attr->sensor->location);
}
static ssize_t igb_hwmon_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value;
/* reset the temp field */
igb_attr->hw->mac.ops.get_thermal_sensor_data(igb_attr->hw);
value = igb_attr->sensor->temp;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
static ssize_t igb_hwmon_show_cautionthresh(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value = igb_attr->sensor->caution_thresh;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
static ssize_t igb_hwmon_show_maxopthresh(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hwmon_attr *igb_attr = container_of(attr, struct hwmon_attr,
dev_attr);
unsigned int value = igb_attr->sensor->max_op_thresh;
/* display millidegree */
value *= 1000;
return sprintf(buf, "%u\n", value);
}
/* igb_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file.
* @ adapter: pointer to the adapter structure
* @ offset: offset in the eeprom sensor data table
* @ type: type of sensor data to display
*
* For each file we want in hwmon's sysfs interface we need a device_attribute
* This is included in our hwmon_attr struct that contains the references to
* the data structures we need to get the data to display.
*/
static int igb_add_hwmon_attr(struct igb_adapter *adapter,
unsigned int offset, int type) {
int rc;
unsigned int n_attr;
struct hwmon_attr *igb_attr;
n_attr = adapter->igb_hwmon_buff.n_hwmon;
igb_attr = &adapter->igb_hwmon_buff.hwmon_list[n_attr];
switch (type) {
case IGB_HWMON_TYPE_LOC:
igb_attr->dev_attr.show = igb_hwmon_show_location;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_label", offset);
break;
case IGB_HWMON_TYPE_TEMP:
igb_attr->dev_attr.show = igb_hwmon_show_temp;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_input", offset);
break;
case IGB_HWMON_TYPE_CAUTION:
igb_attr->dev_attr.show = igb_hwmon_show_cautionthresh;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_max", offset);
break;
case IGB_HWMON_TYPE_MAX:
igb_attr->dev_attr.show = igb_hwmon_show_maxopthresh;
snprintf(igb_attr->name, sizeof(igb_attr->name),
"temp%u_crit", offset);
break;
default:
rc = -EPERM;
return rc;
}
/* These always the same regardless of type */
igb_attr->sensor =
&adapter->hw.mac.thermal_sensor_data.sensor[offset];
igb_attr->hw = &adapter->hw;
igb_attr->dev_attr.store = NULL;
igb_attr->dev_attr.attr.mode = S_IRUGO;
igb_attr->dev_attr.attr.name = igb_attr->name;
sysfs_attr_init(&igb_attr->dev_attr.attr);
rc = device_create_file(&adapter->pdev->dev,
&igb_attr->dev_attr);
if (rc == 0)
++adapter->igb_hwmon_buff.n_hwmon;
return rc;
}
static void igb_sysfs_del_adapter(struct igb_adapter *adapter)
{
int i;
if (adapter == NULL)
return;
for (i = 0; i < adapter->igb_hwmon_buff.n_hwmon; i++) {
device_remove_file(&adapter->pdev->dev,
&adapter->igb_hwmon_buff.hwmon_list[i].dev_attr);
}
kfree(adapter->igb_hwmon_buff.hwmon_list);
if (adapter->igb_hwmon_buff.device)
hwmon_device_unregister(adapter->igb_hwmon_buff.device);
}
/* called from igb_main.c */
void igb_sysfs_exit(struct igb_adapter *adapter)
{
igb_sysfs_del_adapter(adapter);
}
/* called from igb_main.c */
int igb_sysfs_init(struct igb_adapter *adapter)
{
struct hwmon_buff *igb_hwmon = &adapter->igb_hwmon_buff;
unsigned int i;
int n_attrs;
int rc = 0;
/* If this method isn't defined we don't support thermals */
if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL)
goto exit;
/* Don't create thermal hwmon interface if no sensors present */
rc = (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw));
if (rc)
goto exit;
/* Allocation space for max attributes
* max num sensors * values (loc, temp, max, caution)
*/
n_attrs = E1000_MAX_SENSORS * 4;
igb_hwmon->hwmon_list = kcalloc(n_attrs, sizeof(struct hwmon_attr),
GFP_KERNEL);
if (!igb_hwmon->hwmon_list) {
rc = -ENOMEM;
goto err;
}
igb_hwmon->device = hwmon_device_register(&adapter->pdev->dev);
if (IS_ERR(igb_hwmon->device)) {
rc = PTR_ERR(igb_hwmon->device);
goto err;
}
for (i = 0; i < E1000_MAX_SENSORS; i++) {
/* Only create hwmon sysfs entries for sensors that have
* meaningful data.
*/
if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0)
continue;
/* Bail if any hwmon attr struct fails to initialize */
rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_CAUTION);
rc |= igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_LOC);
rc |= igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_TEMP);
rc |= igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_MAX);
if (rc)
goto err;
}
goto exit;
err:
igb_sysfs_del_adapter(adapter);
exit:
return rc;
}
#endif /* IGB_HWMON */

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -39,6 +39,7 @@
#define OPTION_UNSET -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED 1
#define MAX_NUM_LIST_OPTS 15
/* All parameters are treated the same, as an integer array of values.
* This macro just reduces the need to repeat the same declaration code
@ -58,12 +59,12 @@
*/
#define IGB_PARAM(X, desc) \
static const int __devinitdata X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \
static const int X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \
MODULE_PARM(X, "1-" __MODULE_STRING(IGB_MAX_NIC) "i"); \
MODULE_PARM_DESC(X, desc);
#else
#define IGB_PARAM(X, desc) \
static int __devinitdata X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \
static int X[IGB_MAX_NIC+1] = IGB_PARAM_INIT; \
static unsigned int num_##X; \
module_param_array_named(X, X, int, &num_##X, 0); \
MODULE_PARM_DESC(X, desc);
@ -77,7 +78,8 @@ IGB_PARAM(InterruptThrottleRate,
"Maximum interrupts per second, per vector, (max 100000), default 3=adaptive");
#define DEFAULT_ITR 3
#define MAX_ITR 100000
#define MIN_ITR 120
/* #define MIN_ITR 120 */
#define MIN_ITR 0
/* IntMode (Interrupt Mode)
*
* Valid Range: 0 - 2
@ -88,6 +90,8 @@ IGB_PARAM(IntMode, "Change Interrupt Mode (0=Legacy, 1=MSI, 2=MSI-X), default 2"
#define MAX_INTMODE IGB_INT_MODE_MSIX
#define MIN_INTMODE IGB_INT_MODE_LEGACY
IGB_PARAM(Node, "set the starting node to allocate memory on, default -1");
/* LLIPort (Low Latency Interrupt TCP Port)
*
* Valid Range: 0 - 65535
@ -124,17 +128,16 @@ IGB_PARAM(LLISize, "Low Latency Interrupt on Packet Size (0-1500), default 0=off
#define MAX_LLISIZE 1500
#define MIN_LLISIZE 0
/* RSS (Enable RSS multiqueue receive)
*
* Valid Range: 0 - 8
*
* Default Value: 1
*/
IGB_PARAM(RSS, "Number of Receive-Side Scaling Descriptor Queues (0-8), default 1=number of cpus");
IGB_PARAM(RSS, "Number of Receive-Side Scaling Descriptor Queues (0-8), default 1, 0=number of cpus");
#define DEFAULT_RSS 1
#define MAX_RSS ((adapter->hw.mac.type == e1000_82575) ? 4 : 8)
#define MAX_RSS 8
#define MIN_RSS 0
/* VMDQ (Enable VMDq multiqueue receive)
@ -143,12 +146,37 @@ IGB_PARAM(RSS, "Number of Receive-Side Scaling Descriptor Queues (0-8), default
*
* Default Value: 0
*/
IGB_PARAM(VMDQ, "Number of Virtual Machine Device Queues (0-8), default 0");
IGB_PARAM(VMDQ, "Number of Virtual Machine Device Queues: 0-1 = disable, 2-8 enable, default 0");
#define DEFAULT_VMDQ 0
#define MAX_VMDQ MAX_RSS
#define MIN_VMDQ 0
#ifndef __VMKLNX__
/* max_vfs (Enable SR-IOV VF devices)
*
* Valid Range: 0 - 7
*
* Default Value: 0
*/
IGB_PARAM(max_vfs, "Number of Virtual Functions: 0 = disable, 1-7 enable, default 0");
#define DEFAULT_SRIOV 0
#define MAX_SRIOV 7
#define MIN_SRIOV 0
#endif /* __VMKLNX__ */
/* MDD (Enable Malicious Driver Detection)
*
* Only available when SR-IOV is enabled - max_vfs is greater than 0
*
* Valid Range: 0, 1
*
* Default Value: 1
*/
IGB_PARAM(MDD, "Malicious Driver Detection (0/1), default 1 = enabled. "
"Only available when max_vfs is greater than 0");
/* QueuePairs (Enable TX/RX queue pairs for interrupt handling)
*
@ -156,12 +184,33 @@ IGB_PARAM(VMDQ, "Number of Virtual Machine Device Queues (0-8), default 0");
*
* Default Value: 1
*/
IGB_PARAM(QueuePairs, "Enable TX/RX queue pairs for interrupt handling (0,1), default 1=on");
IGB_PARAM(QueuePairs, "Enable Tx/Rx queue pairs for interrupt handling (0,1), default 1=on");
#define DEFAULT_QUEUE_PAIRS 1
#define MAX_QUEUE_PAIRS 1
#define MIN_QUEUE_PAIRS 0
/* Enable/disable EEE (a.k.a. IEEE802.3az)
*
* Valid Range: 0, 1
*
* Default Value: 1
*/
IGB_PARAM(EEE, "Enable/disable on parts that support the feature");
/* Enable/disable DMA Coalescing
*
* Valid Values: 0(off), 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000,
* 9000, 10000(msec), 250(usec), 500(usec)
*
* Default Value: 0
*/
IGB_PARAM(DMAC, "Disable or set latency for DMA Coalescing ((0=off, 1000-10000(msec), 250, 500 (usec))");
struct igb_opt_list {
int i;
char *str;
};
struct igb_option {
enum { enable_option, range_option, list_option } type;
const char *name;
@ -174,12 +223,12 @@ struct igb_option {
} r;
struct { /* list_option info */
int nr;
struct igb_opt_list { int i; char *str; } *p;
struct igb_opt_list *p;
} l;
} arg;
};
static int __devinit igb_validate_option(unsigned int *value,
static int igb_validate_option(unsigned int *value,
struct igb_option *opt,
struct igb_adapter *adapter)
{
@ -240,9 +289,10 @@ static int __devinit igb_validate_option(unsigned int *value,
* in a variable in the adapter structure.
**/
void __devinit igb_check_options(struct igb_adapter *adapter)
void igb_check_options(struct igb_adapter *adapter)
{
int bd = adapter->bd_number;
struct e1000_hw *hw = &adapter->hw;
if (bd >= IGB_MAX_NIC) {
DPRINTK(PROBE, NOTICE,
@ -272,6 +322,9 @@ void __devinit igb_check_options(struct igb_adapter *adapter)
case 0:
DPRINTK(PROBE, INFO, "%s turned off\n",
opt.name);
if (hw->mac.type >= e1000_i350)
adapter->dmac = IGB_DMAC_DISABLE;
adapter->rx_itr_setting = itr;
break;
case 1:
DPRINTK(PROBE, INFO, "%s set to dynamic mode\n",
@ -403,19 +456,58 @@ void __devinit igb_check_options(struct igb_adapter *adapter)
}
#endif
}
#ifndef __VMKLNX__
{ /* SRIOV - Enable SR-IOV VF devices */
struct igb_option opt = {
.type = range_option,
.name = "max_vfs - SR-IOV VF devices",
.err = "using default of " __MODULE_STRING(DEFAULT_SRIOV),
.def = DEFAULT_SRIOV,
.arg = { .r = { .min = MIN_SRIOV,
.max = MAX_SRIOV } }
};
#ifdef module_param_array
if (num_max_vfs > bd) {
#endif
adapter->vfs_allocated_count = max_vfs[bd];
igb_validate_option(&adapter->vfs_allocated_count, &opt, adapter);
#ifdef module_param_array
} else {
adapter->vfs_allocated_count = opt.def;
}
#endif
if (adapter->vfs_allocated_count) {
switch (hw->mac.type) {
case e1000_82575:
case e1000_82580:
case e1000_i210:
case e1000_i211:
case e1000_i354:
adapter->vfs_allocated_count = 0;
DPRINTK(PROBE, INFO, "SR-IOV option max_vfs not supported.\n");
default:
break;
}
}
}
#endif /* __VMKLNX__ */
{ /* VMDQ - Enable VMDq multiqueue receive */
struct igb_option opt = {
.type = range_option,
.name = "VMDQ - VMDq multiqueue receive count",
.name = "VMDQ - VMDq multiqueue queue count",
.err = "using default of " __MODULE_STRING(DEFAULT_VMDQ),
.def = DEFAULT_VMDQ,
.arg = { .r = { .min = MIN_VMDQ,
.max = (MAX_VMDQ - adapter->vfs_allocated_count) } }
};
if ((hw->mac.type != e1000_i210) ||
(hw->mac.type != e1000_i211)) {
#ifdef module_param_array
if (num_VMDQ > bd) {
#endif
adapter->vmdq_pools = VMDQ[bd];
adapter->vmdq_pools = (VMDQ[bd] == 1 ? 0 : VMDQ[bd]);
if (adapter->vfs_allocated_count && !adapter->vmdq_pools) {
DPRINTK(PROBE, INFO, "Enabling SR-IOV requires VMDq be set to at least 1\n");
adapter->vmdq_pools = 1;
@ -425,11 +517,26 @@ void __devinit igb_check_options(struct igb_adapter *adapter)
#ifdef module_param_array
} else {
if (!adapter->vfs_allocated_count)
adapter->vmdq_pools = opt.def;
adapter->vmdq_pools = (opt.def == 1 ? 0 : opt.def);
else
adapter->vmdq_pools = 1;
}
#endif
#ifdef CONFIG_IGB_VMDQ_NETDEV
if (hw->mac.type == e1000_82575 && adapter->vmdq_pools) {
DPRINTK(PROBE, INFO, "VMDq not supported on this part.\n");
adapter->vmdq_pools = 0;
}
#endif
if (adapter->vmdq_pools) {
DPRINTK(PROBE, INFO, "VMDq not supported on ESX-5.5\n");
adapter->vmdq_pools = 0;
}
} else {
DPRINTK(PROBE, INFO, "VMDq option is not supported.\n");
adapter->vmdq_pools = opt.def;
}
}
{ /* RSS - Enable RSS multiqueue receives */
struct igb_option opt = {
@ -441,22 +548,48 @@ void __devinit igb_check_options(struct igb_adapter *adapter)
.max = MAX_RSS } }
};
if (adapter->vmdq_pools) {
switch (adapter->hw.mac.type) {
#ifndef __VMKLNX__
case e1000_82576:
opt.arg.r.max = 2;
break;
switch (hw->mac.type) {
case e1000_82575:
#ifndef CONFIG_IGB_VMDQ_NETDEV
if (!!adapter->vmdq_pools) {
if (adapter->vmdq_pools <= 2) {
if (adapter->vmdq_pools == 2)
opt.arg.r.max = 3;
if (adapter->vmdq_pools <= 2)
} else {
opt.arg.r.max = 1;
}
} else {
opt.arg.r.max = 4;
}
#else
opt.arg.r.max = !!adapter->vmdq_pools ? 1 : 4;
#endif /* CONFIG_IGB_VMDQ_NETDEV */
break;
#endif
case e1000_i210:
opt.arg.r.max = 4;
break;
case e1000_i211:
opt.arg.r.max = 2;
break;
case e1000_82576:
#ifndef CONFIG_IGB_VMDQ_NETDEV
if (!!adapter->vmdq_pools)
opt.arg.r.max = 2;
break;
#endif /* CONFIG_IGB_VMDQ_NETDEV */
case e1000_82580:
case e1000_i350:
case e1000_i354:
default:
if (!!adapter->vmdq_pools)
opt.arg.r.max = 1;
break;
}
if (adapter->int_mode != IGB_INT_MODE_MSIX) {
DPRINTK(PROBE, INFO, "RSS is not supported when in MSI/Legacy Interrupt mode, %s\n",
opt.err);
opt.arg.r.max = 1;
}
#ifdef module_param_array
@ -480,42 +613,195 @@ void __devinit igb_check_options(struct igb_adapter *adapter)
}
#endif
}
{ /* QueuePairs - Enable TX/RX queue pairs for interrupt handling */
{ /* QueuePairs - Enable Tx/Rx queue pairs for interrupt handling */
struct igb_option opt = {
.type = enable_option,
.name = "QueuePairs - TX/RX queue pairs for interrupt handling",
.name = "QueuePairs - Tx/Rx queue pairs for interrupt handling",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
#ifdef module_param_array
if (num_QueuePairs > bd) {
#endif
unsigned int qp = QueuePairs[bd];
/*
* we must enable queue pairs if the number of queues
* exceeds the number of avaialble interrupts. We are
* limited to 10, or 3 per unallocated vf.
* We must enable queue pairs if the number of queues
* exceeds the number of available interrupts. We are
* limited to 10, or 3 per unallocated vf. On I210 and
* I211 devices, we are limited to 5 interrupts.
* However, since I211 only supports 2 queues, we do not
* need to check and override the user option.
*/
if ((adapter->rss_queues > 4) ||
(adapter->vmdq_pools > 4) ||
((adapter->rss_queues > 1) &&
((adapter->vmdq_pools > 3) ||
(adapter->vfs_allocated_count > 6)))) {
if (qp == OPTION_DISABLED) {
if (adapter->rss_queues > 4)
qp = OPTION_ENABLED;
DPRINTK(PROBE, INFO,
"Number of queues exceeds available interrupts, %s\n",opt.err);
}
if (adapter->vmdq_pools > 4)
qp = OPTION_ENABLED;
if (adapter->rss_queues > 1 &&
(adapter->vmdq_pools > 3 ||
adapter->vfs_allocated_count > 6))
qp = OPTION_ENABLED;
if (hw->mac.type == e1000_i210 &&
adapter->rss_queues > 2)
qp = OPTION_ENABLED;
if (qp == OPTION_ENABLED)
DPRINTK(PROBE, INFO, "Number of queues exceeds available interrupts, %s\n",
opt.err);
}
igb_validate_option(&qp, &opt, adapter);
adapter->flags |= qp ? IGB_FLAG_QUEUE_PAIRS : 0;
#ifdef module_param_array
} else {
adapter->flags |= opt.def ? IGB_FLAG_QUEUE_PAIRS : 0;
}
#endif
}
{ /* EEE - Enable EEE for capable adapters */
if (hw->mac.type >= e1000_i350) {
struct igb_option opt = {
.type = enable_option,
.name = "EEE Support",
.err = "defaulting to Enabled",
.def = OPTION_ENABLED
};
#ifdef module_param_array
if (num_EEE > bd) {
#endif
unsigned int eee = EEE[bd];
igb_validate_option(&eee, &opt, adapter);
adapter->flags |= eee ? IGB_FLAG_EEE : 0;
if (eee)
hw->dev_spec._82575.eee_disable = false;
else
hw->dev_spec._82575.eee_disable = true;
#ifdef module_param_array
} else {
adapter->flags |= opt.def ? IGB_FLAG_EEE : 0;
if (adapter->flags & IGB_FLAG_EEE)
hw->dev_spec._82575.eee_disable = false;
else
hw->dev_spec._82575.eee_disable = true;
}
#endif
}
}
{ /* DMAC - Enable DMA Coalescing for capable adapters */
if (hw->mac.type >= e1000_i350) {
struct igb_opt_list list [] = {
{ IGB_DMAC_DISABLE, "DMAC Disable"},
{ IGB_DMAC_MIN, "DMAC 250 usec"},
{ IGB_DMAC_500, "DMAC 500 usec"},
{ IGB_DMAC_EN_DEFAULT, "DMAC 1000 usec"},
{ IGB_DMAC_2000, "DMAC 2000 usec"},
{ IGB_DMAC_3000, "DMAC 3000 usec"},
{ IGB_DMAC_4000, "DMAC 4000 usec"},
{ IGB_DMAC_5000, "DMAC 5000 usec"},
{ IGB_DMAC_6000, "DMAC 6000 usec"},
{ IGB_DMAC_7000, "DMAC 7000 usec"},
{ IGB_DMAC_8000, "DMAC 8000 usec"},
{ IGB_DMAC_9000, "DMAC 9000 usec"},
{ IGB_DMAC_MAX, "DMAC 10000 usec"}
};
struct igb_option opt = {
.type = list_option,
.name = "DMA Coalescing",
.err = "using default of "__MODULE_STRING(IGB_DMAC_DISABLE),
.def = IGB_DMAC_DISABLE,
.arg = { .l = { .nr = 13,
.p = list
}
}
};
#ifdef module_param_array
if (num_DMAC > bd) {
#endif
unsigned int dmac = DMAC[bd];
if (adapter->rx_itr_setting == IGB_DMAC_DISABLE)
dmac = IGB_DMAC_DISABLE;
igb_validate_option(&dmac, &opt, adapter);
switch (dmac) {
case IGB_DMAC_DISABLE:
adapter->dmac = dmac;
break;
case IGB_DMAC_MIN:
adapter->dmac = dmac;
break;
case IGB_DMAC_500:
adapter->dmac = dmac;
break;
case IGB_DMAC_EN_DEFAULT:
adapter->dmac = dmac;
break;
case IGB_DMAC_2000:
adapter->dmac = dmac;
break;
case IGB_DMAC_3000:
adapter->dmac = dmac;
break;
case IGB_DMAC_4000:
adapter->dmac = dmac;
break;
case IGB_DMAC_5000:
adapter->dmac = dmac;
break;
case IGB_DMAC_6000:
adapter->dmac = dmac;
break;
case IGB_DMAC_7000:
adapter->dmac = dmac;
break;
case IGB_DMAC_8000:
adapter->dmac = dmac;
break;
case IGB_DMAC_9000:
adapter->dmac = dmac;
break;
case IGB_DMAC_MAX:
adapter->dmac = dmac;
break;
default:
adapter->dmac = opt.def;
DPRINTK(PROBE, INFO,
"Invalid DMAC setting, "
"resetting DMAC to %d\n", opt.def);
}
#ifdef module_param_array
} else
adapter->dmac = opt.def;
#endif
}
}
#ifndef __VMKLNX__
{ /* MDD - Enable Malicious Driver Detection. Only available when
SR-IOV is enabled. */
struct igb_option opt = {
.type = enable_option,
.name = "Malicious Driver Detection",
.err = "defaulting to 1",
.def = OPTION_ENABLED,
.arg = { .r = { .min = OPTION_DISABLED,
.max = OPTION_ENABLED } }
};
#ifdef module_param_array
if (num_MDD > bd) {
#endif
adapter->mdd = MDD[bd];
igb_validate_option((uint *)&adapter->mdd, &opt,
adapter);
#ifdef module_param_array
} else {
adapter->mdd = opt.def;
}
#endif
}
#endif /* __VMKLNX__ */
}

View file

@ -0,0 +1,962 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include "igb.h"
#include "e1000_82575.h"
#include "e1000_hw.h"
#ifndef IGB_HWMON
#include <linux/module.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/netdevice.h>
static struct proc_dir_entry *igb_top_dir = NULL;
#ifdef __VMKLNX__
static struct net_device_stats *procfs_get_stats(struct net_device *netdev)
{
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
struct igb_adapter *adapter;
#endif
if (netdev == NULL)
return NULL;
#ifdef HAVE_NETDEV_STATS_IN_NETDEV
/* only return the current stats */
return &netdev->stats;
#else
adapter = netdev_priv(netdev);
/* only return the current stats */
return &adapter->net_stats;
#endif /* HAVE_NETDEV_STATS_IN_NETDEV */
}
#endif /* __VMKLNX__ */
bool igb_thermal_present(struct igb_adapter *adapter)
{
s32 status;
struct e1000_hw *hw;
if (adapter == NULL)
return false;
hw = &adapter->hw;
/*
* Only set I2C bit-bang mode if an external thermal sensor is
* supported on this device.
*/
if (adapter->ets) {
status = e1000_set_i2c_bb(hw);
if (status != E1000_SUCCESS)
return false;
}
status = hw->mac.ops.init_thermal_sensor_thresh(hw);
if (status != E1000_SUCCESS)
return false;
return true;
}
#ifdef __VMKLNX__
static int igb_fwbanner(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
return snprintf(page, count, "0x%08x\n", adapter->etrack_id);
}
static int igb_portspeed(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
int speed = 0;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
switch (adapter->link_speed) {
case E1000_STATUS_SPEED_10:
speed = 10;
break;
case E1000_STATUS_SPEED_100:
speed = 100;
break;
case E1000_STATUS_SPEED_1000:
speed = 1000;
break;
}
return snprintf(page, count, "%d\n", speed);
}
static int igb_wqlflag(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
return snprintf(page, count, "%d\n", adapter->wol);
}
static int igb_xflowctl(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "%d\n", hw->fc.current_mode);
}
static int igb_rxdrops(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n",
net_stats->rx_dropped);
}
static int igb_rxerrors(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n", net_stats->rx_errors);
}
static int igb_rxupacks(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "%d\n", E1000_READ_REG(hw, E1000_TPR));
}
static int igb_rxmpacks(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "%d\n",
E1000_READ_REG(hw, E1000_MPRC));
}
static int igb_rxbpacks(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "%d\n",
E1000_READ_REG(hw, E1000_BPRC));
}
static int igb_txupacks(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "%d\n", E1000_READ_REG(hw, E1000_TPT));
}
static int igb_txmpacks(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "%d\n",
E1000_READ_REG(hw, E1000_MPTC));
}
static int igb_txbpacks(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "%d\n",
E1000_READ_REG(hw, E1000_BPTC));
}
static int igb_txerrors(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n",
net_stats->tx_errors);
}
static int igb_txdrops(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n",
net_stats->tx_dropped);
}
static int igb_rxframes(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n",
net_stats->rx_packets);
}
static int igb_rxbytes(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n",
net_stats->rx_bytes);
}
static int igb_txframes(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n",
net_stats->tx_packets);
}
static int igb_txbytes(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device_stats *net_stats;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
net_stats = procfs_get_stats(adapter->netdev);
if (net_stats == NULL)
return snprintf(page, count, "error: no net stats\n");
return snprintf(page, count, "%lu\n",
net_stats->tx_bytes);
}
static int igb_linkstat(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
int bitmask = 0;
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
if (!test_bit(__IGB_DOWN, &adapter->state))
bitmask |= 1;
if (igb_has_link(adapter))
bitmask |= 2;
if (adapter->old_lsc != hw->mac.get_link_status) {
bitmask |= 4;
adapter->old_lsc = hw->mac.get_link_status;
}
return snprintf(page, count, "0x%X\n", bitmask);
}
static int igb_funcid(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device* netdev;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
netdev = adapter->netdev;
if (netdev == NULL)
return snprintf(page, count, "error: no net device\n");
return snprintf(page, count, "0x%lX\n", netdev->base_addr);
}
static int igb_funcvers(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device* netdev;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
netdev = adapter->netdev;
if (netdev == NULL)
return snprintf(page, count, "error: no net device\n");
return snprintf(page, count, "%s\n", igb_driver_version);
}
static int igb_maclla1(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
u16 eeprom_buff[6];
int first_word = 0x37;
int word_count = 6;
int rc;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
rc = e1000_read_nvm(hw, first_word, word_count,
eeprom_buff);
if (rc != E1000_SUCCESS)
return 0;
switch (hw->bus.func) {
case 0:
return snprintf(page, count, "0x%04X%04X%04X\n",
eeprom_buff[0],
eeprom_buff[1],
eeprom_buff[2]);
case 1:
return snprintf(page, count, "0x%04X%04X%04X\n",
eeprom_buff[3],
eeprom_buff[4],
eeprom_buff[5]);
}
return snprintf(page, count, "unexpected port %d\n", hw->bus.func);
}
static int igb_mtusize(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device* netdev;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
netdev = adapter->netdev;
if (netdev == NULL)
return snprintf(page, count, "error: no net device\n");
return snprintf(page, count, "%d\n", netdev->mtu);
}
static int igb_featflag(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
int bitmask = 0;
#ifndef HAVE_NDO_SET_FEATURES
struct igb_ring *ring;
#endif
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device *netdev;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
netdev = adapter->netdev;
if (netdev == NULL)
return snprintf(page, count, "error: no net device\n");
#ifndef HAVE_NDO_SET_FEATURES
/* igb_get_rx_csum(netdev) doesn't compile so hard code */
ring = adapter->rx_ring[0];
bitmask = test_bit(IGB_RING_FLAG_RX_CSUM, &ring->flags);
return snprintf(page, count, "%d\n", bitmask);
#else
if (netdev->features & NETIF_F_RXCSUM)
bitmask |= 1;
return snprintf(page, count, "%d\n", bitmask);
#endif
}
static int igb_lsominct(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
return snprintf(page, count, "%d\n", 1);
}
static int igb_prommode(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
struct net_device *netdev;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
netdev = adapter->netdev;
if (netdev == NULL)
return snprintf(page, count, "error: no net device\n");
return snprintf(page, count, "%d\n",
netdev->flags & IFF_PROMISC);
}
static int igb_txdscqsz(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
return snprintf(page, count, "%d\n", adapter->tx_ring[0]->count);
}
static int igb_rxdscqsz(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
return snprintf(page, count, "%d\n", adapter->rx_ring[0]->count);
}
static int igb_rxqavg(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
int index;
int totaldiff = 0;
u16 ntc;
u16 ntu;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
if (adapter->num_rx_queues <= 0)
return snprintf(page, count,
"can't calculate, number of queues %d\n",
adapter->num_rx_queues);
for (index = 0; index < adapter->num_rx_queues; index++) {
ntc = adapter->rx_ring[index]->next_to_clean;
ntu = adapter->rx_ring[index]->next_to_use;
if (ntc >= ntu)
totaldiff += (ntc - ntu);
else
totaldiff += (adapter->rx_ring[index]->count
- ntu + ntc);
}
if (adapter->num_rx_queues <= 0)
return snprintf(page, count,
"can't calculate, number of queues %d\n",
adapter->num_rx_queues);
return snprintf(page, count, "%d\n", totaldiff/adapter->num_rx_queues);
}
static int igb_txqavg(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
int index;
int totaldiff = 0;
u16 ntc;
u16 ntu;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
if (adapter->num_tx_queues <= 0)
return snprintf(page, count,
"can't calculate, number of queues %d\n",
adapter->num_tx_queues);
for (index = 0; index < adapter->num_tx_queues; index++) {
ntc = adapter->tx_ring[index]->next_to_clean;
ntu = adapter->tx_ring[index]->next_to_use;
if (ntc >= ntu)
totaldiff += (ntc - ntu);
else
totaldiff += (adapter->tx_ring[index]->count
- ntu + ntc);
}
if (adapter->num_tx_queues <= 0)
return snprintf(page, count,
"can't calculate, number of queues %d\n",
adapter->num_tx_queues);
return snprintf(page, count, "%d\n",
totaldiff/adapter->num_tx_queues);
}
static int igb_iovotype(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
return snprintf(page, count, "2\n");
}
static int igb_funcnbr(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
return snprintf(page, count, "%d\n", adapter->vfs_allocated_count);
}
#endif /* __VMKLNX__ */
static int igb_macburn(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "0x%02X%02X%02X%02X%02X%02X\n",
(unsigned int)hw->mac.perm_addr[0],
(unsigned int)hw->mac.perm_addr[1],
(unsigned int)hw->mac.perm_addr[2],
(unsigned int)hw->mac.perm_addr[3],
(unsigned int)hw->mac.perm_addr[4],
(unsigned int)hw->mac.perm_addr[5]);
}
static int igb_macadmn(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct e1000_hw *hw;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
return snprintf(page, count, "0x%02X%02X%02X%02X%02X%02X\n",
(unsigned int)hw->mac.addr[0],
(unsigned int)hw->mac.addr[1],
(unsigned int)hw->mac.addr[2],
(unsigned int)hw->mac.addr[3],
(unsigned int)hw->mac.addr[4],
(unsigned int)hw->mac.addr[5]);
}
static int igb_numeports(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct e1000_hw *hw;
int ports;
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
hw = &adapter->hw;
if (hw == NULL)
return snprintf(page, count, "error: no hw data\n");
ports = 4;
return snprintf(page, count, "%d\n", ports);
}
static int igb_porttype(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct igb_adapter *adapter = (struct igb_adapter *)data;
if (adapter == NULL)
return snprintf(page, count, "error: no adapter\n");
return snprintf(page, count, "%d\n",
test_bit(__IGB_DOWN, &adapter->state));
}
static int igb_therm_location(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct igb_therm_proc_data *therm_data =
(struct igb_therm_proc_data *)data;
if (therm_data == NULL)
return snprintf(page, count, "error: no therm_data\n");
return snprintf(page, count, "%d\n", therm_data->sensor_data->location);
}
static int igb_therm_maxopthresh(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct igb_therm_proc_data *therm_data =
(struct igb_therm_proc_data *)data;
if (therm_data == NULL)
return snprintf(page, count, "error: no therm_data\n");
return snprintf(page, count, "%d\n",
therm_data->sensor_data->max_op_thresh);
}
static int igb_therm_cautionthresh(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct igb_therm_proc_data *therm_data =
(struct igb_therm_proc_data *)data;
if (therm_data == NULL)
return snprintf(page, count, "error: no therm_data\n");
return snprintf(page, count, "%d\n",
therm_data->sensor_data->caution_thresh);
}
static int igb_therm_temp(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
s32 status;
struct igb_therm_proc_data *therm_data =
(struct igb_therm_proc_data *)data;
if (therm_data == NULL)
return snprintf(page, count, "error: no therm_data\n");
status = e1000_get_thermal_sensor_data(therm_data->hw);
if (status != E1000_SUCCESS)
snprintf(page, count, "error: status %d returned\n", status);
return snprintf(page, count, "%d\n", therm_data->sensor_data->temp);
}
struct igb_proc_type{
char name[32];
int (*read)(char*, char**, off_t, int, int*, void*);
};
struct igb_proc_type igb_proc_entries[] = {
{"numeports", &igb_numeports},
{"porttype", &igb_porttype},
{"macburn", &igb_macburn},
{"macadmn", &igb_macadmn},
#ifdef __VMKLNX__
{"fwbanner", &igb_fwbanner},
{"portspeed", &igb_portspeed},
{"wqlflag", &igb_wqlflag},
{"xflowctl", &igb_xflowctl},
{"rxdrops", &igb_rxdrops},
{"rxerrors", &igb_rxerrors},
{"rxupacks", &igb_rxupacks},
{"rxmpacks", &igb_rxmpacks},
{"rxbpacks", &igb_rxbpacks},
{"txdrops", &igb_txdrops},
{"txerrors", &igb_txerrors},
{"txupacks", &igb_txupacks},
{"txmpacks", &igb_txmpacks},
{"txbpacks", &igb_txbpacks},
{"rxframes", &igb_rxframes},
{"rxbytes", &igb_rxbytes},
{"txframes", &igb_txframes},
{"txbytes", &igb_txbytes},
{"linkstat", &igb_linkstat},
{"funcid", &igb_funcid},
{"funcvers", &igb_funcvers},
{"maclla1", &igb_maclla1},
{"mtusize", &igb_mtusize},
{"featflag", &igb_featflag},
{"lsominct", &igb_lsominct},
{"prommode", &igb_prommode},
{"txdscqsz", &igb_txdscqsz},
{"rxdscqsz", &igb_rxdscqsz},
{"txqavg", &igb_txqavg},
{"rxqavg", &igb_rxqavg},
{"iovotype", &igb_iovotype},
{"funcnbr", &igb_funcnbr},
#endif /* __VMKLNX__ */
{"", NULL}
};
struct igb_proc_type igb_internal_entries[] = {
{"location", &igb_therm_location},
{"temp", &igb_therm_temp},
{"cautionthresh", &igb_therm_cautionthresh},
{"maxopthresh", &igb_therm_maxopthresh},
{"", NULL}
};
void igb_del_proc_entries(struct igb_adapter *adapter)
{
int index, i;
char buf[16]; /* much larger than the sensor number will ever be */
if (igb_top_dir == NULL)
return;
for (i = 0; i < E1000_MAX_SENSORS; i++) {
if (adapter->therm_dir[i] == NULL)
continue;
for (index = 0; ; index++) {
if (igb_internal_entries[index].read == NULL)
break;
remove_proc_entry(igb_internal_entries[index].name,
adapter->therm_dir[i]);
}
snprintf(buf, sizeof(buf), "sensor_%d", i);
remove_proc_entry(buf, adapter->info_dir);
}
if (adapter->info_dir != NULL) {
for (index = 0; ; index++) {
if (igb_proc_entries[index].read == NULL)
break;
remove_proc_entry(igb_proc_entries[index].name,
adapter->info_dir);
}
remove_proc_entry("info", adapter->eth_dir);
}
if (adapter->eth_dir != NULL)
remove_proc_entry(pci_name(adapter->pdev), igb_top_dir);
}
/* called from igb_main.c */
void igb_procfs_exit(struct igb_adapter *adapter)
{
igb_del_proc_entries(adapter);
}
int igb_procfs_topdir_init(void)
{
#ifdef __VMKLNX__
igb_top_dir = proc_mkdir("driver/igb", NULL);
#else
igb_top_dir = proc_mkdir("driver/igb", NULL);
#endif /* __VMKLNX__ */
if (igb_top_dir == NULL)
return (-ENOMEM);
return 0;
}
void igb_procfs_topdir_exit(void)
{
#ifdef __VMKLNX__
remove_proc_entry("driver/igb", NULL);
#else
remove_proc_entry("driver/igb", NULL);
#endif /* __VMKLNX__ */
}
/* called from igb_main.c */
int igb_procfs_init(struct igb_adapter *adapter)
{
int rc = 0;
int i;
int index;
char buf[16]; /* much larger than the sensor number will ever be */
adapter->eth_dir = NULL;
adapter->info_dir = NULL;
for (i = 0; i < E1000_MAX_SENSORS; i++)
adapter->therm_dir[i] = NULL;
if ( igb_top_dir == NULL ) {
rc = -ENOMEM;
goto fail;
}
adapter->eth_dir = proc_mkdir(pci_name(adapter->pdev), igb_top_dir);
if (adapter->eth_dir == NULL) {
rc = -ENOMEM;
goto fail;
}
adapter->info_dir = proc_mkdir("info", adapter->eth_dir);
if (adapter->info_dir == NULL) {
rc = -ENOMEM;
goto fail;
}
for (index = 0; ; index++) {
if (igb_proc_entries[index].read == NULL) {
break;
}
if (!(create_proc_read_entry(igb_proc_entries[index].name,
0444,
adapter->info_dir,
igb_proc_entries[index].read,
adapter))) {
rc = -ENOMEM;
goto fail;
}
}
if (igb_thermal_present(adapter) == false)
goto exit;
for (i = 0; i < E1000_MAX_SENSORS; i++) {
if (adapter->hw.mac.thermal_sensor_data.sensor[i].location== 0)
continue;
snprintf(buf, sizeof(buf), "sensor_%d", i);
adapter->therm_dir[i] = proc_mkdir(buf, adapter->info_dir);
if (adapter->therm_dir[i] == NULL) {
rc = -ENOMEM;
goto fail;
}
for (index = 0; ; index++) {
if (igb_internal_entries[index].read == NULL)
break;
/*
* therm_data struct contains pointer the read func
* will be needing
*/
adapter->therm_data[i].hw = &adapter->hw;
adapter->therm_data[i].sensor_data =
&adapter->hw.mac.thermal_sensor_data.sensor[i];
if (!(create_proc_read_entry(
igb_internal_entries[index].name,
0444,
adapter->therm_dir[i],
igb_internal_entries[index].read,
&adapter->therm_data[i]))) {
rc = -ENOMEM;
goto fail;
}
}
}
goto exit;
fail:
igb_del_proc_entries(adapter);
exit:
return rc;
}
#endif /* !IGB_HWMON */

View file

@ -0,0 +1,944 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
/******************************************************************************
Copyright(c) 2011 Richard Cochran <richardcochran@gmail.com> for some of the
82576 and 82580 code
******************************************************************************/
#include "igb.h"
#include <linux/module.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/ptp_classify.h>
#define INCVALUE_MASK 0x7fffffff
#define ISGN 0x80000000
/*
* The 82580 timesync updates the system timer every 8ns by 8ns,
* and this update value cannot be reprogrammed.
*
* Neither the 82576 nor the 82580 offer registers wide enough to hold
* nanoseconds time values for very long. For the 82580, SYSTIM always
* counts nanoseconds, but the upper 24 bits are not availible. The
* frequency is adjusted by changing the 32 bit fractional nanoseconds
* register, TIMINCA.
*
* For the 82576, the SYSTIM register time unit is affect by the
* choice of the 24 bit TININCA:IV (incvalue) field. Five bits of this
* field are needed to provide the nominal 16 nanosecond period,
* leaving 19 bits for fractional nanoseconds.
*
* We scale the NIC clock cycle by a large factor so that relatively
* small clock corrections can be added or subtracted at each clock
* tick. The drawbacks of a large factor are a) that the clock
* register overflows more quickly (not such a big deal) and b) that
* the increment per tick has to fit into 24 bits. As a result we
* need to use a shift of 19 so we can fit a value of 16 into the
* TIMINCA register.
*
*
* SYSTIMH SYSTIML
* +--------------+ +---+---+------+
* 82576 | 32 | | 8 | 5 | 19 |
* +--------------+ +---+---+------+
* \________ 45 bits _______/ fract
*
* +----------+---+ +--------------+
* 82580 | 24 | 8 | | 32 |
* +----------+---+ +--------------+
* reserved \______ 40 bits _____/
*
*
* The 45 bit 82576 SYSTIM overflows every
* 2^45 * 10^-9 / 3600 = 9.77 hours.
*
* The 40 bit 82580 SYSTIM overflows every
* 2^40 * 10^-9 / 60 = 18.3 minutes.
*/
#define IGB_SYSTIM_OVERFLOW_PERIOD (HZ * 60 * 9)
#define IGB_PTP_TX_TIMEOUT (HZ * 15)
#define INCPERIOD_82576 (1 << E1000_TIMINCA_16NS_SHIFT)
#define INCVALUE_82576_MASK ((1 << E1000_TIMINCA_16NS_SHIFT) - 1)
#define INCVALUE_82576 (16 << IGB_82576_TSYNC_SHIFT)
#define IGB_NBITS_82580 40
/*
* SYSTIM read access for the 82576
*/
static cycle_t igb_ptp_read_82576(const struct cyclecounter *cc)
{
struct igb_adapter *igb = container_of(cc, struct igb_adapter, cc);
struct e1000_hw *hw = &igb->hw;
u64 val;
u32 lo, hi;
lo = E1000_READ_REG(hw, E1000_SYSTIML);
hi = E1000_READ_REG(hw, E1000_SYSTIMH);
val = ((u64) hi) << 32;
val |= lo;
return val;
}
/*
* SYSTIM read access for the 82580
*/
static cycle_t igb_ptp_read_82580(const struct cyclecounter *cc)
{
struct igb_adapter *igb = container_of(cc, struct igb_adapter, cc);
struct e1000_hw *hw = &igb->hw;
u64 val;
u32 lo, hi;
/* The timestamp latches on lowest register read. For the 82580
* the lowest register is SYSTIMR instead of SYSTIML. However we only
* need to provide nanosecond resolution, so we just ignore it.
*/
E1000_READ_REG(hw, E1000_SYSTIMR);
lo = E1000_READ_REG(hw, E1000_SYSTIML);
hi = E1000_READ_REG(hw, E1000_SYSTIMH);
val = ((u64) hi) << 32;
val |= lo;
return val;
}
/*
* SYSTIM read access for I210/I211
*/
static void igb_ptp_read_i210(struct igb_adapter *adapter, struct timespec *ts)
{
struct e1000_hw *hw = &adapter->hw;
u32 sec, nsec;
/* The timestamp latches on lowest register read. For I210/I211, the
* lowest register is SYSTIMR. Since we only need to provide nanosecond
* resolution, we can ignore it.
*/
E1000_READ_REG(hw, E1000_SYSTIMR);
nsec = E1000_READ_REG(hw, E1000_SYSTIML);
sec = E1000_READ_REG(hw, E1000_SYSTIMH);
ts->tv_sec = sec;
ts->tv_nsec = nsec;
}
static void igb_ptp_write_i210(struct igb_adapter *adapter,
const struct timespec *ts)
{
struct e1000_hw *hw = &adapter->hw;
/*
* Writing the SYSTIMR register is not necessary as it only provides
* sub-nanosecond resolution.
*/
E1000_WRITE_REG(hw, E1000_SYSTIML, ts->tv_nsec);
E1000_WRITE_REG(hw, E1000_SYSTIMH, ts->tv_sec);
}
/**
* igb_ptp_systim_to_hwtstamp - convert system time value to hw timestamp
* @adapter: board private structure
* @hwtstamps: timestamp structure to update
* @systim: unsigned 64bit system time value.
*
* We need to convert the system time value stored in the RX/TXSTMP registers
* into a hwtstamp which can be used by the upper level timestamping functions.
*
* The 'tmreg_lock' spinlock is used to protect the consistency of the
* system time value. This is needed because reading the 64 bit time
* value involves reading two (or three) 32 bit registers. The first
* read latches the value. Ditto for writing.
*
* In addition, here have extended the system time with an overflow
* counter in software.
**/
static void igb_ptp_systim_to_hwtstamp(struct igb_adapter *adapter,
struct skb_shared_hwtstamps *hwtstamps,
u64 systim)
{
unsigned long flags;
u64 ns;
switch (adapter->hw.mac.type) {
case e1000_82576:
case e1000_82580:
case e1000_i350:
case e1000_i354:
spin_lock_irqsave(&adapter->tmreg_lock, flags);
ns = timecounter_cyc2time(&adapter->tc, systim);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
memset(hwtstamps, 0, sizeof(*hwtstamps));
hwtstamps->hwtstamp = ns_to_ktime(ns);
break;
case e1000_i210:
case e1000_i211:
memset(hwtstamps, 0, sizeof(*hwtstamps));
/* Upper 32 bits contain s, lower 32 bits contain ns. */
hwtstamps->hwtstamp = ktime_set(systim >> 32,
systim & 0xFFFFFFFF);
break;
default:
break;
}
}
/*
* PTP clock operations
*/
static int igb_ptp_adjfreq_82576(struct ptp_clock_info *ptp, s32 ppb)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
struct e1000_hw *hw = &igb->hw;
int neg_adj = 0;
u64 rate;
u32 incvalue;
if (ppb < 0) {
neg_adj = 1;
ppb = -ppb;
}
rate = ppb;
rate <<= 14;
rate = div_u64(rate, 1953125);
incvalue = 16 << IGB_82576_TSYNC_SHIFT;
if (neg_adj)
incvalue -= rate;
else
incvalue += rate;
E1000_WRITE_REG(hw, E1000_TIMINCA, INCPERIOD_82576 | (incvalue & INCVALUE_82576_MASK));
return 0;
}
static int igb_ptp_adjfreq_82580(struct ptp_clock_info *ptp, s32 ppb)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
struct e1000_hw *hw = &igb->hw;
int neg_adj = 0;
u64 rate;
u32 inca;
if (ppb < 0) {
neg_adj = 1;
ppb = -ppb;
}
rate = ppb;
rate <<= 26;
rate = div_u64(rate, 1953125);
/* At 2.5G speeds, the TIMINCA register on I354 updates the clock 2.5x
* as quickly. Account for this by dividing the adjustment by 2.5.
*/
if (hw->mac.type == e1000_i354) {
u32 status = E1000_READ_REG(hw, E1000_STATUS);
if ((status & E1000_STATUS_2P5_SKU) &&
!(status & E1000_STATUS_2P5_SKU_OVER)) {
rate <<= 1;
rate = div_u64(rate, 5);
}
}
inca = rate & INCVALUE_MASK;
if (neg_adj)
inca |= ISGN;
E1000_WRITE_REG(hw, E1000_TIMINCA, inca);
return 0;
}
static int igb_ptp_adjtime_82576(struct ptp_clock_info *ptp, s64 delta)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
unsigned long flags;
s64 now;
spin_lock_irqsave(&igb->tmreg_lock, flags);
now = timecounter_read(&igb->tc);
now += delta;
timecounter_init(&igb->tc, &igb->cc, now);
spin_unlock_irqrestore(&igb->tmreg_lock, flags);
return 0;
}
static int igb_ptp_adjtime_i210(struct ptp_clock_info *ptp, s64 delta)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
unsigned long flags;
struct timespec now, then = ns_to_timespec(delta);
spin_lock_irqsave(&igb->tmreg_lock, flags);
igb_ptp_read_i210(igb, &now);
now = timespec_add(now, then);
igb_ptp_write_i210(igb, (const struct timespec *)&now);
spin_unlock_irqrestore(&igb->tmreg_lock, flags);
return 0;
}
static int igb_ptp_gettime_82576(struct ptp_clock_info *ptp,
struct timespec *ts)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
unsigned long flags;
u64 ns;
u32 remainder;
spin_lock_irqsave(&igb->tmreg_lock, flags);
ns = timecounter_read(&igb->tc);
spin_unlock_irqrestore(&igb->tmreg_lock, flags);
ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
ts->tv_nsec = remainder;
return 0;
}
static int igb_ptp_gettime_i210(struct ptp_clock_info *ptp,
struct timespec *ts)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
unsigned long flags;
spin_lock_irqsave(&igb->tmreg_lock, flags);
igb_ptp_read_i210(igb, ts);
spin_unlock_irqrestore(&igb->tmreg_lock, flags);
return 0;
}
static int igb_ptp_settime_82576(struct ptp_clock_info *ptp,
const struct timespec *ts)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
unsigned long flags;
u64 ns;
ns = ts->tv_sec * 1000000000ULL;
ns += ts->tv_nsec;
spin_lock_irqsave(&igb->tmreg_lock, flags);
timecounter_init(&igb->tc, &igb->cc, ns);
spin_unlock_irqrestore(&igb->tmreg_lock, flags);
return 0;
}
static int igb_ptp_settime_i210(struct ptp_clock_info *ptp,
const struct timespec *ts)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
unsigned long flags;
spin_lock_irqsave(&igb->tmreg_lock, flags);
igb_ptp_write_i210(igb, ts);
spin_unlock_irqrestore(&igb->tmreg_lock, flags);
return 0;
}
static int igb_ptp_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
return -EOPNOTSUPP;
}
/**
* igb_ptp_tx_work
* @work: pointer to work struct
*
* This work function polls the TSYNCTXCTL valid bit to determine when a
* timestamp has been taken for the current stored skb.
*/
void igb_ptp_tx_work(struct work_struct *work)
{
struct igb_adapter *adapter = container_of(work, struct igb_adapter,
ptp_tx_work);
struct e1000_hw *hw = &adapter->hw;
u32 tsynctxctl;
if (!adapter->ptp_tx_skb)
return;
if (time_is_before_jiffies(adapter->ptp_tx_start +
IGB_PTP_TX_TIMEOUT)) {
dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL;
adapter->tx_hwtstamp_timeouts++;
dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang");
return;
}
tsynctxctl = E1000_READ_REG(hw, E1000_TSYNCTXCTL);
if (tsynctxctl & E1000_TSYNCTXCTL_VALID)
igb_ptp_tx_hwtstamp(adapter);
else
/* reschedule to check later */
schedule_work(&adapter->ptp_tx_work);
}
static void igb_ptp_overflow_check(struct work_struct *work)
{
struct igb_adapter *igb =
container_of(work, struct igb_adapter, ptp_overflow_work.work);
struct timespec ts;
igb->ptp_caps.gettime(&igb->ptp_caps, &ts);
pr_debug("igb overflow check at %ld.%09lu\n", ts.tv_sec, ts.tv_nsec);
schedule_delayed_work(&igb->ptp_overflow_work,
IGB_SYSTIM_OVERFLOW_PERIOD);
}
/**
* igb_ptp_rx_hang - detect error case when Rx timestamp registers latched
* @adapter: private network adapter structure
*
* This watchdog task is scheduled to detect error case where hardware has
* dropped an Rx packet that was timestamped when the ring is full. The
* particular error is rare but leaves the device in a state unable to timestamp
* any future packets.
*/
void igb_ptp_rx_hang(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
struct igb_ring *rx_ring;
u32 tsyncrxctl = E1000_READ_REG(hw, E1000_TSYNCRXCTL);
unsigned long rx_event;
int n;
if (hw->mac.type != e1000_82576)
return;
/* If we don't have a valid timestamp in the registers, just update the
* timeout counter and exit
*/
if (!(tsyncrxctl & E1000_TSYNCRXCTL_VALID)) {
adapter->last_rx_ptp_check = jiffies;
return;
}
/* Determine the most recent watchdog or rx_timestamp event */
rx_event = adapter->last_rx_ptp_check;
for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n];
if (time_after(rx_ring->last_rx_timestamp, rx_event))
rx_event = rx_ring->last_rx_timestamp;
}
/* Only need to read the high RXSTMP register to clear the lock */
if (time_is_before_jiffies(rx_event + 5 * HZ)) {
E1000_READ_REG(hw, E1000_RXSTMPH);
adapter->last_rx_ptp_check = jiffies;
adapter->rx_hwtstamp_cleared++;
dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang");
}
}
/**
* igb_ptp_tx_hwtstamp - utility function which checks for TX time stamp
* @adapter: Board private structure.
*
* If we were asked to do hardware stamping and such a time stamp is
* available, then it must have been for this skb here because we only
* allow only one such packet into the queue.
*/
void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
struct skb_shared_hwtstamps shhwtstamps;
u64 regval;
regval = E1000_READ_REG(hw, E1000_TXSTMPL);
regval |= (u64)E1000_READ_REG(hw, E1000_TXSTMPH) << 32;
igb_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL;
}
/**
* igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp
* @q_vector: Pointer to interrupt specific structure
* @va: Pointer to address containing Rx buffer
* @skb: Buffer containing timestamp and packet
*
* This function is meant to retrieve a timestamp from the first buffer of an
* incoming frame. The value is stored in little endian format starting on
* byte 8.
*/
void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
unsigned char *va,
struct sk_buff *skb)
{
__le64 *regval = (__le64 *)va;
/*
* The timestamp is recorded in little endian format.
* DWORD: 0 1 2 3
* Field: Reserved Reserved SYSTIML SYSTIMH
*/
igb_ptp_systim_to_hwtstamp(q_vector->adapter, skb_hwtstamps(skb),
le64_to_cpu(regval[1]));
}
/**
* igb_ptp_rx_rgtstamp - retrieve Rx timestamp stored in register
* @q_vector: Pointer to interrupt specific structure
* @skb: Buffer containing timestamp and packet
*
* This function is meant to retrieve a timestamp from the internal registers
* of the adapter and store it in the skb.
*/
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector,
struct sk_buff *skb)
{
struct igb_adapter *adapter = q_vector->adapter;
struct e1000_hw *hw = &adapter->hw;
u64 regval;
/*
* If this bit is set, then the RX registers contain the time stamp. No
* other packet will be time stamped until we read these registers, so
* read the registers to make them available again. Because only one
* packet can be time stamped at a time, we know that the register
* values must belong to this one here and therefore we don't need to
* compare any of the additional attributes stored for it.
*
* If nothing went wrong, then it should have a shared tx_flags that we
* can turn into a skb_shared_hwtstamps.
*/
if (!(E1000_READ_REG(hw, E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID))
return;
regval = E1000_READ_REG(hw, E1000_RXSTMPL);
regval |= (u64)E1000_READ_REG(hw, E1000_RXSTMPH) << 32;
igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
}
/**
* igb_ptp_hwtstamp_ioctl - control hardware time stamping
* @netdev:
* @ifreq:
* @cmd:
*
* Outgoing time stamping can be enabled and disabled. Play nice and
* disable it when requested, although it shouldn't case any overhead
* when no packet needs it. At most one packet in the queue may be
* marked for time stamping, otherwise it would be impossible to tell
* for sure to which packet the hardware time stamp belongs.
*
* Incoming time stamping has to be configured via the hardware
* filters. Not all combinations are supported, in particular event
* type has to be specified. Matching the kind of event packet is
* not supported, with the exception of "all V2 events regardless of
* level 2 or 4".
*
**/
int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
struct ifreq *ifr, int cmd)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
struct hwtstamp_config config;
u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
u32 tsync_rx_cfg = 0;
bool is_l4 = false;
bool is_l2 = false;
u32 regval;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
/* reserved for future extensions */
if (config.flags)
return -EINVAL;
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
tsync_tx_ctl = 0;
case HWTSTAMP_TX_ON:
break;
default:
return -ERANGE;
}
switch (config.rx_filter) {
case HWTSTAMP_FILTER_NONE:
tsync_rx_ctl = 0;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
is_l4 = true;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
is_l4 = true;
break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
is_l2 = true;
is_l4 = true;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_ALL:
/*
* 82576 cannot timestamp all packets, which it needs to do to
* support both V1 Sync and Delay_Req messages
*/
if (hw->mac.type != e1000_82576) {
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
config.rx_filter = HWTSTAMP_FILTER_ALL;
break;
}
/* fall through */
default:
config.rx_filter = HWTSTAMP_FILTER_NONE;
return -ERANGE;
}
if (hw->mac.type == e1000_82575) {
if (tsync_rx_ctl | tsync_tx_ctl)
return -EINVAL;
return 0;
}
/*
* Per-packet timestamping only works if all packets are
* timestamped, so enable timestamping in all packets as
* long as one rx filter was configured.
*/
if ((hw->mac.type >= e1000_82580) && tsync_rx_ctl) {
tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
config.rx_filter = HWTSTAMP_FILTER_ALL;
is_l2 = true;
is_l4 = true;
if ((hw->mac.type == e1000_i210) ||
(hw->mac.type == e1000_i211)) {
regval = E1000_READ_REG(hw, E1000_RXPBS);
regval |= E1000_RXPBS_CFG_TS_EN;
E1000_WRITE_REG(hw, E1000_RXPBS, regval);
}
}
/* enable/disable TX */
regval = E1000_READ_REG(hw, E1000_TSYNCTXCTL);
regval &= ~E1000_TSYNCTXCTL_ENABLED;
regval |= tsync_tx_ctl;
E1000_WRITE_REG(hw, E1000_TSYNCTXCTL, regval);
/* enable/disable RX */
regval = E1000_READ_REG(hw, E1000_TSYNCRXCTL);
regval &= ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK);
regval |= tsync_rx_ctl;
E1000_WRITE_REG(hw, E1000_TSYNCRXCTL, regval);
/* define which PTP packets are time stamped */
E1000_WRITE_REG(hw, E1000_TSYNCRXCFG, tsync_rx_cfg);
/* define ethertype filter for timestamped packets */
if (is_l2)
E1000_WRITE_REG(hw, E1000_ETQF(3),
(E1000_ETQF_FILTER_ENABLE | /* enable filter */
E1000_ETQF_1588 | /* enable timestamping */
ETH_P_1588)); /* 1588 eth protocol type */
else
E1000_WRITE_REG(hw, E1000_ETQF(3), 0);
/* L4 Queue Filter[3]: filter by destination port and protocol */
if (is_l4) {
u32 ftqf = (IPPROTO_UDP /* UDP */
| E1000_FTQF_VF_BP /* VF not compared */
| E1000_FTQF_1588_TIME_STAMP /* Enable Timestamping */
| E1000_FTQF_MASK); /* mask all inputs */
ftqf &= ~E1000_FTQF_MASK_PROTO_BP; /* enable protocol check */
E1000_WRITE_REG(hw, E1000_IMIR(3), htons(PTP_EV_PORT));
E1000_WRITE_REG(hw, E1000_IMIREXT(3),
(E1000_IMIREXT_SIZE_BP | E1000_IMIREXT_CTRL_BP));
if (hw->mac.type == e1000_82576) {
/* enable source port check */
E1000_WRITE_REG(hw, E1000_SPQF(3), htons(PTP_EV_PORT));
ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP;
}
E1000_WRITE_REG(hw, E1000_FTQF(3), ftqf);
} else {
E1000_WRITE_REG(hw, E1000_FTQF(3), E1000_FTQF_MASK);
}
E1000_WRITE_FLUSH(hw);
/* clear TX/RX time stamp registers, just to be sure */
regval = E1000_READ_REG(hw, E1000_TXSTMPL);
regval = E1000_READ_REG(hw, E1000_TXSTMPH);
regval = E1000_READ_REG(hw, E1000_RXSTMPL);
regval = E1000_READ_REG(hw, E1000_RXSTMPH);
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
void igb_ptp_init(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
switch (hw->mac.type) {
case e1000_82576:
snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
adapter->ptp_caps.owner = THIS_MODULE;
adapter->ptp_caps.max_adj = 999999881;
adapter->ptp_caps.n_ext_ts = 0;
adapter->ptp_caps.pps = 0;
adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82576;
adapter->ptp_caps.adjtime = igb_ptp_adjtime_82576;
adapter->ptp_caps.gettime = igb_ptp_gettime_82576;
adapter->ptp_caps.settime = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_enable;
adapter->cc.read = igb_ptp_read_82576;
adapter->cc.mask = CLOCKSOURCE_MASK(64);
adapter->cc.mult = 1;
adapter->cc.shift = IGB_82576_TSYNC_SHIFT;
/* Dial the nominal frequency. */
E1000_WRITE_REG(hw, E1000_TIMINCA, INCPERIOD_82576 |
INCVALUE_82576);
break;
case e1000_82580:
case e1000_i350:
case e1000_i354:
snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
adapter->ptp_caps.owner = THIS_MODULE;
adapter->ptp_caps.max_adj = 62499999;
adapter->ptp_caps.n_ext_ts = 0;
adapter->ptp_caps.pps = 0;
adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580;
adapter->ptp_caps.adjtime = igb_ptp_adjtime_82576;
adapter->ptp_caps.gettime = igb_ptp_gettime_82576;
adapter->ptp_caps.settime = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_enable;
adapter->cc.read = igb_ptp_read_82580;
adapter->cc.mask = CLOCKSOURCE_MASK(IGB_NBITS_82580);
adapter->cc.mult = 1;
adapter->cc.shift = 0;
/* Enable the timer functions by clearing bit 31. */
E1000_WRITE_REG(hw, E1000_TSAUXC, 0x0);
break;
case e1000_i210:
case e1000_i211:
snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
adapter->ptp_caps.owner = THIS_MODULE;
adapter->ptp_caps.max_adj = 62499999;
adapter->ptp_caps.n_ext_ts = 0;
adapter->ptp_caps.pps = 0;
adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580;
adapter->ptp_caps.adjtime = igb_ptp_adjtime_i210;
adapter->ptp_caps.gettime = igb_ptp_gettime_i210;
adapter->ptp_caps.settime = igb_ptp_settime_i210;
adapter->ptp_caps.enable = igb_ptp_enable;
/* Enable the timer functions by clearing bit 31. */
E1000_WRITE_REG(hw, E1000_TSAUXC, 0x0);
break;
default:
adapter->ptp_clock = NULL;
return;
}
E1000_WRITE_FLUSH(hw);
spin_lock_init(&adapter->tmreg_lock);
INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
/* Initialize the clock and overflow work for devices that need it. */
if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) {
struct timespec ts = ktime_to_timespec(ktime_get_real());
igb_ptp_settime_i210(&adapter->ptp_caps, &ts);
} else {
timecounter_init(&adapter->tc, &adapter->cc,
ktime_to_ns(ktime_get_real()));
INIT_DELAYED_WORK(&adapter->ptp_overflow_work,
igb_ptp_overflow_check);
schedule_delayed_work(&adapter->ptp_overflow_work,
IGB_SYSTIM_OVERFLOW_PERIOD);
}
/* Initialize the time sync interrupts for devices that support it. */
if (hw->mac.type >= e1000_82580) {
E1000_WRITE_REG(hw, E1000_TSIM, E1000_TSIM_TXTS);
E1000_WRITE_REG(hw, E1000_IMS, E1000_IMS_TS);
}
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
&adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) {
adapter->ptp_clock = NULL;
dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n");
} else {
dev_info(&adapter->pdev->dev, "added PHC on %s\n",
adapter->netdev->name);
adapter->flags |= IGB_FLAG_PTP;
}
}
/**
* igb_ptp_stop - Disable PTP device and stop the overflow check.
* @adapter: Board private structure.
*
* This function stops the PTP support and cancels the delayed work.
**/
void igb_ptp_stop(struct igb_adapter *adapter)
{
switch (adapter->hw.mac.type) {
case e1000_82576:
case e1000_82580:
case e1000_i350:
case e1000_i354:
cancel_delayed_work_sync(&adapter->ptp_overflow_work);
break;
case e1000_i210:
case e1000_i211:
/* No delayed work to cancel. */
break;
default:
return;
}
cancel_work_sync(&adapter->ptp_tx_work);
if (adapter->ptp_tx_skb) {
dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL;
}
if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock);
dev_info(&adapter->pdev->dev, "removed PHC on %s\n",
adapter->netdev->name);
adapter->flags &= ~IGB_FLAG_PTP;
}
}
/**
* igb_ptp_reset - Re-enable the adapter for PTP following a reset.
* @adapter: Board private structure.
*
* This function handles the reset work required to re-enable the PTP device.
**/
void igb_ptp_reset(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
if (!(adapter->flags & IGB_FLAG_PTP))
return;
switch (adapter->hw.mac.type) {
case e1000_82576:
/* Dial the nominal frequency. */
E1000_WRITE_REG(hw, E1000_TIMINCA, INCPERIOD_82576 |
INCVALUE_82576);
break;
case e1000_82580:
case e1000_i350:
case e1000_i354:
case e1000_i210:
case e1000_i211:
/* Enable the timer functions and interrupts. */
E1000_WRITE_REG(hw, E1000_TSAUXC, 0x0);
E1000_WRITE_REG(hw, E1000_TSIM, E1000_TSIM_TXTS);
E1000_WRITE_REG(hw, E1000_IMS, E1000_IMS_TS);
break;
default:
/* No work to do. */
return;
}
/* Re-initialize the timer. */
if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) {
struct timespec ts = ktime_to_timespec(ktime_get_real());
igb_ptp_settime_i210(&adapter->ptp_caps, &ts);
} else {
timecounter_init(&adapter->tc, &adapter->cc,
ktime_to_ns(ktime_get_real()));
}
}

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -52,18 +52,48 @@ struct igb_reg_test {
#define TABLE64_TEST_LO 5
#define TABLE64_TEST_HI 6
/* i210 reg test */
static struct igb_reg_test reg_test_i210[] = {
{ E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
{ E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
{ E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
/* RDH is read-only for i210, only test RDT. */
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0003FFF0, 0x0003FFF0 },
{ E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
{ E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
{ E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
{ E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RA, 0, 16, TABLE64_TEST_LO,
0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RA, 0, 16, TABLE64_TEST_HI,
0x900FFFFF, 0xFFFFFFFF },
{ E1000_MTA, 0, 128, TABLE32_TEST,
0xFFFFFFFF, 0xFFFFFFFF },
{ 0, 0, 0, 0 }
};
/* i350 reg test */
static struct igb_reg_test reg_test_i350[] = {
{ E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
{ E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
{ E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
/* VET is readonly on i350 */
{ E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
{ E1000_RDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_RDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
/* RDH is read-only for i350, only test RDT. */
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
@ -72,10 +102,10 @@ static struct igb_reg_test reg_test_i350[] = {
{ E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
{ E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
{ E1000_TDBAL(4), 0x40, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(4), 0x40, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_TDLEN(4), 0x40, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
{ E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },

View file

@ -0,0 +1,815 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include <linux/tcp.h>
#include "igb.h"
#include "igb_vmdq.h"
#include <linux/if_vlan.h>
#ifdef CONFIG_IGB_VMDQ_NETDEV
int igb_vmdq_open(struct net_device *dev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
struct net_device *main_netdev = adapter->netdev;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
if (test_bit(__IGB_DOWN, &adapter->state)) {
DPRINTK(DRV, WARNING,
"Open %s before opening this device.\n",
main_netdev->name);
return -EAGAIN;
}
netif_carrier_off(dev);
vadapter->tx_ring->vmdq_netdev = dev;
vadapter->rx_ring->vmdq_netdev = dev;
if (is_valid_ether_addr(dev->dev_addr)) {
igb_del_mac_filter(adapter, dev->dev_addr, hw_queue);
igb_add_mac_filter(adapter, dev->dev_addr, hw_queue);
}
netif_carrier_on(dev);
return 0;
}
int igb_vmdq_close(struct net_device *dev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
netif_carrier_off(dev);
igb_del_mac_filter(adapter, dev->dev_addr, hw_queue);
vadapter->tx_ring->vmdq_netdev = NULL;
vadapter->rx_ring->vmdq_netdev = NULL;
return 0;
}
netdev_tx_t igb_vmdq_xmit_frame(struct sk_buff *skb, struct net_device *dev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
return igb_xmit_frame_ring(skb, vadapter->tx_ring);
}
struct net_device_stats *igb_vmdq_get_stats(struct net_device *dev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
struct e1000_hw *hw = &adapter->hw;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
vadapter->net_stats.rx_packets +=
E1000_READ_REG(hw, E1000_PFVFGPRC(hw_queue));
E1000_WRITE_REG(hw, E1000_PFVFGPRC(hw_queue), 0);
vadapter->net_stats.tx_packets +=
E1000_READ_REG(hw, E1000_PFVFGPTC(hw_queue));
E1000_WRITE_REG(hw, E1000_PFVFGPTC(hw_queue), 0);
vadapter->net_stats.rx_bytes +=
E1000_READ_REG(hw, E1000_PFVFGORC(hw_queue));
E1000_WRITE_REG(hw, E1000_PFVFGORC(hw_queue), 0);
vadapter->net_stats.tx_bytes +=
E1000_READ_REG(hw, E1000_PFVFGOTC(hw_queue));
E1000_WRITE_REG(hw, E1000_PFVFGOTC(hw_queue), 0);
vadapter->net_stats.multicast +=
E1000_READ_REG(hw, E1000_PFVFMPRC(hw_queue));
E1000_WRITE_REG(hw, E1000_PFVFMPRC(hw_queue), 0);
/* only return the current stats */
return &vadapter->net_stats;
}
/**
* igb_write_vm_addr_list - write unicast addresses to RAR table
* @netdev: network interface device structure
*
* Writes unicast address list to the RAR table.
* Returns: -ENOMEM on failure/insufficient address space
* 0 on no addresses written
* X on writing X addresses to the RAR table
**/
static int igb_write_vm_addr_list(struct net_device *netdev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
struct igb_adapter *adapter = vadapter->real_adapter;
int count = 0;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
/* return ENOMEM indicating insufficient memory for addresses */
if (netdev_uc_count(netdev) > igb_available_rars(adapter))
return -ENOMEM;
if (!netdev_uc_empty(netdev)) {
#ifdef NETDEV_HW_ADDR_T_UNICAST
struct netdev_hw_addr *ha;
#else
struct dev_mc_list *ha;
#endif
netdev_for_each_uc_addr(ha, netdev) {
#ifdef NETDEV_HW_ADDR_T_UNICAST
igb_del_mac_filter(adapter, ha->addr, hw_queue);
igb_add_mac_filter(adapter, ha->addr, hw_queue);
#else
igb_del_mac_filter(adapter, ha->da_addr, hw_queue);
igb_add_mac_filter(adapter, ha->da_addr, hw_queue);
#endif
count++;
}
}
return count;
}
#define E1000_VMOLR_UPE 0x20000000 /* Unicast promiscuous mode */
void igb_vmdq_set_rx_mode(struct net_device *dev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
struct e1000_hw *hw = &adapter->hw;
u32 vmolr, rctl;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
/* Check for Promiscuous and All Multicast modes */
vmolr = E1000_READ_REG(hw, E1000_VMOLR(hw_queue));
/* clear the affected bits */
vmolr &= ~(E1000_VMOLR_UPE | E1000_VMOLR_MPME |
E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE);
if (dev->flags & IFF_PROMISC) {
vmolr |= E1000_VMOLR_UPE;
rctl = E1000_READ_REG(hw, E1000_RCTL);
rctl |= E1000_RCTL_UPE;
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
} else {
rctl = E1000_READ_REG(hw, E1000_RCTL);
rctl &= ~E1000_RCTL_UPE;
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
if (dev->flags & IFF_ALLMULTI) {
vmolr |= E1000_VMOLR_MPME;
} else {
/*
* Write addresses to the MTA, if the attempt fails
* then we should just turn on promiscous mode so
* that we can at least receive multicast traffic
*/
if (igb_write_mc_addr_list(adapter->netdev) != 0)
vmolr |= E1000_VMOLR_ROMPE;
}
#ifdef HAVE_SET_RX_MODE
/*
* Write addresses to available RAR registers, if there is not
* sufficient space to store all the addresses then enable
* unicast promiscous mode
*/
if (igb_write_vm_addr_list(dev) < 0)
vmolr |= E1000_VMOLR_UPE;
#endif
}
E1000_WRITE_REG(hw, E1000_VMOLR(hw_queue), vmolr);
return;
}
int igb_vmdq_set_mac(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
igb_del_mac_filter(adapter, dev->dev_addr, hw_queue);
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
return igb_add_mac_filter(adapter, dev->dev_addr, hw_queue);
}
int igb_vmdq_change_mtu(struct net_device *dev, int new_mtu)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
if (adapter->netdev->mtu < new_mtu) {
DPRINTK(PROBE, INFO,
"Set MTU on %s to >= %d "
"before changing MTU on %s\n",
adapter->netdev->name, new_mtu, dev->name);
return -EINVAL;
}
dev->mtu = new_mtu;
return 0;
}
void igb_vmdq_tx_timeout(struct net_device *dev)
{
return;
}
void igb_vmdq_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
struct e1000_hw *hw = &adapter->hw;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
vadapter->vlgrp = grp;
igb_enable_vlan_tags(adapter);
E1000_WRITE_REG(hw, E1000_VMVIR(hw_queue), 0);
return;
}
void igb_vmdq_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
#ifndef HAVE_NETDEV_VLAN_FEATURES
struct net_device *v_netdev;
#endif
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
/* attempt to add filter to vlvf array */
igb_vlvf_set(adapter, vid, TRUE, hw_queue);
#ifndef HAVE_NETDEV_VLAN_FEATURES
/* Copy feature flags from netdev to the vlan netdev for this vid.
* This allows things like TSO to bubble down to our vlan device.
*/
v_netdev = vlan_group_get_device(vadapter->vlgrp, vid);
v_netdev->features |= adapter->netdev->features;
vlan_group_set_device(vadapter->vlgrp, vid, v_netdev);
#endif
return;
}
void igb_vmdq_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(dev);
struct igb_adapter *adapter = vadapter->real_adapter;
int hw_queue = vadapter->rx_ring->queue_index +
adapter->vfs_allocated_count;
vlan_group_set_device(vadapter->vlgrp, vid, NULL);
/* remove vlan from VLVF table array */
igb_vlvf_set(adapter, vid, FALSE, hw_queue);
return;
}
static int igb_vmdq_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
struct igb_adapter *adapter = vadapter->real_adapter;
struct e1000_hw *hw = &adapter->hw;
u32 status;
if (hw->phy.media_type == e1000_media_type_copper) {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full|
SUPPORTED_Autoneg |
SUPPORTED_TP);
ecmd->advertising = ADVERTISED_TP;
if (hw->mac.autoneg == 1) {
ecmd->advertising |= ADVERTISED_Autoneg;
/* the e1000 autoneg seems to match ethtool nicely */
ecmd->advertising |= hw->phy.autoneg_advertised;
}
ecmd->port = PORT_TP;
ecmd->phy_address = hw->phy.addr;
} else {
ecmd->supported = (SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Autoneg);
ecmd->advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg);
ecmd->port = PORT_FIBRE;
}
ecmd->transceiver = XCVR_INTERNAL;
status = E1000_READ_REG(hw, E1000_STATUS);
if (status & E1000_STATUS_LU) {
if ((status & E1000_STATUS_SPEED_1000) ||
hw->phy.media_type != e1000_media_type_copper)
ecmd->speed = SPEED_1000;
else if (status & E1000_STATUS_SPEED_100)
ecmd->speed = SPEED_100;
else
ecmd->speed = SPEED_10;
if ((status & E1000_STATUS_FD) ||
hw->phy.media_type != e1000_media_type_copper)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ecmd->speed = -1;
ecmd->duplex = -1;
}
ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
return 0;
}
static u32 igb_vmdq_get_msglevel(struct net_device *netdev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
struct igb_adapter *adapter = vadapter->real_adapter;
return adapter->msg_enable;
}
static void igb_vmdq_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
struct igb_adapter *adapter = vadapter->real_adapter;
struct net_device *main_netdev = adapter->netdev;
strncpy(drvinfo->driver, igb_driver_name, 32);
strncpy(drvinfo->version, igb_driver_version, 32);
strncpy(drvinfo->fw_version, "N/A", 4);
snprintf(drvinfo->bus_info, 32, "%s VMDQ %d", main_netdev->name,
vadapter->rx_ring->queue_index);
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = 0;
}
static void igb_vmdq_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
struct igb_ring *tx_ring = vadapter->tx_ring;
struct igb_ring *rx_ring = vadapter->rx_ring;
ring->rx_max_pending = IGB_MAX_RXD;
ring->tx_max_pending = IGB_MAX_TXD;
ring->rx_mini_max_pending = 0;
ring->rx_jumbo_max_pending = 0;
ring->rx_pending = rx_ring->count;
ring->tx_pending = tx_ring->count;
ring->rx_mini_pending = 0;
ring->rx_jumbo_pending = 0;
}
static u32 igb_vmdq_get_rx_csum(struct net_device *netdev)
{
struct igb_vmdq_adapter *vadapter = netdev_priv(netdev);
struct igb_adapter *adapter = vadapter->real_adapter;
return test_bit(IGB_RING_FLAG_RX_CSUM, &adapter->rx_ring[0]->flags);
}
static struct ethtool_ops igb_vmdq_ethtool_ops = {
.get_settings = igb_vmdq_get_settings,
.get_drvinfo = igb_vmdq_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_ringparam = igb_vmdq_get_ringparam,
.get_rx_csum = igb_vmdq_get_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_msglevel = igb_vmdq_get_msglevel,
#ifdef NETIF_F_TSO
.get_tso = ethtool_op_get_tso,
#endif
#ifdef HAVE_ETHTOOL_GET_PERM_ADDR
.get_perm_addr = ethtool_op_get_perm_addr,
#endif
};
void igb_vmdq_set_ethtool_ops(struct net_device *netdev)
{
SET_ETHTOOL_OPS(netdev, &igb_vmdq_ethtool_ops);
}
#endif /* CONFIG_IGB_VMDQ_NETDEV */
#ifdef __VMKNETDDI_QUEUEOPS__
int igb_set_rxqueue_macfilter(struct net_device *netdev, int queue,
u8 *mac_addr)
{
int err = 0;
struct igb_adapter *adapter = netdev_priv(netdev);
struct igb_ring *rx_ring = adapter->rx_ring[queue];
if ((queue < 0) || (queue >= adapter->num_rx_queues)) {
DPRINTK(DRV, ERR, "Invalid RX Queue %u specified\n", queue);
return -EADDRNOTAVAIL;
}
/* Note: Broadcast address is used to disable the MAC filter*/
if (!is_valid_ether_addr(mac_addr)) {
/* Clear ring addr */
DPRINTK(DRV, DEBUG,
"disabling MAC filter on RX Queue[%d]\n", queue);
igb_del_mac_filter(adapter, rx_ring->mac_addr, queue);
memset(rx_ring->mac_addr, 0xFF, NODE_ADDRESS_SIZE);
return -EADDRNOTAVAIL;
}
DPRINTK(DRV, DEBUG,
"enabling MAC filter [[0x%X:0x%X:0x%X:0x%X:0x%X:0x%X]] "
"on RX Queue[%d]\n", mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5], queue);
/* Store in ring */
memcpy(rx_ring->mac_addr, mac_addr, NODE_ADDRESS_SIZE);
igb_add_mac_filter(adapter, rx_ring->mac_addr, queue);
return err;
}
static int igb_get_netqueue_features(vmknetddi_queueop_get_features_args_t *args)
{
args->features = VMKNETDDI_QUEUEOPS_FEATURE_RXQUEUES |
VMKNETDDI_QUEUEOPS_FEATURE_TXQUEUES;
return VMKNETDDI_QUEUEOPS_OK;
}
static int igb_get_queue_count(vmknetddi_queueop_get_queue_count_args_t *args)
{
struct net_device *netdev = args->netdev;
struct igb_adapter *adapter = netdev_priv(netdev);
if (args->type == VMKNETDDI_QUEUEOPS_QUEUE_TYPE_TX) {
args->count = adapter->num_tx_queues - 1;
} else if (args->type == VMKNETDDI_QUEUEOPS_QUEUE_TYPE_RX) {
args->count = adapter->num_rx_queues - 1;
} else {
DPRINTK(DRV, ERR, "invalid queue type\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
return VMKNETDDI_QUEUEOPS_OK;
}
static int igb_get_filter_count(vmknetddi_queueop_get_filter_count_args_t *args)
{
args->count = 1;
return VMKNETDDI_QUEUEOPS_OK;
}
static int igb_alloc_rx_queue(struct net_device *netdev,
vmknetddi_queueops_queueid_t *p_qid,
struct napi_struct **napi_p)
{
struct igb_adapter *adapter = netdev_priv(netdev);
if (adapter->n_rx_queues_allocated >= adapter->num_rx_queues) {
DPRINTK(DRV, ERR, "igb_alloc_rx_queue: no free rx queues\n");
return VMKNETDDI_QUEUEOPS_ERR;
} else {
int i;
for (i = 1; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = adapter->rx_ring[i];
if (!ring->allocated) {
ring->allocated = TRUE;
*p_qid = VMKNETDDI_QUEUEOPS_MK_RX_QUEUEID(i);
DPRINTK(DRV, DEBUG,
"allocated VMDQ rx queue=%d\n", i);
*napi_p = &ring->q_vector->napi;
adapter->n_rx_queues_allocated++;
return VMKNETDDI_QUEUEOPS_OK;
}
}
DPRINTK(DRV, ERR, "no free rx queues found!\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
}
static int igb_alloc_tx_queue(struct net_device *netdev,
vmknetddi_queueops_queueid_t *p_qid,
u16 *queue_mapping)
{
struct igb_adapter *adapter = netdev_priv(netdev);
if (adapter->n_tx_queues_allocated >= adapter->num_tx_queues) {
DPRINTK(DRV, ERR, "igb_alloc_tx_queue: no free tx queues\n");
return VMKNETDDI_QUEUEOPS_ERR;
} else {
int i;
for (i = 1; i < adapter->num_tx_queues; i++) {
struct igb_ring *ring = adapter->tx_ring[i];
if (!ring->allocated) {
ring->allocated = TRUE;
*p_qid = VMKNETDDI_QUEUEOPS_MK_TX_QUEUEID(i);
*queue_mapping = i;
DPRINTK(DRV, DEBUG,
"allocated VMDQ tx queue=%d\n", i);
adapter->n_tx_queues_allocated++;
return VMKNETDDI_QUEUEOPS_OK;
}
}
DPRINTK(DRV, ERR, "no free tx queues found!\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
}
static int igb_alloc_queue(vmknetddi_queueop_alloc_queue_args_t *args)
{
struct net_device *netdev = args->netdev;
struct igb_adapter *adapter = netdev_priv(netdev);
if (args->type == VMKNETDDI_QUEUEOPS_QUEUE_TYPE_TX) {
return igb_alloc_tx_queue(args->netdev, &args->queueid,
&args->queue_mapping);
} else if (args->type == VMKNETDDI_QUEUEOPS_QUEUE_TYPE_RX) {
return igb_alloc_rx_queue(args->netdev, &args->queueid,
&args->napi);
} else {
DPRINTK(DRV, ERR, "invalid queue type\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
}
static int
igb_free_rx_queue(struct net_device *netdev,
vmknetddi_queueops_queueid_t qid)
{
struct igb_adapter *adapter = netdev_priv(netdev);
u16 queue = VMKNETDDI_QUEUEOPS_QUEUEID_VAL(qid);
struct igb_ring *ring = adapter->rx_ring[queue];
if (!ring->allocated) {
DPRINTK(DRV, ERR, "rx queue %d not allocated\n", queue);
return VMKNETDDI_QUEUEOPS_ERR;
}
DPRINTK(DRV, DEBUG, "freed VMDQ rx queue=%d\n", queue);
ring->allocated = FALSE;
adapter->n_rx_queues_allocated--;
return VMKNETDDI_QUEUEOPS_OK;
}
static int
igb_free_tx_queue(struct net_device *netdev,
vmknetddi_queueops_queueid_t qid)
{
struct igb_adapter *adapter = netdev_priv(netdev);
u16 queue = VMKNETDDI_QUEUEOPS_QUEUEID_VAL(qid);
if (!adapter->tx_ring[queue]->allocated) {
DPRINTK(DRV, ERR, "tx queue %d not allocated\n", queue);
return VMKNETDDI_QUEUEOPS_ERR;
}
DPRINTK(DRV, DEBUG, "freed VMDQ tx queue=%d\n", queue);
adapter->tx_ring[queue]->allocated = FALSE;
adapter->n_tx_queues_allocated--;
return VMKNETDDI_QUEUEOPS_OK;
}
static int
igb_free_queue(vmknetddi_queueop_free_queue_args_t *args)
{
struct net_device *netdev = args->netdev;
struct igb_adapter *adapter = netdev_priv(netdev);
if (VMKNETDDI_QUEUEOPS_IS_TX_QUEUEID(args->queueid)) {
return igb_free_tx_queue(netdev, args->queueid);
} else if (VMKNETDDI_QUEUEOPS_IS_RX_QUEUEID(args->queueid)) {
return igb_free_rx_queue(netdev, args->queueid);
} else {
DPRINTK(DRV, ERR, "invalid queue type\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
}
static int
igb_get_queue_vector(vmknetddi_queueop_get_queue_vector_args_t *args)
{
int qid;
struct net_device *netdev = args->netdev;
struct igb_adapter *adapter = netdev_priv(netdev);
/* Assuming RX queue id's are received */
qid = VMKNETDDI_QUEUEOPS_QUEUEID_VAL(args->queueid);
args->vector = adapter->msix_entries[qid].vector;
return VMKNETDDI_QUEUEOPS_OK;
}
static int
igb_get_default_queue(vmknetddi_queueop_get_default_queue_args_t *args)
{
struct net_device *netdev = args->netdev;
struct igb_adapter *adapter = netdev_priv(netdev);
if (args->type == VMKNETDDI_QUEUEOPS_QUEUE_TYPE_RX) {
args->napi = &adapter->rx_ring[0]->q_vector->napi;
args->queueid = VMKNETDDI_QUEUEOPS_MK_RX_QUEUEID(0);
return VMKNETDDI_QUEUEOPS_OK;
} else if (args->type == VMKNETDDI_QUEUEOPS_QUEUE_TYPE_TX) {
args->queueid = VMKNETDDI_QUEUEOPS_MK_TX_QUEUEID(0);
return VMKNETDDI_QUEUEOPS_OK;
} else {
return VMKNETDDI_QUEUEOPS_ERR;
}
}
static int
igb_apply_rx_filter(vmknetddi_queueop_apply_rx_filter_args_t *args)
{
int rval;
u8 *macaddr;
u16 queue = VMKNETDDI_QUEUEOPS_QUEUEID_VAL(args->queueid);
struct igb_adapter *adapter = netdev_priv(args->netdev);
if (!VMKNETDDI_QUEUEOPS_IS_RX_QUEUEID(args->queueid)) {
DPRINTK(DRV, ERR, "not an rx queue 0x%x\n",
args->queueid);
return VMKNETDDI_QUEUEOPS_ERR;
}
if (vmknetddi_queueops_get_filter_class(&args->filter)
!= VMKNETDDI_QUEUEOPS_FILTER_MACADDR) {
DPRINTK(DRV, ERR, "only mac filters supported\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
if (!adapter->rx_ring[queue]->allocated) {
DPRINTK(DRV, ERR, "queue not allocated\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
if (adapter->rx_ring[queue]->active) {
DPRINTK(DRV, ERR, "filter count exceeded\n");
return VMKNETDDI_QUEUEOPS_ERR;
}
macaddr = vmknetddi_queueops_get_filter_macaddr(&args->filter);
rval = igb_set_rxqueue_macfilter(args->netdev, queue, macaddr);
if (rval == 0) {
adapter->rx_ring[queue]->active = TRUE;
/* force to 0 since we only support one filter per queue */
args->filterid = VMKNETDDI_QUEUEOPS_MK_FILTERID(0);
return VMKNETDDI_QUEUEOPS_OK;
} else {
return VMKNETDDI_QUEUEOPS_ERR;
}
}
static int
igb_remove_rx_filter(vmknetddi_queueop_remove_rx_filter_args_t *args)
{
int rval;
u16 cidx = VMKNETDDI_QUEUEOPS_QUEUEID_VAL(args->queueid);
u16 fidx = VMKNETDDI_QUEUEOPS_FILTERID_VAL(args->filterid);
struct igb_adapter *adapter = netdev_priv(args->netdev);
u8 macaddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
DPRINTK(DRV, DEBUG, "removing filter on cidx=%d, fidx=%d\n",
cidx, fidx);
/* This will return an error because broadcast is not a valid
* Ethernet address, so ignore and carry on
*/
rval = igb_set_rxqueue_macfilter(args->netdev, cidx, macaddr);
adapter->rx_ring[cidx]->active = FALSE;
return rval;
}
static int
igb_get_queue_stats(vmknetddi_queueop_get_stats_args_t *args)
{
return VMKNETDDI_QUEUEOPS_ERR;
}
static int
igb_get_netqueue_version(vmknetddi_queueop_get_version_args_t *args)
{
return vmknetddi_queueops_version(args);
}
static int igb_set_tx_priority(vmknetddi_queueop_set_tx_priority_args_t *args)
{
/* Not supported */
return VMKNETDDI_QUEUEOPS_OK;
}
int
igb_netqueue_ops(vmknetddi_queueops_op_t op, void *args)
{
switch (op) {
case VMKNETDDI_QUEUEOPS_OP_GET_VERSION:
return igb_get_netqueue_version(
(vmknetddi_queueop_get_version_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_GET_FEATURES:
return igb_get_netqueue_features(
(vmknetddi_queueop_get_features_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_GET_QUEUE_COUNT:
return igb_get_queue_count(
(vmknetddi_queueop_get_queue_count_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_GET_FILTER_COUNT:
return igb_get_filter_count(
(vmknetddi_queueop_get_filter_count_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_ALLOC_QUEUE:
return igb_alloc_queue(
(vmknetddi_queueop_alloc_queue_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_FREE_QUEUE:
return igb_free_queue(
(vmknetddi_queueop_free_queue_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_GET_QUEUE_VECTOR:
return igb_get_queue_vector(
(vmknetddi_queueop_get_queue_vector_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_GET_DEFAULT_QUEUE:
return igb_get_default_queue(
(vmknetddi_queueop_get_default_queue_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_APPLY_RX_FILTER:
return igb_apply_rx_filter(
(vmknetddi_queueop_apply_rx_filter_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_REMOVE_RX_FILTER:
return igb_remove_rx_filter(
(vmknetddi_queueop_remove_rx_filter_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_GET_STATS:
return igb_get_queue_stats(
(vmknetddi_queueop_get_stats_args_t *)args);
break;
case VMKNETDDI_QUEUEOPS_OP_SET_TX_PRIORITY:
return igb_set_tx_priority(
(vmknetddi_queueop_set_tx_priority_args_t *)args);
break;
default:
return VMKNETDDI_QUEUEOPS_ERR;
}
return VMKNETDDI_QUEUEOPS_ERR;
}
#endif /* __VMKNETDDI_QUEUEOPS__ */

View file

@ -0,0 +1,51 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _IGB_VMDQ_H_
#define _IGB_VMDQ_H_
#ifdef CONFIG_IGB_VMDQ_NETDEV
int igb_vmdq_open(struct net_device *dev);
int igb_vmdq_close(struct net_device *dev);
netdev_tx_t igb_vmdq_xmit_frame(struct sk_buff *skb, struct net_device *dev);
struct net_device_stats *igb_vmdq_get_stats(struct net_device *dev);
void igb_vmdq_set_rx_mode(struct net_device *dev);
int igb_vmdq_set_mac(struct net_device *dev, void *addr);
int igb_vmdq_change_mtu(struct net_device *dev, int new_mtu);
void igb_vmdq_tx_timeout(struct net_device *dev);
void igb_vmdq_vlan_rx_register(struct net_device *dev,
struct vlan_group *grp);
void igb_vmdq_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
void igb_vmdq_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
void igb_vmdq_set_ethtool_ops(struct net_device *netdev);
#endif /* CONFIG_IGB_VMDQ_NETDEV */
#ifdef __VMKLNX__
#ifdef __VMKNETDDI_QUEUEOPS__
extern int igb_netqueue_ops(vmknetddi_queueops_op_t op, void *args);
#endif
#endif
#endif /* _IGB_VMDQ_H_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -33,6 +33,11 @@
#include "vmkapi.h"
#define ESX40_PRODUCT_VER "4.0.0"
#define ESX41_PRODUCT_VER "4.1.0"
#define ESX50_PRODUCT_VER "5.0.0"
#define ESX51_PRODUCT_VER "5.1.0"
/* disable features that VMware ESX does not support */
#ifndef CONFIG_PM
@ -48,7 +53,6 @@
#define vmalloc_node(a,b) vmalloc(a)
#define skb_record_rx_queue(a, b) \
if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) \
vmknetddi_queueops_set_skb_queueid((a), \
VMKNETDDI_QUEUEOPS_MK_RX_QUEUEID((b)));
@ -65,8 +69,6 @@ static inline void _kc_skb_trim(struct sk_buff *skb, unsigned int len)
skb->tail = skb->data + len;
}
}
/* disable pskb_trim usage for now - should break lots of stuff */
#define pskb_trim(a,b)
/* Alternate __VMKLNX__ DMA memory allocation stuff */
#define alloc_page(A) __get_free_pages(A, 0)
@ -81,6 +83,7 @@ static inline void _kc_skb_trim(struct sk_buff *skb, unsigned int len)
/*
* A couple of quick hacks for working with esx40
*/
#define vmknetddi_queueops_queue_features_t unsigned int
#define HAVE_NETDEV_NAPI_LIST
#define vmk_set_module_version(x,y) 1
#define VMKNETDDI_REGISTER_QUEUEOPS(ndev, ops) \
@ -100,3 +103,10 @@ static inline void _kc_skb_trim(struct sk_buff *skb, unsigned int len)
#define device_set_wakeup_enable(d, w) device_init_wakeup(d, w);
#define nr_cpu_ids smp_num_cpus
#define ESX_ALLOC_PERCPU( type ) \
kmalloc(sizeof(type) * nr_cpu_ids, GFP_KERNEL)
#define ESX_FREE_PERCPU( ptr ) kfree(ptr)
#define ESX_PER_CPU_PTR( ptr, cpu, type ) (((cpu) < nr_cpu_ids)? \
((typeof(ptr))((char*)(ptr) + (cpu) * sizeof(type))):NULL)
#define __percpu

View file

@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007-2009 Intel Corporation.
Copyright(c) 2007-2013 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@ -894,8 +894,6 @@ struct mii_ioctl_data;
#define mii_ethtool_sset _kc_mii_ethtool_sset
#undef mii_check_link
#define mii_check_link _kc_mii_check_link
#undef generic_mii_ioctl
#define generic_mii_ioctl _kc_generic_mii_ioctl
extern int _kc_mii_link_ok (struct mii_if_info *mii);
extern int _kc_mii_nway_restart (struct mii_if_info *mii);
extern int _kc_mii_ethtool_gset(struct mii_if_info *mii,
@ -903,9 +901,13 @@ extern int _kc_mii_ethtool_gset(struct mii_if_info *mii,
extern int _kc_mii_ethtool_sset(struct mii_if_info *mii,
struct ethtool_cmd *ecmd);
extern void _kc_mii_check_link (struct mii_if_info *mii);
#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,4,6) )
#undef generic_mii_ioctl
#define generic_mii_ioctl _kc_generic_mii_ioctl
extern int _kc_generic_mii_ioctl(struct mii_if_info *mii_if,
struct mii_ioctl_data *mii_data, int cmd,
unsigned int *duplex_changed);
#endif /* > 2.4.6 */
struct _kc_pci_dev_ext {
@ -1091,6 +1093,7 @@ void _kc_mii_check_link (struct mii_if_info *mii)
netif_carrier_off(mii->dev);
}
#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,4,6) )
int _kc_generic_mii_ioctl(struct mii_if_info *mii_if,
struct mii_ioctl_data *mii_data, int cmd,
unsigned int *duplex_chg_out)
@ -1165,4 +1168,5 @@ int _kc_generic_mii_ioctl(struct mii_if_info *mii_if,
return rc;
}
#endif /* > 2.4.6 */

View file

@ -4413,6 +4413,8 @@ int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
/* Dont allow programming of duplicate MAC
* address on the same PF for different VFs(queues)
*/
if (!compare_ether_addr(addr, hw->mac.perm_addr))
return i;
if (!compare_ether_addr
(addr, adapter->mac_table[i].addr)) {
if (adapter->mac_table[i].queue == queue) {
@ -4473,6 +4475,8 @@ int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8* addr, u16 queue)
return -EINVAL;
for (i = 0; i < hw->mac.num_rar_entries; i++) {
if (!compare_ether_addr(addr, hw->mac.perm_addr))
return 0;
if (!compare_ether_addr(addr, adapter->mac_table[i].addr) &&
adapter->mac_table[i].queue == queue) {
adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;

View file

@ -25,7 +25,7 @@
/*
* Source file for NIC routines to access the Phantom hardware
*
* $Id: //depot/vmkdrivers/prod2013-stage-rel/src_9/drivers/net/nx_nic/unm_nic_hw.c#1 $
* $Id: //depot/vmkdrivers/vsphere55u1/src_9/drivers/net/nx_nic/unm_nic_hw.c#1 $
*
*/
#include <linux/delay.h>

View file

@ -17703,6 +17703,16 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
features |= NETIF_F_TSO_ECN;
}
#if defined(__VMKLNX__) && defined(TG3_INBOX)
/*
* Disable TSO to avoid the data corruption issue happened when
* a 9KB+ buffer straddling a 4GB boundary. Please refer to
* PR 1148150.
*/
features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN);
tg3_flag_clear(tp, TSO_CAPABLE);
tg3_flag_clear(tp, TSO_BUG);
#endif
#if defined(__VMKLNX__)
/* VMWare does not have skb_gso_segment() to workaround TSO_BUG */
if (tg3_flag(tp, TSO_BUG))

View file

@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
#define LPFC_DRIVER_VERSION "8.2.3.1-128vmw"
#define LPFC_DRIVER_VERSION "8.2.3.1-129vmw"
#if defined(__VMKLNX__)
/*

View file

@ -2510,7 +2510,6 @@ static void megasas_hotplug_work(void *arg)
* Because scsi_device_lookup() takes a reference on the device,
* should decrement reference count before removing it.
*/
vmklnx_scsi_device_hot_removed(device);
scsi_device_put(device);
scsi_remove_device(device);
}
@ -2525,7 +2524,6 @@ static void megasas_hotplug_work(void *arg)
* Because scsi_device_lookup() takes a reference on the device,
* should decrement reference count before removing it.
*/
vmklnx_scsi_device_hot_removed(device);
scsi_device_put(device);
scsi_remove_device(device);
} else {

View file

@ -3026,6 +3026,7 @@ mpt2sas_base_get_sata_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz)
{
Mpi2SataPassthroughRequest_t *mpi_request;
Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
u16 smid;
u32 ioc_state;
unsigned long timeleft;
@ -3109,7 +3110,7 @@ mpt2sas_base_get_sata_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
sizeof(Mpi2SataPassthroughRequest_t)/4);
if (!(ioc->config_cmds.status & MPT2_CMD_RESET))
issue_reset = 1;
goto issue_host_reset;
goto issue_target_reset;
}
if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID) {
memcpy(mpi_reply, ioc->config_cmds.reply,
@ -3122,12 +3123,40 @@ mpt2sas_base_get_sata_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
goto out;
issue_host_reset:
if (issue_reset)
mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
FORCE_BIG_HAMMER);
issue_target_reset:
if (issue_reset) {
smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
if (!smid) {
printk(MPT2SAS_ERR_FMT "%s: failed obtaining a tm smid\n",
ioc->name, __func__);
rc = -EAGAIN;
goto out;
}
dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), "
"(open), smid(%d), cb(%d)\n", ioc->name, handle, smid,
ioc->tm_tr_cb_idx));
ioc->config_cmds.status = MPT2_CMD_PENDING;
request = mpt2sas_base_get_msg_frame(ioc, smid);
mpi_request_tm = (Mpi2SCSITaskManagementRequest_t *)request;
memset(mpi_request_tm, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
mpi_request_tm->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
mpi_request_tm->DevHandle = cpu_to_le16(handle);
mpi_request_tm->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
ioc->config_cmds.smid = smid;
mpt2sas_base_put_smid_hi_priority(ioc, smid);
init_completion(&ioc->config_cmds.done);
timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
msecs_to_jiffies(30000));
ioc->config_cmds.status = MPT2_CMD_NOT_USED;
rc = -EFAULT;
memset(mpi_reply, 0, sizeof(Mpi2SataPassthroughReply_t));
}
rc = -EAGAIN;
out:
mutex_unlock(&ioc->config_cmds.mutex);
pci_free_consistent(ioc->pdev, sz, buffer, dma_addr);

View file

@ -8224,7 +8224,6 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
break;
}
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
vmklnx_scsi_target_hot_removed(sas_device->starget);
#endif
_scsih_device_remove_by_handle(ioc, handle);
break;

View file

@ -7,7 +7,7 @@
/*
* Driver version
*/
#define QLA2XXX_VERSION "902.k1.1-11vmw"
#define QLA2XXX_VERSION "902.k1.1-12vmw"
#define QLA_DRIVER_MAJOR_VER 9
#define QLA_DRIVER_MINOR_VER 0

View file

@ -5998,6 +5998,9 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
/* call completion callback */
qc->complete_fn(qc);
#if defined(__VMKLNX__)
ata_restart_waitq(ap);
#endif /* defined(__VMKLNX__) */
}
static void fill_result_tf(struct ata_queued_cmd *qc)
@ -6100,6 +6103,15 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
ata_verify_xfer(qc);
__ata_qc_complete(qc);
#if defined(__VMKLNX__)
/* Fixing PR 1173296 */
if (unlikely((ehi->dev_action[dev->devno] & ATA_EH_REVALIDATE) &&
(ap->pflags & ATA_PFLAG_EH_PENDING))) {
ata_port_printk(ap, KERN_INFO,
"ata_qc_complete, dev needs revalidation, calling EH\n");
wake_up_process(ap->scsi_host->ehandler);
}
#endif /* defined(__VMKLNX__) */
} else {
if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
return;
@ -6951,7 +6963,16 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
DPRINTK("ENTER\n");
#if defined(__VMKLNX__)
struct vmk_ata_all_port_wq *ata_wq;
ap = kzalloc((sizeof(*ap) +
sizeof(struct vmk_ata_all_port_wq)), GFP_KERNEL);
ATA_GET_WAITQ_STRUCT(ap, ata_wq);
ATA_WQ_INIT(ata_wq);
#else
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
#endif /* defined(__VMKLNX__) */
if (!ap)
return NULL;

View file

@ -1110,9 +1110,9 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
spin_unlock_irqrestore(ap->lock, flags);
}
/**
/*
* ata_eh_done - EH action complete
* @ap: target ATA port
* @ap: target ATA port
* @dev: target ATA dev for per-dev action (can be NULL)
* @action: action just completed
*
@ -1263,7 +1263,7 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
return 0;
}
/**
/*
* atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
* @dev: device to perform REQUEST_SENSE to
* @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long)

View file

@ -52,7 +52,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val)
* sata_pmp_write - write PMP register
* @link: link to write PMP register for
* @reg: register to write
* @r_val: value to write
* @val: value to write
*
* Write PMP register.
*
@ -287,7 +287,7 @@ int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class,
/**
* ata_std_postreset - standard postreset method for PMP link
* @link: the target ata_link
* @classes: classes of attached devices
* @class: classes of attached devices
*
* This function is invoked after a successful reset. Note that
* the device might have been reset more than once using

View file

@ -1839,8 +1839,13 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
{
struct ata_port *ap = dev->link->ap;
struct ata_queued_cmd *qc;
int rc;
int rc = 0;
#if defined(__VMKLNX__)
struct vmk_ata_all_port_wq *ata_wq = NULL;
ATA_GET_WAITQ_STRUCT(ap, ata_wq);
#endif /* defined(__VMKLNX__) */
VPRINTK("ENTER\n");
qc = ata_scsi_qc_new(dev, cmd, done);
@ -1877,14 +1882,33 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
if (xlat_func(qc))
goto early_finish;
#if defined(__VMKLNX__)
if (!ATA_WQ_EMPTY(ata_wq)) {
if (!ata_save_waitq(ap, qc)) {
goto noerror_exit;
} else {
goto defer;
}
}
if (ap->ops->qc_defer) {
if ((rc = ap->ops->qc_defer(qc))) {
if (!ata_save_waitq(ap, qc)) {
goto noerror_exit;
} else {
goto defer;
}
}
}
#else
if (ap->ops->qc_defer) {
if ((rc = ap->ops->qc_defer(qc)))
goto defer;
}
#endif /* defined(__VMKLNX__) */
/* select device, send command to hardware */
ata_qc_issue(qc);
noerror_exit:
VPRINTK("EXIT\n");
return 0;
@ -4090,6 +4114,69 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
spin_lock(shost->host_lock);
return rc;
}
#if defined(__VMKLNX__)
/*
* ata_save_waitq
* @ap: ATA port to which the command was being sent
* @qc: command to issue to device
*
* Save qc command into waiting queue list
* because ata_scsi_qc_new can't allocate more than 31
* commands, the waiting queue's depth is not over 31,
* we will hold qc command which is allocate and defered
* by NCQ/Non-NCQ defer.
*
* LOCKING
* spin_lock(ap lock)
*
*/
int ata_save_waitq(struct ata_port *ap, struct ata_queued_cmd *qc)
{
struct vmk_ata_all_port_wq *ata_wq = NULL;
ATA_GET_WAITQ_STRUCT(ap, ata_wq);
if (ATA_WQ_FULL(ata_wq))
return -1;
ATA_WQ_ADD(ata_wq, qc);
return 0;
}
/*
* ata_restart_waitq
* @ap: ATA port to which the command was being sent
*
* start waiting queue work and try to issue command
*
* LOCKING
* spin_lock(ap lock)
*
*/
void ata_restart_waitq(struct ata_port *ap)
{
struct vmk_ata_all_port_wq *ata_wq = NULL;
struct ata_queued_cmd *qc = NULL;
int rc = 0;
ATA_GET_WAITQ_STRUCT(ap, ata_wq);
ATA_WQ_HEAD(ata_wq, qc);
while (qc != NULL) {
if (ap->ops->qc_defer) {
if ((rc = ap->ops->qc_defer(qc))) {
return;
}
}
ATA_WQ_REMOVE(ata_wq, qc);
ata_qc_issue(qc);
ATA_WQ_HEAD(ata_wq, qc);
}
return;
}
#endif /* defined(__VMKLNX__) */
/**
* ata_scsi_simulate - simulate SCSI command on ATA device

View file

@ -38,6 +38,59 @@ struct ata_scsi_args {
void (*done)(struct scsi_cmnd *);
};
#if defined(__VMKLNX__)
#define ATA_WAITQ_ARRAY_SIZE ATA_MAX_QUEUE
struct vmk_ata_all_port_wq {
struct ata_queued_cmd *qc[ATA_WAITQ_ARRAY_SIZE];
int head;
int tail;
int count;
};
#define ATA_GET_WAITQ_STRUCT(ap, ata_wq) \
do { \
ata_wq = (struct vmk_ata_all_port_wq *)((void *)(ap) \
+ sizeof(*ap)); \
} while (0)
#define ATA_WQ_INIT(wq) \
do { \
(wq)->head = (wq)->tail = (wq)->count = 0; \
} while (0)
#define ATA_WQ_FULL(wq) ((wq)->count == ATA_WAITQ_ARRAY_SIZE)
#define ATA_WQ_EMPTY(wq) ((wq)->count == 0)
#define ATA_WQ_ADD(wq, qc) \
do { \
(wq)->qc[(wq)->tail++] = qc; \
if ((wq)->tail >= ATA_WAITQ_ARRAY_SIZE) { \
(wq)->tail = 0; \
} \
(wq)->count++; \
} while (0)
#define ATA_WQ_REMOVE(wq, qc) \
do { \
qc = (wq)->qc[(wq)->head++]; \
if ((wq)->head >= ATA_WAITQ_ARRAY_SIZE) { \
(wq)->head = 0; \
} \
(wq)->count--; \
} while (0)
#define ATA_WQ_HEAD(wq, qc) \
do { \
qc = (wq)->qc[(wq)->head]; \
if ((wq)->count == 0) { \
qc = NULL; \
} \
} while (0)
#endif /* defined(__VMKLNX__) */
/* libata-core.c */
enum {
/* flags for ata_dev_read_id() */
@ -53,6 +106,14 @@ enum {
ATA_DNXFER_QUIET = (1 << 31),
};
#if defined(__VMKLNX__)
int ata_save_waitq(struct ata_port *ap, struct ata_queued_cmd *qc);
extern void ata_restart_waitq(struct ata_port *ap);
extern void ata_waitq_delete_all(struct ata_port *ap);
#endif /* defined(__VMKLNX__) */
extern unsigned int ata_print_id;
extern struct workqueue_struct *ata_aux_wq;
extern int atapi_enabled;

View file

@ -495,6 +495,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
/**
* fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it
* @fip: The FCoE controller for the ELS frame
* @lport: local port
* @dtype: The FIP descriptor type for the frame
* @skb: The FCoE ELS frame including FC header but no FCoE headers
*
@ -1532,6 +1533,7 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
/**
* fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response
* @fip: The FCoE controller
* @lport: not in use
* @fp: The FC frame to snoop
*
* Snoop potential response to FLOGI or even incoming FLOGI.
@ -1648,7 +1650,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
/**
* fcoe_libfc_config() - Sets up libfc related properties for local port
* @lp: The local port to configure libfc for
* @lport: The local port to configure libfc for
* @tt: The libfc function template
*
* Returns : 0 for success

View file

@ -76,6 +76,7 @@ void fc_disc_stop_rports(struct fc_disc *disc)
* fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN)
* @sp: The sequence of the RSCN exchange
* @fp: The RSCN frame
* @disc: The discovery context of local port.
* @lport: The local port that the request will be sent on
*
* Locking Note: This function expects that the disc_mutex is locked
@ -342,9 +343,9 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
}
}
/**
/*
* fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request
* @lport: The discovery context
* @disc: The discovery context
*
* Locking Note: This function expects that the disc_mutex is locked
* before it is called.
@ -376,9 +377,9 @@ err:
fc_disc_error(disc, NULL);
}
/**
/*
* fc_disc_gpn_ft_parse() - Parse the body of the dNS GPN_FT response.
* @lport: The local port the GPN_FT was received on
* @disc: The discovery context
* @buf: The GPN_FT response buffer
* @len: The size of response buffer
*
@ -495,11 +496,11 @@ static void fc_disc_timeout(struct work_struct *work)
mutex_unlock(&disc->disc_mutex);
}
/**
/*
* fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT)
* @sp: The sequence that the GPN_FT response was received on
* @fp: The GPN_FT response frame
* @lp_arg: The discovery context
* @disc_arg: The discovery context
*
* Locking Note: This function is called without disc mutex held, and
* should do all its processing with the mutex held

View file

@ -615,7 +615,7 @@ err:
/**
* fc_fcp_send_data() - Send SCSI data to a target
* @fsp: The FCP packet the data is on
* @sp: The sequence the data is to be sent on
* @seq: The sequence the data is to be sent on
* @offset: The starting offset for this data request
* @seq_blen: The burst length for this data request
*
@ -1767,7 +1767,7 @@ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp)
fc_fcp_send_abort(fsp);
}
/**
/*
* fc_fcp_srr() - Send a SRR request (Sequence Retransmission Request)
* @fsp: The FCP packet the SRR is to be sent on
* @r_ctl: The R_CTL field for the SRR request
@ -1912,7 +1912,7 @@ static inline int fc_fcp_lport_queue_ready(struct fc_lport *lport)
/**
* fc_queuecommand() - The queuecommand function of the SCSI template
* @cmd: The scsi_cmnd to be executed
* @sc_cmd: The scsi_cmnd to be executed
* @done: The callback function to be called when the scsi_cmnd is complete
*
* This is the i/o strategy routine, called by the SCSI layer. This routine

View file

@ -406,7 +406,7 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
/**
* fc_lport_recv_echo_req() - Handle received ECHO request
* @sp: The sequence in the ECHO exchange
* @fp: ECHO request frame
* @in_fp: ECHO request frame
* @lport: The local port recieving the ECHO
*
* Locking Note: The lport lock is expected to be held before calling
@ -448,7 +448,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
/**
* fc_lport_recv_rnid_req() - Handle received Request Node ID data request
* @sp: The sequence in the RNID exchange
* @fp: The RNID request frame
* @in_fp: The RNID request frame
* @lport: The local port recieving the RNID
*
* Locking Note: The lport lock is expected to be held before calling
@ -1205,9 +1205,10 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
fc_lport_error(lport, NULL);
}
/**
/*
* fc_lport_enter_ns() - register some object with the name server
* @lport: Fibre Channel local port to register
* @state: local port state
*
* Locking Note: The lport lock is expected to be held before calling
* this routine.
@ -1705,6 +1706,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
* @job: The BSG Passthrough job
* @lport: The local port sending the request
* @did: The destination port id
* @tov: The timeout period for the frame (in msecs)
*
* Locking Note: The lport lock is expected to be held before calling
* this routine.

View file

@ -109,6 +109,7 @@ static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
/**
* fc_rport_create() - Create a new remote port
* @lport: The local port this remote port will be associated with
* @port_id: The remote port ID to be created.
* @ids: The identifiers for the new remote port
*
* The remote port will start in the INIT state.

View file

@ -18,8 +18,8 @@
#endif
#include "pci-quirks.h"
#if defined(__VMKLNX__)
#include "../host/xhci/xhci-ext-caps.h"
#else
//#include "../host/xhci/xhci-ext-caps.h"
//#else
#include "xhci-ext-caps.h"
#endif

View file

@ -994,7 +994,7 @@ static inline int ata_id_is_cfa(const u16 *id)
/**
* ata_drive_40wire - Check if device is a 40 wire IDE drive
* @id: the pointer to IDENTIFY DEVICE data
* @dev_id: the pointer to IDENTIFY DEVICE data
*
* Check if the device is a compact flash device.
*
@ -1053,7 +1053,7 @@ static inline int atapi_id_dmadir(const u16 *dev_id)
/**
* ata_set_lba_range_entries - Construct TRIM command data buffer
* @_buffer: TRIM data buffer
* @buf_zie: data buffer size
* @buf_size: data buffer size
* @sector: starting sector to be TRIMed
* @count: number of sectors
*

View file

@ -41,6 +41,16 @@ struct fc_ct_req {
/**
* fill FC header fields in specified fc_frame
* @fp: fc frame where header will be placed.
* @r_ctl: pointer to FC header R_CTL.
* @did: FC destination ID.
* @sid: FC source ID.
* @type: pointer to FC-4 type.
* @f_ctl: pointer to FC header F_CTL.
* @parm_offset: parameter offset.
*
* RETURN VALUE:
* None.
*/
/* _VMKLNX_CODECHECK_: fc_fill_fc_hdr */
static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
@ -81,7 +91,12 @@ static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
/**
* fc_ct_hdr_fill- fills ct header and reset ct payload
* returns pointer to ct request.
* @fp: fc frame where ct header be placed.
* @op: CT opcode.
* @req_size: size of request frame.
*
* RETURN VALUE:
* pointer to ct request.
*/
static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
unsigned int op, size_t req_size)
@ -180,10 +195,13 @@ static inline int fc_ct_fill(struct fc_lport *lport,
return 0;
}
/**
/*
* fc_plogi_fill - Fill in plogi request frame
*
* @lport: local port.
* @fp: fc frame where plogi request frame be placed.
* @op: opcode.
*/
/* _VMKLNX_CODECHECK_: fc_plogi_fill */
static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
unsigned int op)
{
@ -214,8 +232,11 @@ static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
cp->cp_open_seq = 1;
}
/**
/*
* fc_flogi_fill - Fill in a flogi request frame.
*
* @lport: local port
* @fp: fc frame where flogi request frame be placed.
*/
static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
{
@ -239,8 +260,11 @@ static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
sp->sp_features = htons(FC_SP_FT_NPIV);
}
/**
/*
* fc_fdisc_fill - Fill in a fdisc request frame.
*
* @lport: local port.
* @fp: fc frame where fdisc request frame be placed.
*/
static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
{
@ -262,8 +286,11 @@ static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp)
cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
}
/**
/*
* fc_logo_fill - Fill in a logo request frame.
*
* @lport: local port
* @fp: fc frame where logo request frame be placed.
*/
static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
{
@ -276,8 +303,11 @@ static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
logo->fl_n_port_wwn = htonll(lport->wwpn);
}
/**
/*
* fc_rtv_fill - Fill in RTV (read timeout value) request frame.
*
* @lport: local port
* @fp: fc frame where RTV request frame be placed.
*/
static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
{
@ -288,8 +318,11 @@ static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
rtv->rtv_cmd = ELS_RTV;
}
/**
/*
* fc_rec_fill - Fill in rec request frame
*
* @lport: local port
* @fp: fc frame where rec request frame be placed.
*/
static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
{
@ -304,8 +337,12 @@ static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
rec->rec_rx_id = htons(ep->rxid);
}
/**
/*
* fc_prli_fill - Fill in prli request frame
*
* @lport: local port
* @fp: fc frame where prli request frame be placed.
*
*/
static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
{
@ -324,8 +361,12 @@ static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
pp->spp.spp_params = htonl(lport->service_params);
}
/**
/*
* fc_scr_fill - Fill in a scr request frame.
*
* @lport: local port
* @fp: fc frame where scr request frame be placed.
*
*/
static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
{
@ -337,8 +378,18 @@ static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
scr->scr_reg_func = ELS_SCRF_FULL;
}
/**
/*
* fc_els_fill - Fill in an ELS request frame
* @lport: local port.
* @did: not in use.
* @fp: fc frame where ELS request frame be placed.
* @op: operation code.
* @r_ctl: pointer to ELS request R_CTL.
* @fh_type: pointer to ELS type.
*
* RETURN VALUE:
* 0 on success.
* -EINVAL on failed.
*/
/* _VMKLNX_CODECHECK_: fc_els_fill */
static inline int fc_els_fill(struct fc_lport *lport,

View file

@ -72,12 +72,15 @@
p[2] = ((v) & 0xFF); \
} while (0)
/**
/*
* enum fc_lport_state - Local port states
* @LPORT_ST_DISABLED: Disabled
* @LPORT_ST_FLOGI: Fabric login (FLOGI) sent
* @LPORT_ST_DNS: Waiting for name server remote port to become ready
* @LPORT_ST_RPN_ID: Register port name by ID (RPN_ID) sent
* @LPORT_ST_RNN_ID:
* @LPORT_ST_RSNN_NN:
* @LPORT_ST_RSPN_ID:
* @LPORT_ST_RFT_ID: Register Fibre Channel types by ID (RFT_ID) sent
* @LPORT_ST_RFF_ID: Register FC-4 Features by ID (RFF_ID) sent
* @LPORT_ST_SCR: State Change Register (SCR) sent
@ -194,7 +197,7 @@ struct fc_rport_libfc_priv {
unsigned int r_a_tov;
};
/**
/*
* struct fc_rport_priv - libfc remote port and discovery info
* @local_port: The associated local port
* @rport: The FC transport remote port
@ -212,6 +215,13 @@ struct fc_rport_libfc_priv {
* @r_a_tov: Resource allocation timeout value (in msec)
* @rp_mutex: The mutex that protects the remote port
* @retry_work: Handle for retries
* @event:
* @ops:
* @peers:
* @event_work:
* @sp_features:
* @spp_type:
* @supported_classes:
* @event_callback: Callback when READY, FAILED or LOGO states complete
*/
struct fc_rport_priv {
@ -304,7 +314,7 @@ struct fc_seq_els_data {
enum fc_els_rjt_explan explan;
};
/**
/*
* struct fc_fcp_pkt - FCP request structure (one for each scsi_cmnd request)
* @lp: The associated local port
* @state: The state of the I/O
@ -338,6 +348,8 @@ struct fc_seq_els_data {
* @seq_ptr: The sequence that will carry the SCSI command
* @recov_retry: Number of recovery retries
* @recov_seq: The sequence for REC or SRR
* @sg:
* @vmksgel:
*/
struct fc_fcp_pkt {
/* Housekeeping information */
@ -800,7 +812,7 @@ struct libfc_function_template {
* struct fc_disc - Discovery context
* @retry_count: Number of retries
* @pending: 1 if discovery is pending, 0 if not
* @requesting: 1 if discovery has been requested, 0 if not
* @requested: 1 if discovery has been requested, 0 if not
* @seq_count: Number of sequences used for discovery
* @buf_len: Length of the discovery buffer
* @disc_id: Discovery ID
@ -830,7 +842,7 @@ struct fc_disc {
enum fc_disc_event);
};
/**
/*
* struct fc_lport - Local port
* @host: The SCSI host associated with a local port
* @ema_list: Exchange manager anchor list
@ -864,6 +876,8 @@ struct fc_disc {
* @mfs: The maximum Fibre Channel payload size
* @max_retry_count: The maximum retry attempts
* @max_rport_retry_count: The maximum remote port retry attempts
* @link_speed:
* @link_supported_speeds:
* @lro_xid: The maximum XID for LRO
* @lso_max: The maximum large offload send size
* @fcts: FC-4 type mask

View file

@ -55,7 +55,7 @@ enum fip_state {
FIP_ST_ENABLED,
};
/**
/*
* struct fcoe_ctlr - FCoE Controller and FIP state
* @state: internal FIP state for network link and FIP or non-FIP mode.
* @mode: LLD-selected mode.
@ -74,12 +74,14 @@ enum fip_state {
* @user_mfs: configured maximum FC frame size, including FC header.
* @flogi_oxid: exchange ID of most recent fabric login.
* @flogi_count: number of FLOGI attempts in AUTO mode.
* @reset_req:
* @map_dest: use the FC_MAP mode for destination MAC addresses.
* @spma: supports SPMA server-provided MACs mode
* @send_ctlr_ka: need to send controller keep alive
* @send_port_ka: need to send port keep alives
* @dest_addr: MAC address of the selected FC forwarder.
* @ctl_src_addr: the native MAC address of our local port.
* @vlan_id:
* @send: LLD-supplied function to handle sending FIP Ethernet frames
* @update_mac: LLD-supplied function to handle changes to MAC addresses.
* @get_src_addr: LLD-supplied function to supply a source MAC address.
@ -132,7 +134,7 @@ struct fcoe_ctlr {
spinlock_t lock;
};
/**
/*
* struct fcoe_fcf - Fibre-Channel Forwarder
* @list: list linkage
* @time: system time (jiffies) when an advertisement was last received
@ -144,6 +146,7 @@ struct fcoe_ctlr {
* @pri: selection priority, smaller values are better
* @flags: flags received from advertisement
* @fka_period: keep-alive period, in jiffies
* @fd_flags:
*
* A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that
* passes FCoE frames on to an FC fabric. This structure represents

View file

@ -248,6 +248,8 @@ static inline int scsi_get_resid(struct scsi_cmnd *cmd)
* scsi_for_each_sg - Loop over scsi_cmd's SG list
* @cmd: a pointer to struct scsi_cmnd
* @nseg: number of elements in the list
* @sg: scatter-gather list
* @__i: index of sg element
*
* Loop over @cmd scsi_cmd's SG list.
*

View file

@ -108,17 +108,16 @@ static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth)
/**
* scsi_deactivate_tcq - turn off tag command queueing
* @SDpnt: device to turn off TCQ for
*
* Turns off tag command queueing
*
* ESX Deviation Notes:
* blk layer is not supported/affected.
* @sdev: SCSI Device to turn off TCQ for
* @depth: number of commands the low level driver can queue up in non-tagged mode.
*
* RETURN VALUE:
* None
*
* ESX Deviation Notes:
* blk layer is not supported/affected.
*/
/* _VMKLNX_CODECHECK_: scsi_deactivate_tcq */
/* _VMKLNX_CODECHECK_: scsi_deactivate_tcq*/
static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
{
#if !defined(__VMKLNX__)
@ -130,7 +129,7 @@ static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
/**
* scsi_populate_tag_msg - place a tag message in a buffer
* @SCpnt: pointer to the Scsi_Cmnd for the tag
* @cmd: pointer to the Scsi_Cmnd for the tag
* @msg: pointer to the area to place the tag
*
* Create the correct type of tag message for the
@ -190,14 +189,14 @@ static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
#endif
}
/**
/*
* scsi_find_tag - find a tagged command by device
* @SDpnt: pointer to the ScSI device
* @sdev: pointer to the SCSI device
* @tag: the tag number
*
* Notes:
* Only works with tags allocated by the generic blk layer.
**/
*/
static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
{
@ -212,7 +211,7 @@ static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
return sdev->current_cmnd;
}
/**
/*
* scsi_init_shared_tag_map - create a shared tag map
* @shost: the host to share the tag map among all devices
* @depth: the total depth of the map

View file

@ -502,14 +502,14 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
complete(eh_action);
}
/**
/*
* scsi_send_eh_cmnd - send a cmd to a device as part of error recovery.
* @scmd: SCSI Cmd to send.
* @timeout: Timeout for cmd.
*
* Return value:
* SUCCESS or FAILED or NEEDS_RETRY
**/
*/
static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
int cmnd_size, int timeout, int copy_sense)
{
@ -842,7 +842,7 @@ retry_tur:
}
}
/**
/*
* scsi_eh_abort_cmds - abort canceled commands.
* @shost: scsi host being recovered.
* @eh_done_q: list_head for processed commands.
@ -853,7 +853,7 @@ retry_tur:
* command that has timed out. if the command simply failed, it makes
* no sense to try and abort the command, since as far as the shost
* adapter is concerned, it isn't running.
**/
*/
static int scsi_eh_abort_cmds(struct list_head *work_q,
struct list_head *done_q)
{
@ -990,17 +990,17 @@ static int scsi_eh_stu(struct Scsi_Host *shost,
}
/**
/*
* scsi_eh_bus_device_reset - send bdr if needed
* @shost: scsi host being recovered.
* @eh_done_q: list_head for processed commands.
* @done_q: list_head for processed commands.
*
* Notes:
* Try a bus device reset. still, look to see whether we have multiple
* devices that are jammed or not - if we have multiple devices, it
* makes no sense to try bus_device_reset - we really would need to try
* a bus_reset instead.
**/
*/
static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
struct list_head *work_q,
struct list_head *done_q)
@ -1115,11 +1115,11 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
return rtn;
}
/**
/*
* scsi_eh_bus_reset - send a bus reset
* @shost: scsi host being recovered.
* @eh_done_q: list_head for processed commands.
**/
*/
static int scsi_eh_bus_reset(struct Scsi_Host *shost,
struct list_head *work_q,
struct list_head *done_q)
@ -1500,12 +1500,12 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
}
#if !defined(__VMKLNX__)
/**
/*
* scsi_eh_ready_devs - check device ready state and recover if not.
* @shost: host to be recovered.
* @eh_done_q: list_head for processed commands.
*
**/
*/
static void scsi_eh_ready_devs(struct Scsi_Host *shost,
struct list_head *work_q,
struct list_head *done_q)

View file

@ -2707,7 +2707,7 @@ __generic_unplug_device(request_queue_t *q, void *data)
VMKAPI_MODULE_CALL_VOID(BLOCK_GET_ID(dev), q->request_fn, q);
}
/**
/*
* generic_unplug_device - fire a request queue
* @q: The &request_queue_t in question
*
@ -2717,7 +2717,7 @@ __generic_unplug_device(request_queue_t *q, void *data)
* is still adding and merging requests on the queue. Once the queue
* gets unplugged, the request_fn defined for the queue is invoked and
* transfers started.
**/
*/
void
generic_unplug_device(request_queue_t *q, void *data)
{

View file

@ -179,6 +179,11 @@ LinuxPCILegacyIntrVectorSet(LinuxPCIDevExt *pciDevExt)
if (status != VMK_OK) {
VMKLNX_WARN("Could not allocate legacy PCI interrupt for device %s",
pciDevExt->linuxDev.dev.bus_id);
/*
* Ensure that the irq field is set to zero to indicate not to
* attempt to free the interrupt cookie.
*/
pciDevExt->linuxDev.irq = 0;
return;
}
@ -196,6 +201,17 @@ LinuxPCIIntrVectorFree(LinuxPCIDevExt *pciDevExt)
vmk_IntrCookie intrCookie;
VMK_ReturnStatus status;
/*
* Check whether the device even has a currently valid,
* allocated interrupt. We attempt to allocate a legacy interrupt
* on device-insert, but not all devices support legacy interrupts.
*/
if (pciDevExt->linuxDev.irq == 0) {
VMK_ASSERT(pciDevExt->linuxDev.msi_enabled == 0);
return;
}
/*
* Get the associated intrCookie for the irq.
*/
@ -494,14 +510,13 @@ LinuxPCIDeviceRemoved(vmk_PCIDevice vmkDev)
VMKAPI_MODULE_CALL_VOID(pciDevExt->moduleID, devres_release_all, &linuxDev->dev);
}
/* free the legacy interrupt setup during LinuxPCIDeviceInserted() */
LinuxPCIIntrVectorFree(pciDevExt);
linuxDev->driver = NULL;
linuxDev->dev.driver = NULL;
LinuxPCI_DeviceUnclaimed(pciDevExt);
quit:
/* free the legacy interrupt setup during LinuxPCIDeviceInserted() */
LinuxPCIIntrVectorFree(pciDevExt);
/*
* If device is physically removed, free up the structures. Otherwise,
@ -727,8 +742,8 @@ LinuxPCI_EnableMSI(struct pci_dev* dev)
VMK_ASSERT(pciDevExt->vmkDev);
/*
* Remove the previous legacy interrupt before requesting
* MSI interrupt.
* Remove the previous legacy interrupt, if it exists,
* before requesting MSI interrupt.
*/
LinuxPCIIntrVectorFree(pciDevExt);

View file

@ -155,24 +155,6 @@ static void scsi_offline_device(struct scsi_device *sdev);
static void vmklnx_scsi_update_lun_path(struct scsi_device *sdev, void *data);
static inline void vmklnx_init_scmd(struct scsi_cmnd *scmd, struct scsi_device *dev);
/**
**********************************************************************
* \globalfn scsi_host_alloc -- allocate a SCSI Host structure
*
* \param pointer to scsi host template
* \param additional size to be allocated as requested by the driver
* \return On Success pointer to newly allocated Scsi_Host structure
* \par Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
* This interface will assume a default value for
* Scsi_Host->dma_boundary to be 0 if the Scsi Host template does
* not specify a value for dma_boundary. This is different from
* the linux behavior which defaults to a 4G boundary in a similar
* situation.
* \sa None.
**********************************************************************
*/
/**
* scsi_host_alloc - allocate a Scsi_Host structure
* @sht: pointer to scsi host template
@ -316,18 +298,18 @@ failed_sh_alloc:
EXPORT_SYMBOL(scsi_host_alloc);
/**
**********************************************************************
* \internalfn scsi_setup_command_freelist -- Setup the command freelist
* Setup the command freelist
* @sh: host to allocate the freelist for
*
* \param shost - host to allocate the freelist for
* \return 0 on success
* \par Include:
* RETURN VALUE:
* 0 on success
*
* Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
*
* ESX Deviation Notes:
* Our scsi_cmnd cache also includes space for the maximally sized
* scatterlist array.
* \sa None.
**********************************************************************
*/
static int scsi_setup_command_freelist(struct Scsi_Host *sh)
{
@ -929,17 +911,6 @@ void vmklnx_scsi_register_poll_handler(struct Scsi_Host *sh,
}
EXPORT_SYMBOL(vmklnx_scsi_register_poll_handler);
/**
**********************************************************************
* \globalfn vmklnx_scsi_set_path_maxsectors --
* Set the max. transfer size for a path
*
* \param[in] sdev - the scsi_device struct representing the target path
* \param[in] max_sectors - the max. transfer size in 512-byte sectors
* \return None
*
**********************************************************************
*/
/**
* vmklnx_scsi_set_path_maxsectors - set the max transfer size for a path
* @sdev: a pointer to scsi_device struct representing the target path
@ -971,18 +942,15 @@ vmklnx_scsi_set_path_maxsectors(struct scsi_device *sdev,
EXPORT_SYMBOL(vmklnx_scsi_set_path_maxsectors);
/**
**********************************************************************
* \internalfn scsi_destroy_command_freelist -- Release the command freelist
* scsi_destroy_command_freelist -- Release the command freelist
* for a scsi host
* @sh: host that's freelist is going to be destroyed
*
* \param shost - host that's freelist is going to be destroyed
* \return None
* \par Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
* RETURN VALUE:
* None
* \sa None.
**********************************************************************
*
* Include:
* scsi/scsi_host.h
*/
static void
scsi_destroy_command_freelist(struct Scsi_Host *sh)
@ -1004,9 +972,8 @@ scsi_destroy_command_freelist(struct Scsi_Host *sh)
}
/*
* \sa All scanning functions needs PSA backend support. Will depend on
* All scanning functions needs PSA backend support. Will depend on
* completion of PR166189
**********************************************************************
*/
/**
* scsi_scan_host - issue wild card scan for the given SCSI host
@ -1097,8 +1064,6 @@ scsi_scan_host(struct Scsi_Host *sh)
EXPORT_SYMBOL(scsi_scan_host);
/*
*----------------------------------------------------------------------
*
* vmklnx_scsi_update_lun_path --
*
* Callback function used in scsi_scan_target which updates
@ -1109,8 +1074,6 @@ EXPORT_SYMBOL(scsi_scan_host);
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
static void
vmklnx_scsi_update_lun_path(struct scsi_device *sdev, void *data)
@ -1212,18 +1175,14 @@ target_scan:
EXPORT_SYMBOL(scsi_scan_target);
/**
**********************************************************************
* \globalfn scsi_register -- Old style passive scsi registration
* Old style passive scsi registration
* @sht: scsi_host_template
* @privsize: private size
*
* \param scsi_host_template, privatesize
* \return None
* \par Include:
*
* \par ESX Deviation Notes:
*
* \sa None.
**********************************************************************
* RETURN VALUE:
* None
*/
/* _VMKLNX_CODECHECK_: scsi_register*/
struct Scsi_Host *
scsi_register(struct scsi_host_template *sht, int privsize)
{
@ -1245,17 +1204,11 @@ scsi_register(struct scsi_host_template *sht, int privsize)
}
/**
**********************************************************************
* \globalfn scsi_unregister -- Old style passive scsi unregistration
* Old style passive scsi unregistration
* @sh: scsi_host_template
*
* \param scsi_host_template, privatesize
* \return None
* \par Include:
*
* \par ESX Deviation Notes:
*
* \sa None.
**********************************************************************
* RETURN VALUE:
* None
*/
void
scsi_unregister(struct Scsi_Host *sh)
@ -1271,19 +1224,17 @@ scsi_unregister(struct Scsi_Host *sh)
}
/**
**********************************************************************
* \globalfn ScsiModifyQueueDepth -- Called by drivers to notify the vmkernel
* Called by drivers to notify the vmkernel
* of the new queue Depth.
*
* \param arg - work queue payload containing vmkAdapter, channel, id, lun,
* @work: work queue payload containing vmkAdapter, channel, id, lun,
* queue depth
* \return None
* \par Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
*
* RETURN VALUE:
* None
* \sa None
**********************************************************************
*
* Include:
* scsi/scsi_host.h
*/
static void
vmklnx_scsi_modify_queue_depth(struct work_struct *work)
@ -1424,6 +1375,7 @@ EXPORT_SYMBOL(scsi_adjust_queue_depth);
* @channel: channel number
* @id: target id number
* @lun: logical unit number
* @hostdata: passed to scsi_alloc_sdev()
*
* Create new scsi device instance
*
@ -1708,6 +1660,11 @@ EXPORT_SYMBOL(scsi_bios_ptable);
/**
* scsi_partsize - non-operational function in release build.
* @buf: partition table, see scsi_bios_ptable
* @capacity: size of the disk in sector
* @cyls: cylinders
* @hds: heads
* @secs: sectors
*
* This is a non-operational function in release build, but can cause panic if being called in non-release mode.
*
@ -1733,18 +1690,20 @@ scsi_partsize(unsigned char *buf, unsigned long capacity,
EXPORT_SYMBOL(scsi_partsize);
/**
**********************************************************************
* \internalfn vmklnx_scsi_alloc_target_conditionally -- Allocate a target
/*
* vmklnx_scsi_alloc_target_conditionally -- Allocate a target
*
* \param parent, channel, id
* \return None
* \par Include:
* @parent: parent of the target (need not be a scsi host)
* @channel: target channel number (zero if no channels)
* @id: target id number
* @force_alloc_flag: if set, force to allocate scsi target.
* @old_target: output value. set as 1 if target already exists, 0 else.
*
* RETURN VALUE
* Pointer to an existing scsi target or a new scsi target.
*
* Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
* Needs
* \sa None.
**********************************************************************
*/
struct scsi_target *
vmklnx_scsi_alloc_target_conditionally(struct device *parent, int channel, uint id,
@ -1818,16 +1777,13 @@ alloc_and_return:
}
/**
**********************************************************************
* \internalfn scsi_alloc_target -- Allocate a new or find an existing target
* Allocate a new or find an existing target
* @parent: parent of the target (need not be a scsi host)
* @channel: target channel number (zero if no channels)
* @id: target id number
*
* \param parent, channel, id
* \return None
* \par Include:
* \par ESX Deviation Notes:
* Needs
* \sa None.
**********************************************************************
* RETURN VALUE:
* Pointer to scsi target
*/
struct scsi_target *
vmklnx_scsi_alloc_target(struct device *parent, int channel, uint id)
@ -1840,7 +1796,7 @@ EXPORT_SYMBOL(vmklnx_scsi_alloc_target);
EXPORT_SYMBOL_ALIASED(vmklnx_scsi_alloc_target, scsi_alloc_target);
/**
* scsi_alloc_target - Allocate a new or find an existing target
* Allocate a new or find an existing target
* @parent: parent device
* @channel: target id
* @id: target id
@ -1848,7 +1804,7 @@ EXPORT_SYMBOL_ALIASED(vmklnx_scsi_alloc_target, scsi_alloc_target);
* Allocate a new or find an existing target
*
* RETURN VALUE:
* scsi_target.
* pointer to scsi target.
*/
/* _VMKLNX_CODECHECK_: scsi_alloc_target */
struct scsi_target *
@ -1948,17 +1904,16 @@ scsi_alloc_target(struct device *parent, int channel, uint id)
}
/**
**********************************************************************
* \internalfn vmklnx_scsi_find_target -- Find a matching target
* Find a matching target
* @sh: scsi host
* @channel: target id
* @id: target id
*
* \param sh, channel, id
* \return None
* \par Include:
* RETURN VALUE:
* None
*
* Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
* Needs
* \sa None.
**********************************************************************
*/
struct scsi_target *
vmklnx_scsi_find_target(struct Scsi_Host *sh,
@ -1983,20 +1938,17 @@ vmklnx_scsi_find_target(struct Scsi_Host *sh,
EXPORT_SYMBOL(vmklnx_scsi_find_target);
/**
**********************************************************************
* \globalfn __scsi_device_lookup_by_target -- Find a matching device
/*
* Find a matching device
* for given target
*
* \param starget, lun
* \return None
* \par Include:
* RETURN VALUE:
* None
*
* Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
* Needs
* \sa None.
* \comments - Usually called from interrupt context
**********************************************************************
*
* comments - Usually called from interrupt context
*/
struct scsi_device *
__scsi_device_lookup_by_target(struct scsi_target *starget, uint lun)
@ -2012,7 +1964,7 @@ __scsi_device_lookup_by_target(struct scsi_target *starget, uint lun)
}
/**
* scsi_device_lookup_by_target - find a device given the target
* find a device given the target
* @starget: SCSI target pointer
* @lun: Logical Unit Number
*
@ -2046,20 +1998,20 @@ EXPORT_SYMBOL(scsi_device_lookup_by_target);
/**
**********************************************************************
* \globalfn scsi_alloc_sdev -- Allocate and set up a scsi device
* Allocate and set up a scsi device
* @starget: which target to allocate a scsi_device for
* @lun: which lun
* @hostdata: usually NULL and set by ->slave_alloc instead
*
* \param starget, lun, hostdata
* \return On failure to alloc sdev, return NULL
* RETURN VALUE:
* return On failure to alloc sdev, return NULL
* On other failures, return ERR_PTR(-errno)
* On Success, return pointer to sdev (which fails IF_ERR)
* \par Include:
*
* Include:
* scsi/scsi_device.h
* \par ESX Deviation Notes:
* Needs
* \sa None.
* \comments - Gets the device ready for IO
**********************************************************************
*
* comments - Gets the device ready for IO
*/
struct scsi_device *
scsi_alloc_sdev(struct scsi_target *starget, unsigned int lun, void *hostdata)
@ -2181,18 +2133,16 @@ out_device_del:
}
/**
**********************************************************************
* \globalfn scsi_destroy_sdev -- Destroy a scsi device
* scsi_destroy_sdev -- Destroy a scsi device
* @sdev: sdevice
*
* \param sdevice
* \return Pointer to sdev
* \par Include:
* RETURN VALUE:
* Pointer to sdev
*
* Include:
* scsi/scsi_device.h
* \par ESX Deviation Notes:
* Needs
* \sa None.
* \comments - Removes from all the lists as well
**********************************************************************
*
* comments - Removes from all the lists as well
*/
void
scsi_destroy_sdev(struct scsi_device *sdev)
@ -2211,19 +2161,20 @@ scsi_destroy_sdev(struct scsi_device *sdev)
}
/**
**********************************************************************
* \globalfn __scsi_device_lookup -- Look up for a scsi device given BTL
/*
* __scsi_device_lookup -- Look up for a scsi device given BTL
* @sh: SCSI host pointer
* @channel: SCSI channel (zero if only one channel)
* @id: SCSI target number (physical unit number)
* @lun: SCSI Logical Unit Number
*
* \param sh, channel, id, lun
* \return Pointer to sdev
* \par Include:
* RETURN VALUE:
* Pointer to scsi device
*
* Include:
* scsi/scsi_device.h
* \par ESX Deviation Notes:
* Needs
* \sa None.
* \comments - Called from IRQ context or with lock held
**********************************************************************
*
* comments - Called from IRQ context or with lock held
*/
struct scsi_device *
__scsi_device_lookup(struct Scsi_Host *sh, uint channel, uint id, uint lun)
@ -2272,18 +2223,16 @@ EXPORT_SYMBOL(scsi_device_lookup);
/**
**********************************************************************
* \globalfn __scsi_get_command -- Return a Scsi_Cmnd
* __scsi_get_command -- Return a Scsi_Cmnd
*
* \param sh, mask
* \return Pointer to sdev
* \par Include:
* @sh: scsi host
* @gfp_mask: allocator flags
*
* RETURN VALUE:
* Pointer to sdev
*
* Include:
* scsi/scsi_device.h
* \par ESX Deviation Notes:
* Needs
* \sa None.
* \comments -
**********************************************************************
*/
struct scsi_cmnd *
__scsi_get_command(struct Scsi_Host *sh, gfp_t gfp_mask)
@ -2925,17 +2874,15 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
EXPORT_SYMBOL(scsi_host_lookup);
/**
**********************************************************************
* \internalfn scsi_forget_host -- Notify all LUNs that a host is going down
* scsi_forget_host -- Notify all LUNs that a host is going down
*
* \param shost - host that is being removed
* \return None
* \par Include:
* scsi/scsi_host.h
* \par ESX Deviation Notes:
* @sh: host that is being removed
*
* RETURN VALUE:
* None
* \sa None.
**********************************************************************
*
* Include:
* scsi/scsi_host.h
*/
static void scsi_forget_host(struct Scsi_Host *sh)
{
@ -3069,7 +3016,7 @@ EXPORT_SYMBOL(scsi_execute_req);
* @timeout: command timeout
* @retries: number of retries before failing
* @data: returns a structure abstracting the mode header data
* @sense: place to put sense data (or NULL if no sense to be collected).
* @sshdr: place to put sense data (or NULL if no sense to be collected).
* must be SCSI_SENSE_BUFFERSIZE big.
*
* Returns zero if unsuccessful, or the header offset (either 4
@ -3169,19 +3116,6 @@ retry:
return result;
}
/**
**********************************************************************
* \globalfn scsi_is_target_device -- Check if this is target type device
*
* \param device struct associated with this target
* \return 0 if not a valid device
* \par Include:
* scsi/scsi_device.h
* \par ESX Deviation Notes:
* None
* \sa None.
**********************************************************************
*/
/**
* scsi_is_target_device - Check if this is target type device
* @dev: device struct associated with this target
@ -3597,17 +3531,14 @@ scsi_rescan_device(struct device *dev)
EXPORT_SYMBOL(scsi_rescan_device);
/**
**************************************************************************
* \globalfn scsi_device_set_state - Take the given device through the device
* scsi_device_set_state - Take the given device through the device
* state model.
* \param sdev scsi device to change the state of.
* \param state state to change to.
* \return zero if unsuccessful or an error if the requested transition
* @sdev: scsi device to change the state of.
* @state: state to change to.
*
* RETURN VALUE:
* return zero if unsuccessful or an error if the requested transition
* is illegal.
* \par ESX Deviation Notes:
* None
* \sa None
**************************************************************************
**/
/**
* scsi_device_set_state - Set scsi state to the given scsi device
@ -3633,14 +3564,11 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
EXPORT_SYMBOL(scsi_device_set_state);
/**
**************************************************************************
* \globalfn vmklnx_get_vmhba_name - Provide the vmhba name
* \param shost - Scsi_Host for the adapter
* \return vmhba Name
* \par ESX Deviation Notes:
* None
* \sa None
**************************************************************************
* vmklnx_get_vmhba_name - Provide the vmhba name
* @sh: Scsi_Host for the adapter
*
* RETURN VALUE:
* vmhba Name
**/
char *
vmklnx_get_vmhba_name(struct Scsi_Host *sh)
@ -3662,8 +3590,6 @@ vmklnx_get_vmhba_name(struct Scsi_Host *sh)
EXPORT_SYMBOL(vmklnx_get_vmhba_name);
/*
*----------------------------------------------------------------------
*
* vmklnx_scsi_free_host_resources --
*
* Frees the common host resources
@ -3673,8 +3599,6 @@ EXPORT_SYMBOL(vmklnx_get_vmhba_name);
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
static void
vmklnx_scsi_free_host_resources(struct Scsi_Host *sh)
@ -3697,8 +3621,6 @@ vmklnx_scsi_free_host_resources(struct Scsi_Host *sh)
/*
*----------------------------------------------------------------------
*
* scsi_host_dev_release --
*
* This function is called when the ref count on the adapter goes to zero
@ -3710,8 +3632,6 @@ vmklnx_scsi_free_host_resources(struct Scsi_Host *sh)
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
static void scsi_host_dev_release(struct device *dev)
{
@ -3780,8 +3700,6 @@ vmklnx_destroy_adapter_tls(struct vmklnx_ScsiAdapter *vmklnx26ScsiAdapter)
}
/*
*----------------------------------------------------------------------
*
* vmklnx_scsi_unregister_host --
*
* This function is called from a WQ. This fn unregisters ourselves
@ -3792,8 +3710,6 @@ vmklnx_destroy_adapter_tls(struct vmklnx_ScsiAdapter *vmklnx26ScsiAdapter)
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
static void
vmklnx_scsi_unregister_host(struct work_struct *work)
@ -3853,8 +3769,6 @@ vmklnx_scsi_unregister_host(struct work_struct *work)
/*
*----------------------------------------------------------------------
*
* scsi_target_dev_release --
*
* This function is called when the ref count on the target goes to zero
@ -3865,8 +3779,6 @@ vmklnx_scsi_unregister_host(struct work_struct *work)
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
static void scsi_target_dev_release(struct device *dev)
{
@ -3896,8 +3808,6 @@ static void scsi_target_dev_release(struct device *dev)
}
/*
*----------------------------------------------------------------------
*
* scsi_device_dev_release --
*
* This function is called when the ref count on the device goes to zero
@ -3909,8 +3819,6 @@ static void scsi_target_dev_release(struct device *dev)
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
static void scsi_device_dev_release(struct device *dev)
{
@ -3990,7 +3898,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
/**
* scsi_req_abort_cmd -- Request command recovery for the specified command
* cmd: pointer to the SCSI command of interest
* @cmd: pointer to the SCSI command of interest
*
* This function requests that SCSI Core start recovery for the
* command by deleting the timer and adding the command to the eh
@ -3998,6 +3906,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
* implement their own error recovery MAY ignore the timeout event if
* they generated scsi_req_abort_cmd.
**/
/* _VMKLNX_CODECHECK_: scsi_req_abort_cmd*/
void scsi_req_abort_cmd(struct scsi_cmnd *cmd)
{
VMK_ASSERT(vmk_PreemptionIsEnabled() == VMK_FALSE);
@ -4023,6 +3932,7 @@ void __scsi_done(struct scsi_cmnd *cmd)
* Returns zero if successful or an error if the requested
* transition is illegal.
**/
/* _VMKLNX_CODECHECK_: csi_host_set_state*/
int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
{
VMK_ASSERT(vmk_PreemptionIsEnabled() == VMK_FALSE);
@ -4078,17 +3988,12 @@ vmklnx_scsi_target_offline(struct device *dev)
EXPORT_SYMBOL(vmklnx_scsi_target_offline);
EXPORT_SYMBOL_ALIASED(vmklnx_scsi_target_offline, scsi_target_offline);
/**
**********************************************************************
* \globalfn scsi_offline_device -- Mark the device offline
/*
* scsi_offline_device -- Mark the device offline
* @sdev: scsi device
*
* \param sh
* \return None
* \par Include:
* \par ESX Deviation Notes:
* RETURN VALUE:
* None
* \sa None
**********************************************************************
*/
static void
scsi_offline_device(struct scsi_device *sdev)
@ -4146,19 +4051,18 @@ scsi_offline_device(struct scsi_device *sdev)
}
/**
**********************************************************************
* \globalfn vmklnx_scsi_get_num_ioqueue -- get num of queues to create
* get num of queues to create
* @maxQueue: Maximum queues adapter can create
*
* \param Maximum queues adapter can create
* \return Number of queues to be created, returns 0 for no additional
* RETURN VALUE:
* return Number of queues to be created, returns 0 for no additional
* queues in adapter
* \par Include:
* \par ESX Deviation Notes:
*
* ESX Deviation Notes:
* ESX specific API to query VMKernel for the number of queues to
* be created
* \sa None
**********************************************************************
*/
/* _VMKLNX_CODECHECK_: vmklnx_scsi_get_num_ioqueue*/
int
vmklnx_scsi_get_num_ioqueue(unsigned int maxQueue)
{
@ -4171,19 +4075,19 @@ vmklnx_scsi_get_num_ioqueue(unsigned int maxQueue)
EXPORT_SYMBOL(vmklnx_scsi_get_num_ioqueue);
/**
**********************************************************************
* \globalfn vmklnx_scsi_get_cmd_ioqueue_handle -- returns queue handle
* returns queue handle
* @cmd: scsi command
* @sh: scsi host
*
* \param scsi_cmd, sh
* \return ioqueue handle
* \par Include:
* \par ESX Deviation Notes:
* RETURN VALUE:
* ioqueue handle
*
* Deviation Notes:
* ESX specific API to query VMKernel for the ioqueues to be used
* to issue the given scsi command
* None
* \sa None
**********************************************************************
*/
/* _VMKLNX_CODECHECK_: vmklnx_scsi_get_cmd_ioqueue_handle*/
void *
vmklnx_scsi_get_cmd_ioqueue_handle(struct scsi_cmnd *cmd,
struct Scsi_Host *sh)
@ -4204,21 +4108,20 @@ vmklnx_scsi_get_cmd_ioqueue_handle(struct scsi_cmnd *cmd,
EXPORT_SYMBOL(vmklnx_scsi_get_cmd_ioqueue_handle);
/**
**********************************************************************
* \globalfn vmklnx_scsi_register_ioqueue-- pass queue info to vmkernel
*
* \param sh, Number of I/O queues, scsi_ioqueue_info for each queue
* \return zero if successful, error code otherwise
* \par Include:
* \par ESX Deviation Notes:
* vmklnx_scsi_register_ioqueue-- pass queue info to vmkernel.
* ESX specific API to register all the ioqueues in the adapter
* with VMKernel. For each ioqueue the driver should provide the
* handle and interrupt vector. The handle will be returned by
* vmkernel when vmklnx_scsi_get_cmd_ioqueue_handle() is invoked
* to select queue for a scsi_cmd
* \sa None
**********************************************************************
* to select queue for a scsi_cmd.
* @sh: scsi host
* @numIoQueue: Number of I/O queues
* @q_info: scsi_ioqueue_info for each queue
*
* RETURN VALUE:
* return zero if successful, error code otherwise
*/
/* _VMKLNX_CODECHECK_: vmklnx_scsi_register_ioqueue*/
int
vmklnx_scsi_register_ioqueue(struct Scsi_Host *sh, unsigned int numIoQueue,
struct vmklnx_scsi_ioqueue_info q_info[])
@ -4361,8 +4264,6 @@ SCSILinux_InitLLD(void)
}
/*
*----------------------------------------------------------------------
*
* SCSILinux_CleanupLLD
*
* Entry point for SCSI LLD-specific teardown.
@ -4373,8 +4274,6 @@ SCSILinux_InitLLD(void)
*
* Side effects:
* Cleans up SCSI LLD log.
*
*----------------------------------------------------------------------
*/
void
SCSILinux_CleanupLLD(void)
@ -4384,7 +4283,7 @@ SCSILinux_CleanupLLD(void)
/**
* scsi_device_reprobe - Rediscover device status by reprobing if needed
* sdev: Pointer to scsi_device which needs status update
* @sdev: Pointer to scsi_device which needs status update
*
* This function will either hide a device which doesn't need exposure to upper
* layers anymore or will initiate a scan to rediscover new devices on the
@ -4418,16 +4317,14 @@ EXPORT_SYMBOL(scsi_device_reprobe);
/**
***********************************************************************
* vmklnx_scsi_cmd_get_sensedata - Get sense data length from SCSI cmd
* scmd: SCSI command
* buf: Buffer that will contain sense data
* bufLen: Length of the sense buffer
* @scmd: SCSI command
* @buf: Buffer that will contain sense data
* @bufLen: Length of the sense buffer
*
* Command is identified by scmd. The buffer buf is filled with sense data.
* The length of the input buffer is passed through bufLen.
*
**********************************************************************
*/
/* _VMKLNX_CODECHECK_: vmklnx_scsi_cmd_get_sensedata */
int
@ -4441,19 +4338,16 @@ vmklnx_scsi_cmd_get_sensedata(struct scsi_cmnd *scmd,
EXPORT_SYMBOL(vmklnx_scsi_cmd_get_sensedata);
/**
***********************************************************************
* vmklnx_scsi_cmd_set_sensedata - Set sense data of SCSI cmd
* buf: Buffer that contains sense data to set
* scmd: SCSI command
* bufLen: Number of bytes to copy
* @buf: Buffer that contains sense data to set
* @scmd: SCSI command
* @bufLen: Number of bytes to copy
*
* Command is identified by scmd. The number of bytes to copy from buf
* is passed as bufLen. If the number of bytes to copy is less than the
* sense buffer size of SCSI cmd(obtained by calling
* vmklnx_scsi_cmd_get_supportedsensedata_size), the remaining bytes in
* SCSI cmd's sense buffer are set to 0.
*
**********************************************************************
*/
/* _VMKLNX_CODECHECK_: vmklnx_scsi_cmd_set_sensedata */
int
@ -4467,13 +4361,11 @@ vmklnx_scsi_cmd_set_sensedata(uint8_t *buf,
EXPORT_SYMBOL(vmklnx_scsi_cmd_set_sensedata);
/**
***********************************************************************
* vmklnx_scsi_cmd_clear_sensedata - Clear sense data of SCSI cmd
* scmd: SCSI command
* @scmd: SCSI command
*
* Command is identified by scmd.
*
**********************************************************************
*/
/* _VMKLNX_CODECHECK_: vmklnx_scsi_cmd_clear_sensedata */
int
@ -4484,10 +4376,8 @@ vmklnx_scsi_cmd_clear_sensedata(struct scsi_cmnd *scmd)
EXPORT_SYMBOL(vmklnx_scsi_cmd_clear_sensedata);
/**
***********************************************************************
* vmklnx_scsi_cmd_get_supportedsensedata_size - Get scmd's sense buffer size
*
**********************************************************************
*/
/* _VMKLNX_CODECHECK_: vmklnx_scsi_cmd_get_supportedsensedata_size */
int

File diff suppressed because it is too large Load diff

View file

@ -1617,6 +1617,14 @@ FcLinuxPortAttributes(void *clientData, vmk_uint32 portId, vmk_FcPortAttributes
return VMK_NOT_FOUND;
}
if (ft->get_host_port_id) {
VMKAPI_MODULE_CALL_VOID(SCSI_GET_MODULE_ID(shost), ft->get_host_port_id, shost);
}
if (ft->get_host_speed) {
VMKAPI_MODULE_CALL_VOID(SCSI_GET_MODULE_ID(shost), ft->get_host_speed, shost);
}
lport = shost_priv(shost);
memset(portAttrib, 0, sizeof(vmk_FcPortAttributes));