ESXi-5.5-U1
This commit is contained in:
parent
91e0d39c98
commit
89a4bb14d0
79 changed files with 21997 additions and 8736 deletions
|
@ -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. */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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"
|
||||
|
|
13
BUILD.txt
13
BUILD.txt
|
@ -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
26
machines.cfgx
Normal 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
26
vmkdrivers-gpl.odpx
Normal 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>
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
@ -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,10 +45,10 @@
|
|||
#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 */
|
||||
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
@ -675,11 +691,7 @@ bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
|
|||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -710,25 +719,7 @@ s32 e1000_mng_write_cmd_header(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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"
|
||||
|
||||
struct e1000_mac_operations {
|
||||
/* Function pointers for the MAC. */
|
||||
struct e1000_mac_operations {
|
||||
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);
|
||||
|
|
909
vmkdrivers/src_9/drivers/net/igb/e1000_i210.c
Executable file
909
vmkdrivers/src_9/drivers/net/igb/e1000_i210.c
Executable 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);
|
||||
}
|
91
vmkdrivers/src_9/drivers/net/igb/e1000_i210.h
Executable file
91
vmkdrivers/src_9/drivers/net/igb/e1000_i210.h
Executable 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
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
*pba_num = (u32)(nvm_data << 16);
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
}
|
||||
*pba_num |= nvm_data;
|
||||
|
||||
out:
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_lro_stats {
|
||||
u32 flushed;
|
||||
u32 coal;
|
||||
u32 recycled;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct igb_lro_list {
|
||||
struct hlist_head active;
|
||||
struct hlist_head free;
|
||||
int active_cnt;
|
||||
struct igb_lro_stats stats;
|
||||
};
|
||||
|
||||
#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 {
|
||||
unsigned long time_stamp;
|
||||
u16 length;
|
||||
u16 next_to_watch;
|
||||
u16 mapped_as_page;
|
||||
u16 gso_segs;
|
||||
};
|
||||
|
||||
#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT
|
||||
/* RX */
|
||||
struct {
|
||||
unsigned long page_offset;
|
||||
struct page *page;
|
||||
dma_addr_t page_dma;
|
||||
};
|
||||
struct igb_cb {
|
||||
#ifdef HAVE_VLAN_RX_REGISTER
|
||||
u16 vid; /* VLAN tag */
|
||||
#endif
|
||||
};
|
||||
#define IGB_CB(skb) ((struct igb_cb *)(skb)->cb)
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
/* VLAN info */
|
||||
#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
|
||||
#define IGB_TX_FLAGS_VLAN_SHIFT 16
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/* wrapper around a pointer to a socket buffer,
|
||||
* so a DMA handle can be stored along with the buffer */
|
||||
struct igb_tx_buffer {
|
||||
union e1000_adv_tx_desc *next_to_watch;
|
||||
unsigned long time_stamp;
|
||||
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;
|
||||
};
|
||||
|
||||
struct igb_rx_buffer {
|
||||
dma_addr_t dma;
|
||||
#ifdef CONFIG_IGB_DISABLE_PACKET_SPLIT
|
||||
struct sk_buff *skb;
|
||||
#else
|
||||
struct page *page;
|
||||
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_ */
|
||||
|
|
29
vmkdrivers/src_9/drivers/net/igb/igb_debugfs.c
Executable file
29
vmkdrivers/src_9/drivers/net/igb/igb_debugfs.c
Executable 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
242
vmkdrivers/src_9/drivers/net/igb/igb_hwmon.c
Executable file
242
vmkdrivers/src_9/drivers/net/igb/igb_hwmon.c
Executable 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
|
@ -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__ */
|
||||
}
|
||||
|
||||
|
|
962
vmkdrivers/src_9/drivers/net/igb/igb_procfs.c
Executable file
962
vmkdrivers/src_9/drivers/net/igb/igb_procfs.c
Executable 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 */
|
944
vmkdrivers/src_9/drivers/net/igb/igb_ptp.c
Executable file
944
vmkdrivers/src_9/drivers/net/igb/igb_ptp.c
Executable 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()));
|
||||
}
|
||||
}
|
|
@ -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 },
|
||||
|
|
815
vmkdrivers/src_9/drivers/net/igb/igb_vmdq.c
Executable file
815
vmkdrivers/src_9/drivers/net/igb/igb_vmdq.c
Executable 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__ */
|
51
vmkdrivers/src_9/drivers/net/igb/igb_vmdq.h
Executable file
51
vmkdrivers/src_9/drivers/net/igb/igb_vmdq.h
Executable 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
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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__)
|
||||
/*
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1110,7 +1110,7 @@ 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
|
||||
* @dev: target ATA dev for per-dev action (can be NULL)
|
||||
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -108,15 +108,14 @@ 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*/
|
||||
static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in a new issue