mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Update the ixgbe driver to 1.7.4, this includes support
for the new 82599 adapter family, adds header split, and many small fixes. The driver should now be added to the GENERIC kernel. MFC after: 2 weeks
This commit is contained in:
parent
d035aa2db2
commit
0ac6dfec68
13 changed files with 3211 additions and 813 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
FreeBSD Driver for 10 Gigabit PCI Express Server Adapters
|
||||
=============================================
|
||||
$FreeBSD$
|
||||
/*$FreeBSD$*/
|
||||
|
||||
May 14, 2008
|
||||
|
||||
|
||||
Contents
|
||||
|
|
@ -258,7 +260,7 @@ For general information and support, go to the Intel support website at:
|
|||
|
||||
If an issue is identified with the released source code on the supported
|
||||
kernel with a supported adapter, email the specific information related to
|
||||
the issue to freebsdnic@mailbox.intel.com.
|
||||
the issue to freebsd@intel.com.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -64,6 +64,7 @@
|
|||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_lro.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include <machine/in_cksum.h>
|
||||
|
|
@ -83,8 +84,12 @@
|
|||
#include <sys/taskqueue.h>
|
||||
#include <sys/pcpu.h>
|
||||
|
||||
#ifdef IXGBE_TIMESYNC
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "ixgbe_api.h"
|
||||
#include "tcp_lro.h"
|
||||
|
||||
/* Tunables */
|
||||
|
||||
|
|
@ -95,7 +100,7 @@
|
|||
* bytes. Performance tests have show the 2K value to be optimal for top
|
||||
* performance.
|
||||
*/
|
||||
#define DEFAULT_TXD 256
|
||||
#define DEFAULT_TXD 1024
|
||||
#define PERFORM_TXD 2048
|
||||
#define MAX_TXD 4096
|
||||
#define MIN_TXD 64
|
||||
|
|
@ -110,7 +115,7 @@
|
|||
* against the system mbuf pool limit, you can tune nmbclusters
|
||||
* to adjust for this.
|
||||
*/
|
||||
#define DEFAULT_RXD 256
|
||||
#define DEFAULT_RXD 1024
|
||||
#define PERFORM_RXD 2048
|
||||
#define MAX_RXD 4096
|
||||
#define MIN_RXD 64
|
||||
|
|
@ -159,7 +164,8 @@
|
|||
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
|
||||
|
||||
#define MAX_NUM_MULTICAST_ADDRESSES 128
|
||||
#define IXGBE_MAX_SCATTER 100
|
||||
#define IXGBE_82598_SCATTER 100
|
||||
#define IXGBE_82599_SCATTER 32
|
||||
#define MSIX_82598_BAR 3
|
||||
#define MSIX_82599_BAR 4
|
||||
#define IXGBE_TSO_SIZE 65535
|
||||
|
|
@ -171,12 +177,13 @@
|
|||
#define IXGBE_MSGS 18
|
||||
|
||||
/* For 6.X code compatibility */
|
||||
#if __FreeBSD_version < 700000
|
||||
#if !defined(ETHER_BPF_MTAP)
|
||||
#define ETHER_BPF_MTAP BPF_MTAP
|
||||
#endif
|
||||
|
||||
#if __FreeBSD_version < 700000
|
||||
#define CSUM_TSO 0
|
||||
#define IFCAP_TSO4 0
|
||||
#define FILTER_STRAY
|
||||
#define FILTER_HANDLED
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -214,6 +221,7 @@ typedef struct _ixgbe_vendor_info_t {
|
|||
|
||||
|
||||
struct ixgbe_tx_buf {
|
||||
u32 eop_index;
|
||||
struct mbuf *m_head;
|
||||
bus_dmamap_t map;
|
||||
};
|
||||
|
|
@ -314,8 +322,6 @@ struct adapter {
|
|||
|
||||
/*
|
||||
* Interrupt resources:
|
||||
* Oplin has 20 MSIX messages
|
||||
* so allocate that for now.
|
||||
*/
|
||||
void *tag[IXGBE_MSGS];
|
||||
struct resource *res[IXGBE_MSGS];
|
||||
|
|
@ -334,6 +340,7 @@ struct adapter {
|
|||
bool link_active;
|
||||
u16 max_frame_size;
|
||||
u32 link_speed;
|
||||
bool link_up;
|
||||
u32 linkvec;
|
||||
u32 tx_int_delay;
|
||||
u32 tx_abs_int_delay;
|
||||
|
|
@ -343,8 +350,12 @@ struct adapter {
|
|||
/* Mbuf cluster size */
|
||||
u32 rx_mbuf_sz;
|
||||
|
||||
/* Check for missing optics */
|
||||
/* Support for pluggable optics */
|
||||
bool sfp_probe;
|
||||
struct task link_task; /* Link tasklet */
|
||||
struct task mod_task; /* SFP tasklet */
|
||||
struct task msf_task; /* Multispeed Fiber tasklet */
|
||||
struct taskqueue *tq;
|
||||
|
||||
/*
|
||||
* Transmit rings:
|
||||
|
|
@ -364,6 +375,12 @@ struct adapter {
|
|||
u32 rx_mask;
|
||||
u32 rx_process_limit;
|
||||
|
||||
#ifdef IXGBE_TIMESYNC
|
||||
u64 last_stamp;
|
||||
u64 last_sec;
|
||||
u32 last_ns;
|
||||
#endif
|
||||
|
||||
/* Misc stats maintained by the driver */
|
||||
unsigned long dropped_pkts;
|
||||
unsigned long mbuf_defrag_failed;
|
||||
|
|
@ -378,6 +395,32 @@ struct adapter {
|
|||
struct ixgbe_hw_stats stats;
|
||||
};
|
||||
|
||||
#ifdef IXGBE_TIMESYNC
|
||||
/* Precision Time Sync (IEEE 1588) defines */
|
||||
#define ETHERTYPE_IEEE1588 0x88F7
|
||||
#define PICOSECS_PER_TICK 20833
|
||||
#define TSYNC_UDP_PORT 319 /* UDP port for the protocol */
|
||||
#define IXGBE_ADVTXD_TSTAMP 0x00080000
|
||||
|
||||
/* TIMESYNC IOCTL defines */
|
||||
#define IXGBE_TIMESYNC_READTS _IOWR('i', 127, struct ixgbe_tsync_read)
|
||||
#define IXGBE_TIMESTAMP 5 /* A unique return value */
|
||||
|
||||
/* Used in the READTS IOCTL */
|
||||
struct ixgbe_tsync_read {
|
||||
int read_current_time;
|
||||
struct timespec system_time;
|
||||
u64 network_time;
|
||||
u64 rx_stamp;
|
||||
u64 tx_stamp;
|
||||
u16 seqid;
|
||||
unsigned char srcid[6];
|
||||
int rx_valid;
|
||||
int tx_valid;
|
||||
};
|
||||
|
||||
#endif /* IXGBE_TIMESYNC */
|
||||
|
||||
#define IXGBE_CORE_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->core_mtx, _name, "IXGBE Core Lock", MTX_DEF)
|
||||
#define IXGBE_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx)
|
||||
|
|
@ -385,6 +428,7 @@ struct adapter {
|
|||
#define IXGBE_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
|
||||
#define IXGBE_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
|
||||
#define IXGBE_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
|
||||
#define IXGBE_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx)
|
||||
#define IXGBE_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
|
||||
#define IXGBE_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
|
||||
#define IXGBE_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
|
||||
|
|
@ -393,4 +437,20 @@ struct adapter {
|
|||
#define IXGBE_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
|
||||
|
||||
|
||||
static inline bool
|
||||
ixgbe_is_sfp(struct ixgbe_hw *hw)
|
||||
{
|
||||
switch (hw->phy.type) {
|
||||
case ixgbe_phy_sfp_avago:
|
||||
case ixgbe_phy_sfp_ftl:
|
||||
case ixgbe_phy_sfp_intel:
|
||||
case ixgbe_phy_sfp_unknown:
|
||||
case ixgbe_phy_tw_tyco:
|
||||
case ixgbe_phy_tw_unknown:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _IXGBE_H_ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -37,15 +37,12 @@
|
|||
#include "ixgbe_common.h"
|
||||
#include "ixgbe_phy.h"
|
||||
|
||||
u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw);
|
||||
static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
|
||||
ixgbe_link_speed *speed,
|
||||
bool *autoneg);
|
||||
s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
|
||||
ixgbe_link_speed *speed,
|
||||
bool *autoneg);
|
||||
static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||
s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||
static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw);
|
||||
static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
|
||||
|
|
@ -60,22 +57,41 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
|
|||
ixgbe_link_speed speed,
|
||||
bool autoneg,
|
||||
bool autoneg_wait_to_complete);
|
||||
#ifndef NO_82598_A0_SUPPORT
|
||||
s32 ixgbe_reset_hw_rev_0_82598(struct ixgbe_hw *hw);
|
||||
#endif
|
||||
static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
|
||||
static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
|
||||
s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan,
|
||||
u32 vind, bool vlan_on);
|
||||
static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
|
||||
static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index);
|
||||
static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index);
|
||||
s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val);
|
||||
s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val);
|
||||
s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 *eeprom_data);
|
||||
u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw);
|
||||
|
||||
/**
|
||||
* ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Read PCIe configuration space, and get the MSI-X vector count from
|
||||
* the capabilities table.
|
||||
**/
|
||||
u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 msix_count = 18;
|
||||
|
||||
if (hw->mac.msix_vectors_from_pcie) {
|
||||
msix_count = IXGBE_READ_PCIE_WORD(hw,
|
||||
IXGBE_PCIE_MSIX_82598_CAPS);
|
||||
msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
|
||||
|
||||
/* MSI-X count is zero-based in HW, so increment to give
|
||||
* proper value */
|
||||
msix_count++;
|
||||
}
|
||||
return msix_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_init_ops_82598 - Inits func ptrs and MAC type
|
||||
|
|
@ -89,30 +105,21 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
|
|||
struct ixgbe_mac_info *mac = &hw->mac;
|
||||
struct ixgbe_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 list_offset, data_offset;
|
||||
|
||||
ret_val = ixgbe_init_phy_ops_generic(hw);
|
||||
ret_val = ixgbe_init_ops_generic(hw);
|
||||
|
||||
/* PHY */
|
||||
phy->ops.init = &ixgbe_init_phy_ops_82598;
|
||||
|
||||
/* MAC */
|
||||
#ifndef NO_82598_A0_SUPPORT
|
||||
if (hw->revision_id == 0)
|
||||
mac->ops.reset_hw = &ixgbe_reset_hw_rev_0_82598;
|
||||
else
|
||||
mac->ops.reset_hw = &ixgbe_reset_hw_82598;
|
||||
#else
|
||||
mac->ops.reset_hw = &ixgbe_reset_hw_82598;
|
||||
#endif
|
||||
mac->ops.get_media_type = &ixgbe_get_media_type_82598;
|
||||
mac->ops.get_supported_physical_layer =
|
||||
&ixgbe_get_supported_physical_layer_82598;
|
||||
mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82598;
|
||||
mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82598;
|
||||
|
||||
/* LEDs */
|
||||
mac->ops.blink_led_start = &ixgbe_blink_led_start_82598;
|
||||
mac->ops.blink_led_stop = &ixgbe_blink_led_stop_82598;
|
||||
|
||||
/* RAR, Multicast, VLAN */
|
||||
mac->ops.set_vmdq = &ixgbe_set_vmdq_82598;
|
||||
mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82598;
|
||||
|
|
@ -120,42 +127,67 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
|
|||
mac->ops.clear_vfta = &ixgbe_clear_vfta_82598;
|
||||
|
||||
/* Flow Control */
|
||||
mac->ops.setup_fc = &ixgbe_setup_fc_82598;
|
||||
|
||||
/* Link */
|
||||
mac->ops.check_link = &ixgbe_check_mac_link_82598;
|
||||
if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
|
||||
mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
|
||||
mac->ops.setup_link_speed =
|
||||
&ixgbe_setup_copper_link_speed_82598;
|
||||
mac->ops.get_link_capabilities =
|
||||
&ixgbe_get_copper_link_capabilities_82598;
|
||||
} else {
|
||||
mac->ops.setup_link = &ixgbe_setup_mac_link_82598;
|
||||
mac->ops.setup_link_speed = &ixgbe_setup_mac_link_speed_82598;
|
||||
mac->ops.get_link_capabilities =
|
||||
&ixgbe_get_link_capabilities_82598;
|
||||
}
|
||||
mac->ops.fc_enable = &ixgbe_fc_enable_82598;
|
||||
|
||||
mac->mcft_size = 128;
|
||||
mac->vft_size = 128;
|
||||
mac->num_rar_entries = 16;
|
||||
mac->max_tx_queues = 32;
|
||||
mac->max_rx_queues = 64;
|
||||
mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
|
||||
|
||||
/* SFP+ Module */
|
||||
phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598;
|
||||
|
||||
/* Call PHY identify routine to get the phy type */
|
||||
/* Link */
|
||||
mac->ops.check_link = &ixgbe_check_mac_link_82598;
|
||||
mac->ops.setup_link = &ixgbe_setup_mac_link_82598;
|
||||
mac->ops.setup_link_speed = &ixgbe_setup_mac_link_speed_82598;
|
||||
mac->ops.get_link_capabilities =
|
||||
&ixgbe_get_link_capabilities_82598;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_init_phy_ops_82598 - PHY/SFP specific init
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Initialize any function pointers that were not able to be
|
||||
* set during init_shared_code because the PHY/SFP type was
|
||||
* not known. Perform the SFP init if necessary.
|
||||
*
|
||||
**/
|
||||
s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
|
||||
{
|
||||
struct ixgbe_mac_info *mac = &hw->mac;
|
||||
struct ixgbe_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = IXGBE_SUCCESS;
|
||||
u16 list_offset, data_offset;
|
||||
|
||||
|
||||
/* Identify the PHY */
|
||||
phy->ops.identify(hw);
|
||||
|
||||
/* PHY Init */
|
||||
/* Overwrite the link function pointers if copper PHY */
|
||||
if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
|
||||
mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
|
||||
mac->ops.setup_link_speed =
|
||||
&ixgbe_setup_copper_link_speed_82598;
|
||||
mac->ops.get_link_capabilities =
|
||||
&ixgbe_get_copper_link_capabilities_generic;
|
||||
}
|
||||
|
||||
switch (hw->phy.type) {
|
||||
case ixgbe_phy_tn:
|
||||
phy->ops.check_link = &ixgbe_check_phy_link_tnx;
|
||||
phy->ops.get_firmware_version =
|
||||
&ixgbe_get_phy_firmware_version_tnx;
|
||||
break;
|
||||
case ixgbe_phy_aq:
|
||||
phy->ops.get_firmware_version =
|
||||
&ixgbe_get_phy_firmware_version_aq;
|
||||
break;
|
||||
case ixgbe_phy_nl:
|
||||
phy->ops.reset = &ixgbe_reset_phy_nl;
|
||||
|
||||
|
|
@ -198,18 +230,19 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
|
|||
bool *autoneg)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
s32 autoc_reg;
|
||||
u32 autoc = 0;
|
||||
|
||||
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
/*
|
||||
* Determine link capabilities based on the stored value of AUTOC,
|
||||
* which represents EEPROM defaults. If AUTOC value has not been
|
||||
* stored, use the current register value.
|
||||
*/
|
||||
if (hw->mac.orig_link_settings_stored)
|
||||
autoc = hw->mac.orig_autoc;
|
||||
else
|
||||
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
|
||||
if (hw->mac.link_settings_loaded) {
|
||||
autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
|
||||
autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
|
||||
autoc_reg |= hw->mac.link_attach_type;
|
||||
autoc_reg |= hw->mac.link_mode_select;
|
||||
}
|
||||
|
||||
switch (autoc_reg & IXGBE_AUTOC_LMS_MASK) {
|
||||
switch (autoc & IXGBE_AUTOC_LMS_MASK) {
|
||||
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
|
||||
*speed = IXGBE_LINK_SPEED_1GB_FULL;
|
||||
*autoneg = FALSE;
|
||||
|
|
@ -228,9 +261,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
|
|||
case IXGBE_AUTOC_LMS_KX4_AN:
|
||||
case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
|
||||
*speed = IXGBE_LINK_SPEED_UNKNOWN;
|
||||
if (autoc_reg & IXGBE_AUTOC_KX4_SUPP)
|
||||
if (autoc & IXGBE_AUTOC_KX4_SUPP)
|
||||
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
|
||||
if (autoc_reg & IXGBE_AUTOC_KX_SUPP)
|
||||
if (autoc & IXGBE_AUTOC_KX_SUPP)
|
||||
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
|
||||
*autoneg = TRUE;
|
||||
break;
|
||||
|
|
@ -243,38 +276,6 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities
|
||||
* @hw: pointer to hardware structure
|
||||
* @speed: pointer to link speed
|
||||
* @autoneg: boolean auto-negotiation value
|
||||
*
|
||||
* Determines the link capabilities by reading the AUTOC register.
|
||||
**/
|
||||
s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
|
||||
ixgbe_link_speed *speed,
|
||||
bool *autoneg)
|
||||
{
|
||||
s32 status = IXGBE_ERR_LINK_SETUP;
|
||||
u16 speed_ability;
|
||||
|
||||
*speed = 0;
|
||||
*autoneg = TRUE;
|
||||
|
||||
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
|
||||
IXGBE_MDIO_PMA_PMD_DEV_TYPE,
|
||||
&speed_ability);
|
||||
|
||||
if (status == IXGBE_SUCCESS) {
|
||||
if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
|
||||
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
|
||||
if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
|
||||
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_media_type_82598 - Determines media type
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -285,9 +286,18 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
|
|||
{
|
||||
enum ixgbe_media_type media_type;
|
||||
|
||||
/* Detect if there is a copper PHY attached. */
|
||||
if (hw->phy.type == ixgbe_phy_cu_unknown ||
|
||||
hw->phy.type == ixgbe_phy_tn ||
|
||||
hw->phy.type == ixgbe_phy_aq) {
|
||||
media_type = ixgbe_media_type_copper;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Media type for I82598 is based on device ID */
|
||||
switch (hw->device_id) {
|
||||
case IXGBE_DEV_ID_82598:
|
||||
case IXGBE_DEV_ID_82598_BX:
|
||||
/* Default device ID is mezzanine card KX/KX4 */
|
||||
media_type = ixgbe_media_type_backplane;
|
||||
break;
|
||||
|
|
@ -308,7 +318,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
|
|||
media_type = ixgbe_media_type_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return media_type;
|
||||
}
|
||||
|
||||
|
|
@ -328,6 +338,12 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
|
|||
|
||||
DEBUGFUNC("ixgbe_fc_enable_82598");
|
||||
|
||||
/* Negotiate the fc mode to use */
|
||||
ret_val = ixgbe_fc_autoneg(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Disable any previous flow control settings */
|
||||
fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
|
||||
fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
|
||||
|
||||
|
|
@ -339,14 +355,16 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
|
|||
* 0: Flow control is completely disabled
|
||||
* 1: Rx flow control is enabled (we can receive pause frames,
|
||||
* but not send pause frames).
|
||||
* 2: Tx flow control is enabled (we can send pause frames but
|
||||
* 2: Tx flow control is enabled (we can send pause frames but
|
||||
* we do not support receiving pause frames).
|
||||
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
||||
* other: Invalid.
|
||||
*/
|
||||
switch (hw->fc.current_mode) {
|
||||
case ixgbe_fc_none:
|
||||
/* Flow control completely disabled by software override. */
|
||||
/* Flow control is disabled by software override or autoneg.
|
||||
* The code below will actually disable it in the HW.
|
||||
*/
|
||||
break;
|
||||
case ixgbe_fc_rx_pause:
|
||||
/*
|
||||
|
|
@ -378,7 +396,8 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Enable 802.3x based flow control settings. */
|
||||
/* Set 802.3x based flow control settings. */
|
||||
fctrl_reg |= IXGBE_FCTRL_DPF;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
|
||||
|
||||
|
|
@ -410,73 +429,6 @@ out:
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_setup_fc_82598 - Set up flow control
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Sets up flow control.
|
||||
**/
|
||||
s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||
{
|
||||
s32 ret_val = IXGBE_SUCCESS;
|
||||
ixgbe_link_speed speed;
|
||||
bool link_up;
|
||||
|
||||
/* Validate the packetbuf configuration */
|
||||
if (packetbuf_num < 0 || packetbuf_num > 7) {
|
||||
DEBUGOUT1("Invalid packet buffer number [%d], expected range is"
|
||||
" 0-7\n", packetbuf_num);
|
||||
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the water mark configuration. Zero water marks are invalid
|
||||
* because it causes the controller to just blast out fc packets.
|
||||
*/
|
||||
if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
|
||||
DEBUGOUT("Invalid water mark configuration\n");
|
||||
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the requested mode. Strict IEEE mode does not allow
|
||||
* ixgbe_fc_rx_pause because it will cause testing anomalies.
|
||||
*/
|
||||
if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
|
||||
DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
|
||||
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* 10gig parts do not have a word in the EEPROM to determine the
|
||||
* default flow control setting, so we explicitly set it to full.
|
||||
*/
|
||||
if (hw->fc.requested_mode == ixgbe_fc_default)
|
||||
hw->fc.requested_mode = ixgbe_fc_full;
|
||||
|
||||
/*
|
||||
* Save off the requested flow control mode for use later. Depending
|
||||
* on the link partner's capabilities, we may or may not use this mode.
|
||||
*/
|
||||
hw->fc.current_mode = hw->fc.requested_mode;
|
||||
|
||||
/* Decide whether to use autoneg or not. */
|
||||
hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
|
||||
if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL))
|
||||
ret_val = ixgbe_fc_autoneg(hw);
|
||||
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_setup_mac_link_82598 - Configures MAC link settings
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -491,27 +443,17 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
|
|||
u32 i;
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
|
||||
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
|
||||
if (hw->mac.link_settings_loaded) {
|
||||
autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
|
||||
autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
|
||||
autoc_reg |= hw->mac.link_attach_type;
|
||||
autoc_reg |= hw->mac.link_mode_select;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
msec_delay(50);
|
||||
}
|
||||
|
||||
/* Restart link */
|
||||
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
||||
|
||||
/* Only poll for autoneg to complete if specified to do so */
|
||||
if (hw->phy.autoneg_wait_to_complete) {
|
||||
if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN ||
|
||||
hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
|
||||
if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
|
||||
IXGBE_AUTOC_LMS_KX4_AN ||
|
||||
(autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
|
||||
IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
|
||||
links_reg = 0; /* Just in case Autoneg time = 0 */
|
||||
for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
|
||||
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
|
||||
|
|
@ -526,9 +468,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set up flow control */
|
||||
status = ixgbe_setup_fc_82598(hw, 0);
|
||||
|
||||
/* Add delay to filter out noises during initial link setup */
|
||||
msec_delay(50);
|
||||
|
||||
|
|
@ -616,6 +555,11 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
|
|||
else
|
||||
*speed = IXGBE_LINK_SPEED_1GB_FULL;
|
||||
|
||||
/* if link is down, zero out the current_mode */
|
||||
if (*link_up == FALSE) {
|
||||
hw->fc.current_mode = ixgbe_fc_none;
|
||||
hw->fc.fc_was_autonegged = FALSE;
|
||||
}
|
||||
out:
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
|
@ -633,28 +577,34 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
|
|||
ixgbe_link_speed speed, bool autoneg,
|
||||
bool autoneg_wait_to_complete)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
|
||||
u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
u32 autoc = curr_autoc;
|
||||
u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
|
||||
|
||||
/* If speed is 10G, then check for CX4 or XAUI. */
|
||||
if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
|
||||
(!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
|
||||
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
|
||||
} else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
|
||||
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
|
||||
} else if (autoneg) {
|
||||
/* BX mode - Autonegotiate 1G */
|
||||
if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
|
||||
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
|
||||
else /* KX/KX4 mode */
|
||||
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN_1G_AN;
|
||||
} else {
|
||||
/* Check to see if speed passed in is supported. */
|
||||
ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
|
||||
speed &= link_capabilities;
|
||||
|
||||
if (speed == IXGBE_LINK_SPEED_UNKNOWN)
|
||||
status = IXGBE_ERR_LINK_SETUP;
|
||||
|
||||
/* Set KX4/KX support according to speed requested */
|
||||
else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
|
||||
link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
|
||||
autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
|
||||
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
|
||||
autoc |= IXGBE_AUTOC_KX4_SUPP;
|
||||
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
|
||||
autoc |= IXGBE_AUTOC_KX_SUPP;
|
||||
if (autoc != curr_autoc)
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
|
||||
}
|
||||
|
||||
if (status == IXGBE_SUCCESS) {
|
||||
hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete;
|
||||
|
||||
hw->mac.link_settings_loaded = TRUE;
|
||||
/*
|
||||
* Setup and restart the link based on the new values in
|
||||
* ixgbe_hw This will write the AUTOC register based on the new
|
||||
|
|
@ -683,10 +633,6 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
|
|||
/* Restart autonegotiation on PHY */
|
||||
status = hw->phy.ops.setup_link(hw);
|
||||
|
||||
/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
|
||||
hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
|
||||
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
|
||||
|
||||
/* Set up MAC */
|
||||
ixgbe_setup_mac_link_82598(hw);
|
||||
|
||||
|
|
@ -712,110 +658,12 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
|
|||
/* Setup the PHY according to input speed */
|
||||
status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
|
||||
autoneg_wait_to_complete);
|
||||
|
||||
/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
|
||||
hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
|
||||
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
|
||||
|
||||
/* Set up MAC */
|
||||
ixgbe_setup_mac_link_82598(hw);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifndef NO_82598_A0_SUPPORT
|
||||
/**
|
||||
* ixgbe_reset_hw_rev_0_82598 - Performs hardware reset
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Resets the hardware by resetting the transmit and receive units, masks and
|
||||
* clears all interrupts, performing a PHY reset, and performing a link (MAC)
|
||||
* reset.
|
||||
**/
|
||||
s32 ixgbe_reset_hw_rev_0_82598(struct ixgbe_hw *hw)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
u32 ctrl;
|
||||
u32 gheccr;
|
||||
u32 autoc;
|
||||
u32 i;
|
||||
u32 resets;
|
||||
|
||||
/* Call adapter stop to disable tx/rx and clear interrupts */
|
||||
hw->mac.ops.stop_adapter(hw);
|
||||
|
||||
/* Reset PHY */
|
||||
hw->phy.ops.reset(hw);
|
||||
|
||||
for (resets = 0; resets < 10; resets++) {
|
||||
/*
|
||||
* Prevent the PCI-E bus from from hanging by disabling PCI-E
|
||||
* master access and verify no pending requests before reset
|
||||
*/
|
||||
if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS) {
|
||||
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
|
||||
DEBUGOUT("PCI-E Master disable polling has failed.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue global reset to the MAC. This needs to be a SW reset.
|
||||
* If link reset is used, it might reset the MAC when mng is
|
||||
* using it.
|
||||
*/
|
||||
ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
/*
|
||||
* Poll for reset bit to self-clear indicating reset is
|
||||
* complete
|
||||
*/
|
||||
for (i = 0; i < 10; i++) {
|
||||
usec_delay(1);
|
||||
ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
|
||||
if (!(ctrl & IXGBE_CTRL_RST))
|
||||
break;
|
||||
}
|
||||
if (ctrl & IXGBE_CTRL_RST) {
|
||||
status = IXGBE_ERR_RESET_FAILED;
|
||||
DEBUGOUT("Reset polling failed to complete.\n");
|
||||
}
|
||||
}
|
||||
|
||||
msec_delay(50);
|
||||
|
||||
gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
|
||||
gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6));
|
||||
IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
|
||||
|
||||
/*
|
||||
* AUTOC register which stores link settings gets cleared
|
||||
* and reloaded from EEPROM after reset. We need to restore
|
||||
* our stored value from init in case SW changed the attach
|
||||
* type or speed. If this is the first time and link settings
|
||||
* have not been stored, store default settings from AUTOC.
|
||||
*/
|
||||
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
if (hw->mac.link_settings_loaded) {
|
||||
autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE);
|
||||
autoc &= ~(IXGBE_AUTOC_LMS_MASK);
|
||||
autoc |= hw->mac.link_attach_type;
|
||||
autoc |= hw->mac.link_mode_select;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
|
||||
} else {
|
||||
hw->mac.link_attach_type =
|
||||
(autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
|
||||
hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
|
||||
hw->mac.link_settings_loaded = TRUE;
|
||||
}
|
||||
|
||||
/* Store the permanent mac address */
|
||||
hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* NO_A0_SUPPORT */
|
||||
/**
|
||||
* ixgbe_reset_hw_82598 - Performs hardware reset
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -870,14 +718,23 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
|
|||
}
|
||||
|
||||
/* Reset PHY */
|
||||
if (hw->phy.reset_disable == FALSE)
|
||||
if (hw->phy.reset_disable == FALSE) {
|
||||
/* PHY ops must be identified and initialized prior to reset */
|
||||
|
||||
/* Init PHY and function pointers, perform SFP setup */
|
||||
status = hw->phy.ops.init(hw);
|
||||
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
|
||||
goto reset_hw_out;
|
||||
|
||||
hw->phy.ops.reset(hw);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
|
||||
* access and verify no pending requests before reset
|
||||
*/
|
||||
if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS) {
|
||||
status = ixgbe_disable_pcie_master(hw);
|
||||
if (status != IXGBE_SUCCESS) {
|
||||
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
|
||||
DEBUGOUT("PCI-E Master disable polling has failed.\n");
|
||||
}
|
||||
|
|
@ -909,29 +766,27 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
|
|||
IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
|
||||
|
||||
/*
|
||||
* AUTOC register which stores link settings gets cleared
|
||||
* and reloaded from EEPROM after reset. We need to restore
|
||||
* our stored value from init in case SW changed the attach
|
||||
* type or speed. If this is the first time and link settings
|
||||
* have not been stored, store default settings from AUTOC.
|
||||
* Store the original AUTOC value if it has not been
|
||||
* stored off yet. Otherwise restore the stored original
|
||||
* AUTOC value since the reset operation sets back to deaults.
|
||||
*/
|
||||
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
if (hw->mac.link_settings_loaded) {
|
||||
autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE);
|
||||
autoc &= ~(IXGBE_AUTOC_LMS_MASK);
|
||||
autoc |= hw->mac.link_attach_type;
|
||||
autoc |= hw->mac.link_mode_select;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
|
||||
} else {
|
||||
hw->mac.link_attach_type =
|
||||
(autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
|
||||
hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
|
||||
hw->mac.link_settings_loaded = TRUE;
|
||||
}
|
||||
if (hw->mac.orig_link_settings_stored == FALSE) {
|
||||
hw->mac.orig_autoc = autoc;
|
||||
hw->mac.orig_link_settings_stored = TRUE;
|
||||
} else if (autoc != hw->mac.orig_autoc)
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
|
||||
|
||||
/*
|
||||
* Store MAC address from RAR0, clear receive address registers, and
|
||||
* clear the multicast table
|
||||
*/
|
||||
hw->mac.ops.init_rx_addrs(hw);
|
||||
|
||||
/* Store the permanent mac address */
|
||||
hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
|
||||
|
||||
reset_hw_out:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -1048,61 +903,6 @@ static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
|
|||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_blink_led_start_82598 - Blink LED based on index.
|
||||
* @hw: pointer to hardware structure
|
||||
* @index: led number to blink
|
||||
**/
|
||||
static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index)
|
||||
{
|
||||
ixgbe_link_speed speed = 0;
|
||||
bool link_up = 0;
|
||||
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
|
||||
|
||||
/*
|
||||
* Link must be up to auto-blink the LEDs on the 82598EB MAC;
|
||||
* force it if link is down.
|
||||
*/
|
||||
hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
|
||||
|
||||
if (!link_up) {
|
||||
autoc_reg |= IXGBE_AUTOC_FLU;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
||||
msec_delay(10);
|
||||
}
|
||||
|
||||
led_reg &= ~IXGBE_LED_MODE_MASK(index);
|
||||
led_reg |= IXGBE_LED_BLINK(index);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_blink_led_stop_82598 - Stop blinking LED based on index.
|
||||
* @hw: pointer to hardware structure
|
||||
* @index: led number to stop blinking
|
||||
**/
|
||||
static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index)
|
||||
{
|
||||
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
|
||||
|
||||
autoc_reg &= ~IXGBE_AUTOC_FLU;
|
||||
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
||||
|
||||
led_reg &= ~IXGBE_LED_MODE_MASK(index);
|
||||
led_reg &= ~IXGBE_LED_BLINK(index);
|
||||
led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -1216,33 +1016,56 @@ out:
|
|||
u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
|
||||
u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
|
||||
u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
|
||||
u16 ext_ability = 0;
|
||||
|
||||
switch (hw->device_id) {
|
||||
case IXGBE_DEV_ID_82598:
|
||||
/* Default device ID is mezzanine card KX/KX4 */
|
||||
physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
|
||||
IXGBE_PHYSICAL_LAYER_1000BASE_KX);
|
||||
hw->phy.ops.identify(hw);
|
||||
|
||||
/* Copper PHY must be checked before AUTOC LMS to determine correct
|
||||
* physical layer because 10GBase-T PHYs use LMS = KX4/KX */
|
||||
if (hw->phy.type == ixgbe_phy_tn ||
|
||||
hw->phy.type == ixgbe_phy_cu_unknown) {
|
||||
hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
|
||||
IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
|
||||
if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
|
||||
physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
|
||||
if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
|
||||
physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
|
||||
if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
|
||||
physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (autoc & IXGBE_AUTOC_LMS_MASK) {
|
||||
case IXGBE_AUTOC_LMS_1G_AN:
|
||||
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
|
||||
if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
|
||||
else
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598EB_CX4:
|
||||
case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
|
||||
case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
|
||||
if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
|
||||
else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
|
||||
else /* XAUI */
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
|
||||
case IXGBE_AUTOC_LMS_KX4_AN:
|
||||
case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
|
||||
if (autoc & IXGBE_AUTOC_KX_SUPP)
|
||||
physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
|
||||
if (autoc & IXGBE_AUTOC_KX4_SUPP)
|
||||
physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
|
||||
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
|
||||
case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
|
||||
default:
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598EB_XF_LR:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598AT:
|
||||
physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
|
||||
IXGBE_PHYSICAL_LAYER_1000BASE_T);
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598EB_SFP_LOM:
|
||||
}
|
||||
|
||||
if (hw->phy.type == ixgbe_phy_nl) {
|
||||
hw->phy.ops.identify_sfp(hw);
|
||||
|
||||
switch (hw->phy.sfp_type) {
|
||||
|
|
@ -1259,12 +1082,24 @@ u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
|
|||
physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (hw->device_id) {
|
||||
case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
|
||||
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
|
||||
case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
|
||||
break;
|
||||
case IXGBE_DEV_ID_82598EB_XF_LR:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
|
||||
break;
|
||||
default:
|
||||
physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return physical_layer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
#include "ixgbe_common.h"
|
||||
|
||||
extern s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw);
|
||||
extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw);
|
||||
|
||||
/**
|
||||
* ixgbe_init_shared_code - Initialize the shared code
|
||||
|
|
@ -62,6 +63,9 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw)
|
|||
case ixgbe_mac_82598EB:
|
||||
status = ixgbe_init_ops_82598(hw);
|
||||
break;
|
||||
case ixgbe_mac_82599EB:
|
||||
status = ixgbe_init_ops_82599(hw);
|
||||
break;
|
||||
default:
|
||||
status = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
|
||||
break;
|
||||
|
|
@ -86,6 +90,7 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
|
|||
if (hw->vendor_id == IXGBE_INTEL_VENDOR_ID) {
|
||||
switch (hw->device_id) {
|
||||
case IXGBE_DEV_ID_82598:
|
||||
case IXGBE_DEV_ID_82598_BX:
|
||||
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
|
||||
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
|
||||
case IXGBE_DEV_ID_82598AT:
|
||||
|
|
@ -97,6 +102,11 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
|
|||
case IXGBE_DEV_ID_82598EB_SFP_LOM:
|
||||
hw->mac.type = ixgbe_mac_82598EB;
|
||||
break;
|
||||
case IXGBE_DEV_ID_82599_KX4:
|
||||
case IXGBE_DEV_ID_82599_SFP:
|
||||
case IXGBE_DEV_ID_82599_CX4:
|
||||
hw->mac.type = ixgbe_mac_82599EB;
|
||||
break;
|
||||
default:
|
||||
ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
|
||||
break;
|
||||
|
|
@ -192,6 +202,46 @@ s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
|
|||
(hw, mac_addr), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_san_mac_addr - Get SAN MAC address
|
||||
* @hw: pointer to hardware structure
|
||||
* @san_mac_addr: SAN MAC address
|
||||
*
|
||||
* Reads the SAN MAC address from the EEPROM, if it's available. This is
|
||||
* per-port, so set_lan_id() must be called before reading the addresses.
|
||||
**/
|
||||
s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->mac.ops.get_san_mac_addr,
|
||||
(hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_set_san_mac_addr - Write a SAN MAC address
|
||||
* @hw: pointer to hardware structure
|
||||
* @san_mac_addr: SAN MAC address
|
||||
*
|
||||
* Writes A SAN MAC address to the EEPROM.
|
||||
**/
|
||||
s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->mac.ops.set_san_mac_addr,
|
||||
(hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_device_caps - Get additional device capabilities
|
||||
* @hw: pointer to hardware structure
|
||||
* @device_caps: the EEPROM word for device capabilities
|
||||
*
|
||||
* Reads the extra device capabilities from the EEPROM
|
||||
**/
|
||||
s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->mac.ops.get_device_caps,
|
||||
(hw, device_caps), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_bus_info - Set PCI bus info
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -319,6 +369,9 @@ s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw, u16 *firmware_version)
|
|||
s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
|
||||
u16 *phy_data)
|
||||
{
|
||||
if (hw->phy.id == 0)
|
||||
ixgbe_identify_phy(hw);
|
||||
|
||||
return ixgbe_call_func(hw, hw->phy.ops.read_reg, (hw, reg_addr,
|
||||
device_type, phy_data), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
|
@ -334,6 +387,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
|
|||
s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type,
|
||||
u16 phy_data)
|
||||
{
|
||||
if (hw->phy.id == 0)
|
||||
ixgbe_identify_phy(hw);
|
||||
|
||||
return ixgbe_call_func(hw, hw->phy.ops.write_reg, (hw, reg_addr,
|
||||
device_type, phy_data), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
|
@ -556,6 +612,22 @@ s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw)
|
|||
IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_insert_mac_addr - Find a RAR for this mac address
|
||||
* @hw: pointer to hardware structure
|
||||
* @addr: Address to put into receive address register
|
||||
* @vmdq: VMDq pool to assign
|
||||
*
|
||||
* Puts an ethernet address into a receive address register, or
|
||||
* finds the rar that it is aleady in; adds to the pool list
|
||||
**/
|
||||
s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->mac.ops.insert_mac_addr,
|
||||
(hw, addr, vmdq),
|
||||
IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_set_rar - Set Rx address register
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -724,15 +796,15 @@ s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on)
|
|||
}
|
||||
|
||||
/**
|
||||
* ixgbe_setup_fc - Set flow control
|
||||
* ixgbe_fc_enable - Enable flow control
|
||||
* @hw: pointer to hardware structure
|
||||
* @packetbuf_num: packet buffer number (0-7)
|
||||
*
|
||||
* Configures the flow control settings based on SW configuration.
|
||||
**/
|
||||
s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||
s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->mac.ops.setup_fc, (hw, packetbuf_num),
|
||||
return ixgbe_call_func(hw, hw->mac.ops.fc_enable, (hw, packetbuf_num),
|
||||
IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
|
|
@ -777,6 +849,53 @@ s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw)
|
|||
IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_read_i2c_byte - Reads 8 bit word over I2C at specified device address
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: byte offset to read
|
||||
* @data: value read
|
||||
*
|
||||
* Performs byte read operation to SFP module's EEPROM over I2C interface.
|
||||
**/
|
||||
s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
|
||||
u8 *data)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->phy.ops.read_i2c_byte, (hw, byte_offset,
|
||||
dev_addr, data), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_write_i2c_byte - Writes 8 bit word over I2C
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: byte offset to write
|
||||
* @data: value to write
|
||||
*
|
||||
* Performs byte write operation to SFP module's EEPROM over I2C interface
|
||||
* at a specified device address.
|
||||
**/
|
||||
s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
|
||||
u8 data)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->phy.ops.write_i2c_byte, (hw, byte_offset,
|
||||
dev_addr, data), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: EEPROM byte offset to write
|
||||
* @eeprom_data: value to write
|
||||
*
|
||||
* Performs byte write operation to SFP module's EEPROM over I2C interface.
|
||||
**/
|
||||
s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw,
|
||||
u8 byte_offset, u8 eeprom_data)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->phy.ops.write_i2c_eeprom,
|
||||
(hw, byte_offset, eeprom_data),
|
||||
IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_read_i2c_eeprom - Reads 8 bit EEPROM word over I2C interface
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -803,3 +922,16 @@ u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw)
|
|||
return ixgbe_call_func(hw, hw->mac.ops.get_supported_physical_layer,
|
||||
(hw), IXGBE_PHYSICAL_LAYER_UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_enable_rx_dma - Enables Rx DMA unit, dependant on device specifics
|
||||
* @hw: pointer to hardware structure
|
||||
* @regval: bitfield to write to the Rx DMA register
|
||||
*
|
||||
* Enables the Rx DMA unit of the device.
|
||||
**/
|
||||
s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval)
|
||||
{
|
||||
return ixgbe_call_func(hw, hw->mac.ops.enable_rx_dma,
|
||||
(hw, regval), IXGBE_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -85,6 +85,7 @@ s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data);
|
|||
s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
|
||||
s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw);
|
||||
|
||||
s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
|
||||
s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
|
||||
u32 enable_addr);
|
||||
s32 ixgbe_clear_rar(struct ixgbe_hw *hw, u32 index);
|
||||
|
|
@ -102,7 +103,7 @@ s32 ixgbe_clear_vfta(struct ixgbe_hw *hw);
|
|||
s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan,
|
||||
u32 vind, bool vlan_on);
|
||||
|
||||
s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||
s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||
|
||||
void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr);
|
||||
s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw,
|
||||
|
|
@ -112,5 +113,54 @@ s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val);
|
|||
s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data);
|
||||
u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval);
|
||||
s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
|
||||
s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
|
||||
s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
|
||||
struct ixgbe_atr_input *input,
|
||||
u8 queue);
|
||||
s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
|
||||
struct ixgbe_atr_input *input,
|
||||
u16 soft_id,
|
||||
u8 queue);
|
||||
u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key);
|
||||
s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan_id);
|
||||
s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr);
|
||||
s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr);
|
||||
s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, u32 src_addr_1,
|
||||
u32 src_addr_2, u32 src_addr_3,
|
||||
u32 src_addr_4);
|
||||
s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 dst_addr_1,
|
||||
u32 dst_addr_2, u32 dst_addr_3,
|
||||
u32 dst_addr_4);
|
||||
s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port);
|
||||
s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port);
|
||||
s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte);
|
||||
s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool);
|
||||
s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type);
|
||||
s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan_id);
|
||||
s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr);
|
||||
s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr);
|
||||
s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, u32 *src_addr_1,
|
||||
u32 *src_addr_2, u32 *src_addr_3,
|
||||
u32 *src_addr_4);
|
||||
s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 *dst_addr_1,
|
||||
u32 *dst_addr_2, u32 *dst_addr_3,
|
||||
u32 *dst_addr_4);
|
||||
s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port);
|
||||
s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port);
|
||||
s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input,
|
||||
u16 *flex_byte);
|
||||
s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool);
|
||||
s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type);
|
||||
s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
|
||||
u8 *data);
|
||||
s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
|
||||
u8 data);
|
||||
s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data);
|
||||
s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
|
||||
s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
|
||||
s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps);
|
||||
|
||||
#endif /* _IXGBE_API_H_ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -49,11 +49,7 @@ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
|
|||
static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
|
||||
static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw);
|
||||
|
||||
static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
|
||||
static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
|
||||
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
|
||||
void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
|
||||
void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
|
||||
|
||||
/**
|
||||
* ixgbe_init_ops_generic - Inits function ptrs
|
||||
|
|
@ -86,6 +82,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
|
|||
mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic;
|
||||
mac->ops.get_media_type = NULL;
|
||||
mac->ops.get_supported_physical_layer = NULL;
|
||||
mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic;
|
||||
mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic;
|
||||
mac->ops.stop_adapter = &ixgbe_stop_adapter_generic;
|
||||
mac->ops.get_bus_info = &ixgbe_get_bus_info_generic;
|
||||
|
|
@ -94,12 +91,13 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
|
|||
/* LEDs */
|
||||
mac->ops.led_on = &ixgbe_led_on_generic;
|
||||
mac->ops.led_off = &ixgbe_led_off_generic;
|
||||
mac->ops.blink_led_start = NULL;
|
||||
mac->ops.blink_led_stop = NULL;
|
||||
mac->ops.blink_led_start = &ixgbe_blink_led_start_generic;
|
||||
mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic;
|
||||
|
||||
/* RAR, Multicast, VLAN */
|
||||
mac->ops.set_rar = &ixgbe_set_rar_generic;
|
||||
mac->ops.clear_rar = &ixgbe_clear_rar_generic;
|
||||
mac->ops.insert_mac_addr = NULL;
|
||||
mac->ops.set_vmdq = NULL;
|
||||
mac->ops.clear_vmdq = NULL;
|
||||
mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic;
|
||||
|
|
@ -111,6 +109,8 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
|
|||
mac->ops.set_vfta = NULL;
|
||||
mac->ops.init_uta_tables = NULL;
|
||||
|
||||
/* Flow Control */
|
||||
mac->ops.fc_enable = &ixgbe_fc_enable_generic;
|
||||
|
||||
/* Link */
|
||||
mac->ops.get_link_capabilities = NULL;
|
||||
|
|
@ -133,28 +133,16 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
|
|||
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 ctrl_ext;
|
||||
s32 ret_val = IXGBE_SUCCESS;
|
||||
|
||||
/* Set the media type */
|
||||
hw->phy.media_type = hw->mac.ops.get_media_type(hw);
|
||||
|
||||
/* Set bus info */
|
||||
hw->mac.ops.get_bus_info(hw);
|
||||
|
||||
/* Identify the PHY */
|
||||
hw->phy.ops.identify(hw);
|
||||
|
||||
/*
|
||||
* Store MAC address from RAR0, clear receive address registers, and
|
||||
* clear the multicast table
|
||||
*/
|
||||
hw->mac.ops.init_rx_addrs(hw);
|
||||
/* PHY ops initialization must be done in reset_hw() */
|
||||
|
||||
/* Clear the VLAN filter table */
|
||||
hw->mac.ops.clear_vfta(hw);
|
||||
|
||||
/* Set up link */
|
||||
hw->mac.ops.setup_link(hw);
|
||||
|
||||
/* Clear statistics registers */
|
||||
hw->mac.ops.clear_hw_cntrs(hw);
|
||||
|
||||
|
|
@ -164,10 +152,13 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
|
|||
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
/* Setup flow control */
|
||||
ixgbe_setup_fc(hw, 0);
|
||||
|
||||
/* Clear adapter stopped flag */
|
||||
hw->adapter_stopped = FALSE;
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -182,13 +173,17 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
|
|||
**/
|
||||
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
|
||||
/* Reset the hardware */
|
||||
hw->mac.ops.reset_hw(hw);
|
||||
status = hw->mac.ops.reset_hw(hw);
|
||||
|
||||
/* Start the HW */
|
||||
hw->mac.ops.start_hw(hw);
|
||||
if (status == IXGBE_SUCCESS) {
|
||||
/* Start the HW */
|
||||
status = hw->mac.ops.start_hw(hw);
|
||||
}
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -214,15 +209,28 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
|
|||
IXGBE_READ_REG(hw, IXGBE_RLEC);
|
||||
IXGBE_READ_REG(hw, IXGBE_LXONTXC);
|
||||
IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
|
||||
IXGBE_READ_REG(hw, IXGBE_LXONRXC);
|
||||
IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
|
||||
if (hw->mac.type >= ixgbe_mac_82599EB) {
|
||||
IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
|
||||
IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
|
||||
} else {
|
||||
IXGBE_READ_REG(hw, IXGBE_LXONRXC);
|
||||
IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
|
||||
IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
|
||||
IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
|
||||
IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
|
||||
if (hw->mac.type >= ixgbe_mac_82599EB) {
|
||||
IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
|
||||
IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
|
||||
} else {
|
||||
IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
|
||||
IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
|
||||
}
|
||||
}
|
||||
if (hw->mac.type >= ixgbe_mac_82599EB)
|
||||
for (i = 0; i < 8; i++)
|
||||
IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
|
||||
IXGBE_READ_REG(hw, IXGBE_PRC64);
|
||||
IXGBE_READ_REG(hw, IXGBE_PRC127);
|
||||
IXGBE_READ_REG(hw, IXGBE_PRC255);
|
||||
|
|
@ -391,6 +399,7 @@ void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
|
|||
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
|
||||
bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
|
||||
bus->lan_id = bus->func;
|
||||
|
||||
/* check for a port swap */
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_FACTPS);
|
||||
|
|
@ -595,7 +604,6 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
|
|||
ixgbe_shift_out_eeprom_bits(hw, data, 16);
|
||||
ixgbe_standby_eeprom(hw);
|
||||
|
||||
msec_delay(hw->eeprom.semaphore_delay);
|
||||
/* Done with writing - release the EEPROM */
|
||||
ixgbe_release_eeprom(hw);
|
||||
}
|
||||
|
|
@ -802,7 +810,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
|
|||
status = IXGBE_SUCCESS;
|
||||
break;
|
||||
}
|
||||
msec_delay(1);
|
||||
usec_delay(50);
|
||||
}
|
||||
|
||||
/* Now get the semaphore between SW/FW through the SWESMBI bit */
|
||||
|
|
@ -830,11 +838,14 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
|
|||
* was not granted because we don't have access to the EEPROM
|
||||
*/
|
||||
if (i >= timeout) {
|
||||
DEBUGOUT("Driver can't access the Eeprom - Semaphore "
|
||||
DEBUGOUT("SWESMBI Software EEPROM semaphore "
|
||||
"not granted.\n");
|
||||
ixgbe_release_eeprom_semaphore(hw);
|
||||
status = IXGBE_ERR_EEPROM;
|
||||
}
|
||||
} else {
|
||||
DEBUGOUT("Software semaphore SMBI between device drivers "
|
||||
"not granted.\n");
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
@ -1295,38 +1306,6 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
|
|||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_enable_rar - Enable Rx address register
|
||||
* @hw: pointer to hardware structure
|
||||
* @index: index into the RAR table
|
||||
*
|
||||
* Enables the select receive address register.
|
||||
**/
|
||||
static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index)
|
||||
{
|
||||
u32 rar_high;
|
||||
|
||||
rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
|
||||
rar_high |= IXGBE_RAH_AV;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_disable_rar - Disable Rx address register
|
||||
* @hw: pointer to hardware structure
|
||||
* @index: index into the RAR table
|
||||
*
|
||||
* Disables the select receive address register.
|
||||
**/
|
||||
static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index)
|
||||
{
|
||||
u32 rar_high;
|
||||
|
||||
rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
|
||||
rar_high &= (~IXGBE_RAH_AV);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_init_rx_addrs_generic - Initializes receive address filters.
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -1378,7 +1357,6 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
|
|||
}
|
||||
|
||||
/* Clear the MTA */
|
||||
hw->addr_ctrl.mc_addr_in_rar_count = 0;
|
||||
hw->addr_ctrl.mta_in_use = 0;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
|
||||
|
||||
|
|
@ -1411,8 +1389,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
|
|||
* else put the controller into promiscuous mode
|
||||
*/
|
||||
if (hw->addr_ctrl.rar_used_count < rar_entries) {
|
||||
rar = hw->addr_ctrl.rar_used_count -
|
||||
hw->addr_ctrl.mc_addr_in_rar_count;
|
||||
rar = hw->addr_ctrl.rar_used_count;
|
||||
hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
|
||||
DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar);
|
||||
hw->addr_ctrl.rar_used_count++;
|
||||
|
|
@ -1451,14 +1428,13 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
|
|||
* Clear accounting of old secondary address list,
|
||||
* don't count RAR[0]
|
||||
*/
|
||||
uc_addr_in_use = hw->addr_ctrl.rar_used_count -
|
||||
hw->addr_ctrl.mc_addr_in_rar_count - 1;
|
||||
uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
|
||||
hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
|
||||
hw->addr_ctrl.overflow_promisc = 0;
|
||||
|
||||
/* Zero out the other receive addresses */
|
||||
DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use);
|
||||
for (i = 1; i <= uc_addr_in_use; i++) {
|
||||
DEBUGOUT1("Clearing RAR[1-%d]\n", hw->addr_ctrl.rar_used_count);
|
||||
for (i = 1; i <= hw->addr_ctrl.rar_used_count; i++) {
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
|
||||
}
|
||||
|
|
@ -1567,40 +1543,6 @@ void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
|
|||
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_add_mc_addr - Adds a multicast address.
|
||||
* @hw: pointer to hardware structure
|
||||
* @mc_addr: new multicast address
|
||||
*
|
||||
* Adds it to unused receive address register or to the multicast table.
|
||||
**/
|
||||
void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
|
||||
{
|
||||
u32 rar_entries = hw->mac.num_rar_entries;
|
||||
u32 rar;
|
||||
|
||||
DEBUGOUT6(" MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
|
||||
mc_addr[0], mc_addr[1], mc_addr[2],
|
||||
mc_addr[3], mc_addr[4], mc_addr[5]);
|
||||
|
||||
/*
|
||||
* Place this multicast address in the RAR if there is room,
|
||||
* else put it in the MTA
|
||||
*/
|
||||
if (hw->addr_ctrl.rar_used_count < rar_entries) {
|
||||
/* use RAR from the end up for multicast */
|
||||
rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1;
|
||||
hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV);
|
||||
DEBUGOUT1("Added a multicast address to RAR[%d]\n", rar);
|
||||
hw->addr_ctrl.rar_used_count++;
|
||||
hw->addr_ctrl.mc_addr_in_rar_count++;
|
||||
} else {
|
||||
ixgbe_set_mta(hw, mc_addr);
|
||||
}
|
||||
|
||||
DEBUGOUT("ixgbe_add_mc_addr Complete\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -1617,7 +1559,6 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
|
|||
u32 mc_addr_count, ixgbe_mc_addr_itr next)
|
||||
{
|
||||
u32 i;
|
||||
u32 rar_entries = hw->mac.num_rar_entries;
|
||||
u32 vmdq;
|
||||
|
||||
/*
|
||||
|
|
@ -1625,18 +1566,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
|
|||
* use.
|
||||
*/
|
||||
hw->addr_ctrl.num_mc_addrs = mc_addr_count;
|
||||
hw->addr_ctrl.rar_used_count -= hw->addr_ctrl.mc_addr_in_rar_count;
|
||||
hw->addr_ctrl.mc_addr_in_rar_count = 0;
|
||||
hw->addr_ctrl.mta_in_use = 0;
|
||||
|
||||
/* Zero out the other receive addresses. */
|
||||
DEBUGOUT2("Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count,
|
||||
rar_entries - 1);
|
||||
for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) {
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
|
||||
}
|
||||
|
||||
/* Clear the MTA */
|
||||
DEBUGOUT(" Clearing MTA\n");
|
||||
for (i = 0; i < hw->mac.mcft_size; i++)
|
||||
|
|
@ -1645,7 +1576,7 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
|
|||
/* Add the new addresses */
|
||||
for (i = 0; i < mc_addr_count; i++) {
|
||||
DEBUGOUT(" Adding the multicast addresses:\n");
|
||||
ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq));
|
||||
ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq));
|
||||
}
|
||||
|
||||
/* Enable mta */
|
||||
|
|
@ -1665,15 +1596,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
|
|||
**/
|
||||
s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 i;
|
||||
u32 rar_entries = hw->mac.num_rar_entries;
|
||||
struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
|
||||
|
||||
if (a->mc_addr_in_rar_count > 0)
|
||||
for (i = (rar_entries - a->mc_addr_in_rar_count);
|
||||
i < rar_entries; i++)
|
||||
ixgbe_enable_rar(hw, i);
|
||||
|
||||
if (a->mta_in_use > 0)
|
||||
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
|
||||
hw->mac.mc_filter_type);
|
||||
|
|
@ -1689,52 +1613,56 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
|
|||
**/
|
||||
s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 i;
|
||||
u32 rar_entries = hw->mac.num_rar_entries;
|
||||
struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
|
||||
|
||||
if (a->mc_addr_in_rar_count > 0)
|
||||
for (i = (rar_entries - a->mc_addr_in_rar_count);
|
||||
i < rar_entries; i++)
|
||||
ixgbe_disable_rar(hw, i);
|
||||
|
||||
if (a->mta_in_use > 0)
|
||||
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ixgbe_fc_autoneg - Configure flow control
|
||||
* ixgbe_fc_enable_generic - Enable flow control
|
||||
* @hw: pointer to hardware structure
|
||||
* @packetbuf_num: packet buffer number (0-7)
|
||||
*
|
||||
* Negotiates flow control capabilities with link partner using autoneg and
|
||||
* applies the results.
|
||||
* Enable flow control according to the current settings.
|
||||
**/
|
||||
s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
||||
s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||
{
|
||||
s32 ret_val = IXGBE_SUCCESS;
|
||||
u32 i, reg, pcs_anadv_reg, pcs_lpab_reg;
|
||||
u32 mflcn_reg, fccfg_reg;
|
||||
u32 reg;
|
||||
|
||||
DEBUGFUNC("ixgbe_fc_autoneg");
|
||||
DEBUGFUNC("ixgbe_fc_enable_generic");
|
||||
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
|
||||
/* Negotiate the fc mode to use */
|
||||
ret_val = ixgbe_fc_autoneg(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Disable any previous flow control settings */
|
||||
mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
|
||||
mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
|
||||
|
||||
fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
|
||||
fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
|
||||
|
||||
/*
|
||||
* The possible values of fc.current_mode are:
|
||||
* 0: Flow control is completely disabled
|
||||
* 1: Rx flow control is enabled (we can receive pause frames,
|
||||
* but not send pause frames).
|
||||
* 2: Tx flow control is enabled (we can send pause frames but
|
||||
* we do not support receiving pause frames).
|
||||
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
||||
* 0: Flow control is completely disabled
|
||||
* 1: Rx flow control is enabled (we can receive pause frames,
|
||||
* but not send pause frames).
|
||||
* 2: Tx flow control is enabled (we can send pause frames but
|
||||
* we do not support receiving pause frames).
|
||||
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
||||
* other: Invalid.
|
||||
*/
|
||||
switch (hw->fc.current_mode) {
|
||||
case ixgbe_fc_none:
|
||||
/* Flow control completely disabled by software override. */
|
||||
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
/* Flow control is disabled by software override or autoneg.
|
||||
* The code below will actually disable it in the HW.
|
||||
*/
|
||||
break;
|
||||
case ixgbe_fc_rx_pause:
|
||||
/*
|
||||
|
|
@ -1745,19 +1673,19 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
|||
* symmetric and asymmetric Rx PAUSE. Later, we will
|
||||
* disable the adapter's ability to send PAUSE frames.
|
||||
*/
|
||||
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
mflcn_reg |= IXGBE_MFLCN_RFCE;
|
||||
break;
|
||||
case ixgbe_fc_tx_pause:
|
||||
/*
|
||||
* Tx Flow control is enabled, and Rx Flow control is
|
||||
* disabled by software override.
|
||||
*/
|
||||
reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
|
||||
fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
|
||||
break;
|
||||
case ixgbe_fc_full:
|
||||
/* Flow control (both Rx and Tx) is enabled by SW override. */
|
||||
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
mflcn_reg |= IXGBE_MFLCN_RFCE;
|
||||
fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
|
||||
break;
|
||||
default:
|
||||
DEBUGOUT("Flow control param set incorrectly\n");
|
||||
|
|
@ -1766,39 +1694,80 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
|||
break;
|
||||
}
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
|
||||
/* Set 802.3x based flow control settings. */
|
||||
mflcn_reg |= IXGBE_MFLCN_DPF;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
|
||||
|
||||
/* Set PCS register for autoneg */
|
||||
/* Enable and restart autoneg */
|
||||
reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
|
||||
|
||||
/* Disable AN timeout */
|
||||
if (hw->fc.strict_ieee)
|
||||
reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
|
||||
|
||||
DEBUGOUT1("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
|
||||
|
||||
/* See if autonegotiation has succeeded */
|
||||
hw->mac.autoneg_succeeded = 0;
|
||||
for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
|
||||
msec_delay(10);
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
|
||||
if ((reg & (IXGBE_PCS1GLSTA_LINK_OK |
|
||||
IXGBE_PCS1GLSTA_AN_COMPLETE)) ==
|
||||
(IXGBE_PCS1GLSTA_LINK_OK |
|
||||
IXGBE_PCS1GLSTA_AN_COMPLETE)) {
|
||||
if (!(reg & IXGBE_PCS1GLSTA_AN_TIMED_OUT))
|
||||
hw->mac.autoneg_succeeded = 1;
|
||||
break;
|
||||
/* Set up and enable Rx high/low water mark thresholds, enable XON. */
|
||||
if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
|
||||
if (hw->fc.send_xon) {
|
||||
IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
|
||||
(hw->fc.low_water | IXGBE_FCRTL_XONE));
|
||||
} else {
|
||||
IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
|
||||
hw->fc.low_water);
|
||||
}
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
|
||||
(hw->fc.high_water | IXGBE_FCRTH_FCEN));
|
||||
}
|
||||
|
||||
if (!hw->mac.autoneg_succeeded) {
|
||||
/* Autoneg failed to achieve a link, so we turn fc off */
|
||||
hw->fc.current_mode = ixgbe_fc_none;
|
||||
DEBUGOUT("Flow Control = NONE.\n");
|
||||
/* Configure pause time (2 TCs per register) */
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
|
||||
if ((packetbuf_num & 1) == 0)
|
||||
reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
|
||||
else
|
||||
reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_fc_autoneg - Configure flow control
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Compares our advertised flow control capabilities to those advertised by
|
||||
* our link partner, and determines the proper flow control mode to use.
|
||||
**/
|
||||
s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
||||
{
|
||||
s32 ret_val = IXGBE_SUCCESS;
|
||||
ixgbe_link_speed speed;
|
||||
u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
|
||||
bool link_up;
|
||||
|
||||
DEBUGFUNC("ixgbe_fc_autoneg");
|
||||
|
||||
/*
|
||||
* AN should have completed when the cable was plugged in.
|
||||
* Look for reasons to bail out. Bail out if:
|
||||
* - FC autoneg is disabled, or if
|
||||
* - we don't have multispeed fiber, or if
|
||||
* - we're not running at 1G, or if
|
||||
* - link is not up, or if
|
||||
* - link is up but AN did not complete, or if
|
||||
* - link is up and AN completed but timed out
|
||||
*
|
||||
* Since we're being called from an LSC, link is already know to be up.
|
||||
* So use link_up_wait_to_complete=FALSE.
|
||||
*/
|
||||
hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
|
||||
linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
|
||||
|
||||
if (hw->fc.disable_fc_autoneg ||
|
||||
!hw->phy.multispeed_fiber ||
|
||||
(speed != IXGBE_LINK_SPEED_1GB_FULL) ||
|
||||
!link_up ||
|
||||
((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
|
||||
((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
|
||||
hw->fc.fc_was_autonegged = FALSE;
|
||||
hw->fc.current_mode = hw->fc.requested_mode;
|
||||
DEBUGOUT("Autoneg FC was skipped.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -1841,10 +1810,128 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
|||
DEBUGOUT("Flow Control = NONE.\n");
|
||||
}
|
||||
|
||||
/* Record that current_mode is the result of a successful autoneg */
|
||||
hw->fc.fc_was_autonegged = TRUE;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_setup_fc - Set up flow control
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Called at init time to set up flow control.
|
||||
**/
|
||||
s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||
{
|
||||
s32 ret_val = IXGBE_SUCCESS;
|
||||
u32 reg;
|
||||
|
||||
|
||||
/* Validate the packetbuf configuration */
|
||||
if (packetbuf_num < 0 || packetbuf_num > 7) {
|
||||
DEBUGOUT1("Invalid packet buffer number [%d], expected range is"
|
||||
" 0-7\n", packetbuf_num);
|
||||
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the water mark configuration. Zero water marks are invalid
|
||||
* because it causes the controller to just blast out fc packets.
|
||||
*/
|
||||
if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
|
||||
DEBUGOUT("Invalid water mark configuration\n");
|
||||
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the requested mode. Strict IEEE mode does not allow
|
||||
* ixgbe_fc_rx_pause because it will cause us to fail at UNH.
|
||||
*/
|
||||
if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
|
||||
DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
|
||||
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* 10gig parts do not have a word in the EEPROM to determine the
|
||||
* default flow control setting, so we explicitly set it to full.
|
||||
*/
|
||||
if (hw->fc.requested_mode == ixgbe_fc_default)
|
||||
hw->fc.requested_mode = ixgbe_fc_full;
|
||||
|
||||
/*
|
||||
* Set up the 1G flow control advertisement registers so the HW will be
|
||||
* able to do fc autoneg once the cable is plugged in. If we end up
|
||||
* using 10g instead, this is harmless.
|
||||
*/
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
|
||||
|
||||
/*
|
||||
* The possible values of fc.requested_mode are:
|
||||
* 0: Flow control is completely disabled
|
||||
* 1: Rx flow control is enabled (we can receive pause frames,
|
||||
* but not send pause frames).
|
||||
* 2: Tx flow control is enabled (we can send pause frames but
|
||||
* we do not support receiving pause frames).
|
||||
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
||||
* other: Invalid.
|
||||
*/
|
||||
switch (hw->fc.requested_mode) {
|
||||
case ixgbe_fc_none:
|
||||
/* Flow control completely disabled by software override. */
|
||||
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
break;
|
||||
case ixgbe_fc_rx_pause:
|
||||
/*
|
||||
* Rx Flow control is enabled and Tx Flow control is
|
||||
* disabled by software override. Since there really
|
||||
* isn't a way to advertise that we are capable of RX
|
||||
* Pause ONLY, we will advertise that we support both
|
||||
* symmetric and asymmetric Rx PAUSE. Later, we will
|
||||
* disable the adapter's ability to send PAUSE frames.
|
||||
*/
|
||||
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
break;
|
||||
case ixgbe_fc_tx_pause:
|
||||
/*
|
||||
* Tx Flow control is enabled, and Rx Flow control is
|
||||
* disabled by software override.
|
||||
*/
|
||||
reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
|
||||
break;
|
||||
case ixgbe_fc_full:
|
||||
/* Flow control (both Rx and Tx) is enabled by SW override. */
|
||||
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||
break;
|
||||
default:
|
||||
DEBUGOUT("Flow control param set incorrectly\n");
|
||||
ret_val = -IXGBE_ERR_CONFIG;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
|
||||
|
||||
/* Enable and restart autoneg to inform the link partner */
|
||||
reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
|
||||
|
||||
/* Disable AN timeout */
|
||||
if (hw->fc.strict_ieee)
|
||||
reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
|
||||
DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_disable_pcie_master - Disable PCI-express master access
|
||||
|
|
@ -1904,6 +1991,10 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
|||
s32 timeout = 200;
|
||||
|
||||
while (timeout) {
|
||||
/*
|
||||
* SW EEPROM semaphore bit is used for access to all
|
||||
* SW_FW_SYNC/GSSR bits (not just EEPROM)
|
||||
*/
|
||||
if (ixgbe_get_eeprom_semaphore(hw))
|
||||
return -IXGBE_ERR_SWFW_SYNC;
|
||||
|
||||
|
|
@ -1921,7 +2012,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
|||
}
|
||||
|
||||
if (!timeout) {
|
||||
DEBUGOUT("Driver can't access resource, GSSR timeout.\n");
|
||||
DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
|
||||
return -IXGBE_ERR_SWFW_SYNC;
|
||||
}
|
||||
|
||||
|
|
@ -1952,5 +2043,77 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
|||
IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
|
||||
|
||||
ixgbe_release_eeprom_semaphore(hw);
|
||||
|
||||
/* Delay before attempt to obtain semaphore again to allow FW access */
|
||||
msec_delay(hw->eeprom.semaphore_delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
|
||||
* @hw: pointer to hardware structure
|
||||
* @regval: register value to write to RXCTRL
|
||||
*
|
||||
* Enables the Rx DMA unit
|
||||
**/
|
||||
s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
|
||||
{
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_blink_led_start_generic - Blink LED based on index.
|
||||
* @hw: pointer to hardware structure
|
||||
* @index: led number to blink
|
||||
**/
|
||||
s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
|
||||
{
|
||||
ixgbe_link_speed speed = 0;
|
||||
bool link_up = 0;
|
||||
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
|
||||
|
||||
/*
|
||||
* Link must be up to auto-blink the LEDs;
|
||||
* Force it if link is down.
|
||||
*/
|
||||
hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
|
||||
|
||||
if (!link_up) {
|
||||
autoc_reg |= IXGBE_AUTOC_FLU;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
||||
msec_delay(10);
|
||||
}
|
||||
|
||||
led_reg &= ~IXGBE_LED_MODE_MASK(index);
|
||||
led_reg |= IXGBE_LED_BLINK(index);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
|
||||
* @hw: pointer to hardware structure
|
||||
* @index: led number to stop blinking
|
||||
**/
|
||||
s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
|
||||
{
|
||||
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
|
||||
|
||||
autoc_reg &= ~IXGBE_AUTOC_FLU;
|
||||
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
||||
|
||||
led_reg &= ~IXGBE_LED_MODE_MASK(index);
|
||||
led_reg &= ~IXGBE_LED_BLINK(index);
|
||||
led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -36,6 +36,11 @@
|
|||
#define _IXGBE_COMMON_H_
|
||||
|
||||
#include "ixgbe_type.h"
|
||||
#define IXGBE_WRITE_REG64(hw, reg, value) \
|
||||
do { \
|
||||
IXGBE_WRITE_REG(hw, reg, (u32) value); \
|
||||
IXGBE_WRITE_REG(hw, reg + 4, (u32) (value >> 32)); \
|
||||
} while (0)
|
||||
|
||||
s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
|
||||
|
|
@ -68,11 +73,13 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
|
|||
ixgbe_mc_addr_itr func);
|
||||
s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
|
||||
u32 addr_count, ixgbe_mc_addr_itr func);
|
||||
void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
|
||||
s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
|
||||
|
||||
s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||
s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packtetbuf_num);
|
||||
s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||
s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num);
|
||||
s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
|
||||
|
||||
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
|
||||
|
|
@ -82,4 +89,7 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
|
|||
|
||||
s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val);
|
||||
s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
|
||||
s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
|
||||
s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
|
||||
|
||||
#endif /* IXGBE_COMMON */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -96,6 +96,7 @@ typedef boolean_t bool;
|
|||
|
||||
#define le16_to_cpu
|
||||
|
||||
#if __FreeBSD_version < 800000
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
#define mb() __asm volatile("mfence" ::: "memory")
|
||||
#define wmb() __asm volatile("sfence" ::: "memory")
|
||||
|
|
@ -105,6 +106,7 @@ typedef boolean_t bool;
|
|||
#define rmb()
|
||||
#define wmb()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct ixgbe_osdep
|
||||
{
|
||||
|
|
@ -113,11 +115,14 @@ struct ixgbe_osdep
|
|||
struct device *dev;
|
||||
};
|
||||
|
||||
/* This is needed by the shared code */
|
||||
/* These routines are needed by the shared code */
|
||||
struct ixgbe_hw;
|
||||
extern u16 ixgbe_read_pci_cfg(struct ixgbe_hw *, u32);
|
||||
#define IXGBE_READ_PCIE_WORD ixgbe_read_pci_cfg
|
||||
|
||||
extern void ixgbe_write_pci_cfg(struct ixgbe_hw *, u32, u16);
|
||||
#define IXGBE_WRITE_PCIE_WORD ixgbe_write_pci_cfg
|
||||
|
||||
#define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)
|
||||
|
||||
#define IXGBE_READ_REG(a, reg) (\
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -36,6 +36,19 @@
|
|||
#include "ixgbe_common.h"
|
||||
#include "ixgbe_phy.h"
|
||||
|
||||
static void ixgbe_i2c_start(struct ixgbe_hw *hw);
|
||||
static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
|
||||
static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
|
||||
static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
|
||||
static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
|
||||
static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
|
||||
static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
|
||||
static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
|
||||
static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
|
||||
static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
|
||||
static bool ixgbe_get_i2c_data(u32 *i2cctl);
|
||||
void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
|
||||
|
||||
/**
|
||||
* ixgbe_init_phy_ops_generic - Inits PHY function ptrs
|
||||
* @hw: pointer to the hardware structure
|
||||
|
|
@ -55,6 +68,11 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
|
|||
phy->ops.setup_link_speed = &ixgbe_setup_phy_link_speed_generic;
|
||||
phy->ops.check_link = NULL;
|
||||
phy->ops.get_firmware_version = NULL;
|
||||
phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic;
|
||||
phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic;
|
||||
phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic;
|
||||
phy->ops.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic;
|
||||
phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear;
|
||||
phy->ops.identify_sfp = &ixgbe_identify_sfp_module_generic;
|
||||
phy->sfp_type = ixgbe_sfp_type_unknown;
|
||||
|
||||
|
|
@ -71,6 +89,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
|
|||
{
|
||||
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
|
||||
u32 phy_addr;
|
||||
u16 ext_ability = 0;
|
||||
|
||||
if (hw->phy.type == ixgbe_phy_unknown) {
|
||||
for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
|
||||
|
|
@ -79,10 +98,29 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
|
|||
ixgbe_get_phy_id(hw);
|
||||
hw->phy.type =
|
||||
ixgbe_get_phy_type_from_id(hw->phy.id);
|
||||
|
||||
if (hw->phy.type == ixgbe_phy_unknown) {
|
||||
hw->phy.ops.read_reg(hw,
|
||||
IXGBE_MDIO_PHY_EXT_ABILITY,
|
||||
IXGBE_MDIO_PMA_PMD_DEV_TYPE,
|
||||
&ext_ability);
|
||||
if (ext_ability &
|
||||
IXGBE_MDIO_PHY_10GBASET_ABILITY ||
|
||||
ext_ability &
|
||||
IXGBE_MDIO_PHY_1000BASET_ABILITY)
|
||||
hw->phy.type =
|
||||
ixgbe_phy_cu_unknown;
|
||||
else
|
||||
hw->phy.type =
|
||||
ixgbe_phy_generic;
|
||||
}
|
||||
|
||||
status = IXGBE_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status != IXGBE_SUCCESS)
|
||||
hw->phy.addr = 0;
|
||||
} else {
|
||||
status = IXGBE_SUCCESS;
|
||||
}
|
||||
|
|
@ -149,6 +187,9 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
|
|||
case TN1010_PHY_ID:
|
||||
phy_type = ixgbe_phy_tn;
|
||||
break;
|
||||
case AQ1002_PHY_ID:
|
||||
phy_type = ixgbe_phy_aq;
|
||||
break;
|
||||
case QT2022_PHY_ID:
|
||||
phy_type = ixgbe_phy_qt;
|
||||
break;
|
||||
|
|
@ -170,13 +211,40 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
|
|||
**/
|
||||
s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 i;
|
||||
u16 ctrl = 0;
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
|
||||
if (hw->phy.type == ixgbe_phy_unknown)
|
||||
status = ixgbe_identify_phy_generic(hw);
|
||||
|
||||
if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Perform soft PHY reset to the PHY_XS.
|
||||
* This will cause a soft reset to the PHY
|
||||
*/
|
||||
return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
|
||||
IXGBE_MDIO_PHY_XS_DEV_TYPE,
|
||||
IXGBE_MDIO_PHY_XS_RESET);
|
||||
hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
|
||||
IXGBE_MDIO_PHY_XS_DEV_TYPE,
|
||||
IXGBE_MDIO_PHY_XS_RESET);
|
||||
|
||||
/* Poll for reset bit to self-clear indicating reset is complete */
|
||||
for (i = 0; i < 500; i++) {
|
||||
msec_delay(1);
|
||||
hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
|
||||
IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl);
|
||||
if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctrl & IXGBE_MDIO_PHY_XS_RESET) {
|
||||
status = IXGBE_ERR_RESET_FAILED;
|
||||
DEBUGOUT("PHY reset polling failed to complete.\n");
|
||||
}
|
||||
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -454,12 +522,49 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
|
|||
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
|
||||
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
|
||||
|
||||
if (speed & IXGBE_LINK_SPEED_100_FULL)
|
||||
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
|
||||
|
||||
/* Setup link based on the new speed settings */
|
||||
hw->phy.ops.setup_link(hw);
|
||||
|
||||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
|
||||
* @hw: pointer to hardware structure
|
||||
* @speed: pointer to link speed
|
||||
* @autoneg: boolean auto-negotiation value
|
||||
*
|
||||
* Determines the link capabilities by reading the AUTOC register.
|
||||
**/
|
||||
s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
|
||||
ixgbe_link_speed *speed,
|
||||
bool *autoneg)
|
||||
{
|
||||
s32 status = IXGBE_ERR_LINK_SETUP;
|
||||
u16 speed_ability;
|
||||
|
||||
*speed = 0;
|
||||
*autoneg = TRUE;
|
||||
|
||||
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
|
||||
IXGBE_MDIO_PMA_PMD_DEV_TYPE,
|
||||
&speed_ability);
|
||||
|
||||
if (status == IXGBE_SUCCESS) {
|
||||
if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
|
||||
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
|
||||
if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
|
||||
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
|
||||
if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M)
|
||||
*speed |= IXGBE_LINK_SPEED_100_FULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_check_phy_link_tnx - Determine link and speed status
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -525,6 +630,24 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ixgbe_get_phy_firmware_version_aq - Gets the PHY Firmware Version
|
||||
* @hw: pointer to hardware structure
|
||||
* @firmware_version: pointer to the PHY Firmware Version
|
||||
**/
|
||||
s32 ixgbe_get_phy_firmware_version_aq(struct ixgbe_hw *hw,
|
||||
u16 *firmware_version)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
|
||||
status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
|
||||
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
|
||||
firmware_version);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_reset_phy_nl - Performs a PHY reset
|
||||
* @hw: pointer to hardware structure
|
||||
|
|
@ -632,20 +755,30 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
|
|||
{
|
||||
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
|
||||
u32 vendor_oui = 0;
|
||||
enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
|
||||
u8 identifier = 0;
|
||||
u8 comp_codes_1g = 0;
|
||||
u8 comp_codes_10g = 0;
|
||||
u8 oui_bytes[4] = {0, 0, 0, 0};
|
||||
u8 oui_bytes[3] = {0, 0, 0};
|
||||
u8 transmission_media = 0;
|
||||
u16 enforce_sfp = 0;
|
||||
|
||||
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
|
||||
&identifier);
|
||||
|
||||
if (status == IXGBE_ERR_SFP_NOT_PRESENT) {
|
||||
if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) {
|
||||
status = IXGBE_ERR_SFP_NOT_PRESENT;
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
|
||||
if (hw->phy.type != ixgbe_phy_nl) {
|
||||
hw->phy.id = 0;
|
||||
hw->phy.type = ixgbe_phy_unknown;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* LAN ID is needed for sfp_type determination */
|
||||
hw->mac.ops.set_lan_id(hw);
|
||||
|
||||
if (identifier == IXGBE_SFF_IDENTIFIER_SFP) {
|
||||
hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_1GBE_COMP_CODES,
|
||||
&comp_codes_1g);
|
||||
|
|
@ -659,22 +792,57 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
|
|||
* 0 SFP_DA_CU
|
||||
* 1 SFP_SR
|
||||
* 2 SFP_LR
|
||||
* 3 SFP_DA_CORE0 - 82599-specific
|
||||
* 4 SFP_DA_CORE1 - 82599-specific
|
||||
* 5 SFP_SR/LR_CORE0 - 82599-specific
|
||||
* 6 SFP_SR/LR_CORE1 - 82599-specific
|
||||
*/
|
||||
if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
|
||||
else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_sr;
|
||||
else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_lr;
|
||||
else
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
|
||||
if (hw->mac.type == ixgbe_mac_82598EB) {
|
||||
if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
|
||||
else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_sr;
|
||||
else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_lr;
|
||||
else
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
|
||||
} else if (hw->mac.type == ixgbe_mac_82599EB) {
|
||||
if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
|
||||
if (hw->bus.lan_id == 0)
|
||||
hw->phy.sfp_type =
|
||||
ixgbe_sfp_type_da_cu_core0;
|
||||
else
|
||||
hw->phy.sfp_type =
|
||||
ixgbe_sfp_type_da_cu_core1;
|
||||
else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
|
||||
if (hw->bus.lan_id == 0)
|
||||
hw->phy.sfp_type =
|
||||
ixgbe_sfp_type_srlr_core0;
|
||||
else
|
||||
hw->phy.sfp_type =
|
||||
ixgbe_sfp_type_srlr_core1;
|
||||
else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
|
||||
if (hw->bus.lan_id == 0)
|
||||
hw->phy.sfp_type =
|
||||
ixgbe_sfp_type_srlr_core0;
|
||||
else
|
||||
hw->phy.sfp_type =
|
||||
ixgbe_sfp_type_srlr_core1;
|
||||
else
|
||||
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
|
||||
}
|
||||
|
||||
if (hw->phy.sfp_type != stored_sfp_type)
|
||||
hw->phy.sfp_setup_needed = TRUE;
|
||||
|
||||
/* Determine if the SFP+ PHY is dual speed or not. */
|
||||
if ((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
|
||||
(comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE))
|
||||
if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
|
||||
(comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
|
||||
((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
|
||||
(comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
|
||||
hw->phy.multispeed_fiber = TRUE;
|
||||
/* Determine PHY vendor */
|
||||
if (hw->phy.type == ixgbe_phy_unknown) {
|
||||
if (hw->phy.type != ixgbe_phy_nl) {
|
||||
hw->phy.id = identifier;
|
||||
hw->phy.ops.read_i2c_eeprom(hw,
|
||||
IXGBE_SFF_VENDOR_OUI_BYTE0,
|
||||
|
|
@ -703,6 +871,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
|
|||
case IXGBE_SFF_VENDOR_OUI_AVAGO:
|
||||
hw->phy.type = ixgbe_phy_sfp_avago;
|
||||
break;
|
||||
case IXGBE_SFF_VENDOR_OUI_INTEL:
|
||||
hw->phy.type = ixgbe_phy_sfp_intel;
|
||||
break;
|
||||
default:
|
||||
if (transmission_media &
|
||||
IXGBE_SFF_TWIN_AX_CAPABLE)
|
||||
|
|
@ -712,7 +883,34 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
|
|||
break;
|
||||
}
|
||||
}
|
||||
status = IXGBE_SUCCESS;
|
||||
|
||||
if (comp_codes_10g == 0) {
|
||||
hw->phy.type = ixgbe_phy_sfp_unsupported;
|
||||
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
|
||||
goto out;
|
||||
}
|
||||
if (hw->mac.type == ixgbe_mac_82598EB ||
|
||||
(hw->phy.sfp_type != ixgbe_sfp_type_sr &&
|
||||
hw->phy.sfp_type != ixgbe_sfp_type_lr &&
|
||||
hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 &&
|
||||
hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) {
|
||||
status = IXGBE_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ixgbe_get_device_caps(hw, &enforce_sfp);
|
||||
if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
|
||||
/* Make sure we're a supported PHY type */
|
||||
if (hw->phy.type == ixgbe_phy_sfp_intel) {
|
||||
status = IXGBE_SUCCESS;
|
||||
} else {
|
||||
DEBUGOUT("SFP+ module not supported\n");
|
||||
hw->phy.type = ixgbe_phy_sfp_unsupported;
|
||||
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
status = IXGBE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -748,7 +946,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
|
|||
hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
|
||||
|
||||
if ((!*list_offset) || (*list_offset == 0xFFFF))
|
||||
return IXGBE_ERR_PHY;
|
||||
return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
|
||||
|
||||
/* Shift offset to first ID word */
|
||||
(*list_offset)++;
|
||||
|
|
@ -784,3 +982,549 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
|
|||
return IXGBE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: EEPROM byte offset to read
|
||||
* @eeprom_data: value read
|
||||
*
|
||||
* Performs byte read operation to SFP module's EEPROM over I2C interface.
|
||||
**/
|
||||
s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 *eeprom_data)
|
||||
{
|
||||
DEBUGFUNC("ixgbe_read_i2c_eeprom_generic");
|
||||
|
||||
return hw->phy.ops.read_i2c_byte(hw, byte_offset,
|
||||
IXGBE_I2C_EEPROM_DEV_ADDR,
|
||||
eeprom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: EEPROM byte offset to write
|
||||
* @eeprom_data: value to write
|
||||
*
|
||||
* Performs byte write operation to SFP module's EEPROM over I2C interface.
|
||||
**/
|
||||
s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 eeprom_data)
|
||||
{
|
||||
DEBUGFUNC("ixgbe_write_i2c_eeprom_generic");
|
||||
|
||||
return hw->phy.ops.write_i2c_byte(hw, byte_offset,
|
||||
IXGBE_I2C_EEPROM_DEV_ADDR,
|
||||
eeprom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: byte offset to read
|
||||
* @data: value read
|
||||
*
|
||||
* Performs byte read operation to SFP module's EEPROM over I2C interface at
|
||||
* a specified deivce address.
|
||||
**/
|
||||
s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 dev_addr, u8 *data)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
u32 max_retry = 1;
|
||||
u32 retry = 0;
|
||||
u16 swfw_mask = 0;
|
||||
bool nack = 1;
|
||||
|
||||
DEBUGFUNC("ixgbe_read_i2c_byte_generic");
|
||||
|
||||
if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
|
||||
swfw_mask = IXGBE_GSSR_PHY1_SM;
|
||||
else
|
||||
swfw_mask = IXGBE_GSSR_PHY0_SM;
|
||||
|
||||
if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) {
|
||||
status = IXGBE_ERR_SWFW_SYNC;
|
||||
goto read_byte_out;
|
||||
}
|
||||
|
||||
do {
|
||||
ixgbe_i2c_start(hw);
|
||||
|
||||
/* Device Address and write indication */
|
||||
status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_get_i2c_ack(hw);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_get_i2c_ack(hw);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
ixgbe_i2c_start(hw);
|
||||
|
||||
/* Device Address and read indication */
|
||||
status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_get_i2c_ack(hw);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_clock_in_i2c_byte(hw, data);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_clock_out_i2c_bit(hw, nack);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
ixgbe_i2c_stop(hw);
|
||||
break;
|
||||
|
||||
fail:
|
||||
ixgbe_i2c_bus_clear(hw);
|
||||
retry++;
|
||||
if (retry < max_retry)
|
||||
DEBUGOUT("I2C byte read error - Retrying.\n");
|
||||
else
|
||||
DEBUGOUT("I2C byte read error.\n");
|
||||
|
||||
} while (retry < max_retry);
|
||||
|
||||
ixgbe_release_swfw_sync(hw, swfw_mask);
|
||||
|
||||
read_byte_out:
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: byte offset to write
|
||||
* @data: value to write
|
||||
*
|
||||
* Performs byte write operation to SFP module's EEPROM over I2C interface at
|
||||
* a specified device address.
|
||||
**/
|
||||
s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 dev_addr, u8 data)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
u32 max_retry = 1;
|
||||
u32 retry = 0;
|
||||
u16 swfw_mask = 0;
|
||||
|
||||
DEBUGFUNC("ixgbe_write_i2c_byte_generic");
|
||||
|
||||
if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
|
||||
swfw_mask = IXGBE_GSSR_PHY1_SM;
|
||||
else
|
||||
swfw_mask = IXGBE_GSSR_PHY0_SM;
|
||||
|
||||
if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) {
|
||||
status = IXGBE_ERR_SWFW_SYNC;
|
||||
goto write_byte_out;
|
||||
}
|
||||
|
||||
do {
|
||||
ixgbe_i2c_start(hw);
|
||||
|
||||
status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_get_i2c_ack(hw);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_get_i2c_ack(hw);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_clock_out_i2c_byte(hw, data);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
status = ixgbe_get_i2c_ack(hw);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
ixgbe_i2c_stop(hw);
|
||||
break;
|
||||
|
||||
fail:
|
||||
ixgbe_i2c_bus_clear(hw);
|
||||
retry++;
|
||||
if (retry < max_retry)
|
||||
DEBUGOUT("I2C byte write error - Retrying.\n");
|
||||
else
|
||||
DEBUGOUT("I2C byte write error.\n");
|
||||
} while (retry < max_retry);
|
||||
|
||||
ixgbe_release_swfw_sync(hw, swfw_mask);
|
||||
|
||||
write_byte_out:
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_i2c_start - Sets I2C start condition
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Sets I2C start condition (High -> Low on SDA while SCL is High)
|
||||
**/
|
||||
static void ixgbe_i2c_start(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
|
||||
DEBUGFUNC("ixgbe_i2c_start");
|
||||
|
||||
/* Start condition must begin with data and clock high */
|
||||
ixgbe_set_i2c_data(hw, &i2cctl, 1);
|
||||
ixgbe_raise_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Setup time for start condition (4.7us) */
|
||||
usec_delay(IXGBE_I2C_T_SU_STA);
|
||||
|
||||
ixgbe_set_i2c_data(hw, &i2cctl, 0);
|
||||
|
||||
/* Hold time for start condition (4us) */
|
||||
usec_delay(IXGBE_I2C_T_HD_STA);
|
||||
|
||||
ixgbe_lower_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Minimum low period of clock is 4.7 us */
|
||||
usec_delay(IXGBE_I2C_T_LOW);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_i2c_stop - Sets I2C stop condition
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Sets I2C stop condition (Low -> High on SDA while SCL is High)
|
||||
**/
|
||||
static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
|
||||
DEBUGFUNC("ixgbe_i2c_stop");
|
||||
|
||||
/* Stop condition must begin with data low and clock high */
|
||||
ixgbe_set_i2c_data(hw, &i2cctl, 0);
|
||||
ixgbe_raise_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Setup time for stop condition (4us) */
|
||||
usec_delay(IXGBE_I2C_T_SU_STO);
|
||||
|
||||
ixgbe_set_i2c_data(hw, &i2cctl, 1);
|
||||
|
||||
/* bus free time between stop and start (4.7us)*/
|
||||
usec_delay(IXGBE_I2C_T_BUF);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
|
||||
* @hw: pointer to hardware structure
|
||||
* @data: data byte to clock in
|
||||
*
|
||||
* Clocks in one byte data via I2C data/clock
|
||||
**/
|
||||
static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
s32 i;
|
||||
bool bit = 0;
|
||||
|
||||
DEBUGFUNC("ixgbe_clock_in_i2c_byte");
|
||||
|
||||
for (i = 7; i >= 0; i--) {
|
||||
status = ixgbe_clock_in_i2c_bit(hw, &bit);
|
||||
*data |= bit<<i;
|
||||
|
||||
if (status != IXGBE_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
|
||||
* @hw: pointer to hardware structure
|
||||
* @data: data byte clocked out
|
||||
*
|
||||
* Clocks out one byte data via I2C data/clock
|
||||
**/
|
||||
static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
s32 i;
|
||||
u32 i2cctl;
|
||||
bool bit = 0;
|
||||
|
||||
DEBUGFUNC("ixgbe_clock_out_i2c_byte");
|
||||
|
||||
for (i = 7; i >= 0; i--) {
|
||||
bit = (data >> i) & 0x1;
|
||||
status = ixgbe_clock_out_i2c_bit(hw, bit);
|
||||
|
||||
if (status != IXGBE_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Release SDA line (set high) */
|
||||
i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
i2cctl |= IXGBE_I2C_DATA_OUT;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_i2c_ack - Polls for I2C ACK
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Clocks in/out one bit via I2C data/clock
|
||||
**/
|
||||
static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
|
||||
{
|
||||
s32 status;
|
||||
u32 i = 0;
|
||||
u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
u32 timeout = 10;
|
||||
bool ack = 1;
|
||||
|
||||
DEBUGFUNC("ixgbe_get_i2c_ack");
|
||||
|
||||
status = ixgbe_raise_i2c_clk(hw, &i2cctl);
|
||||
|
||||
if (status != IXGBE_SUCCESS)
|
||||
goto out;
|
||||
|
||||
/* Minimum high period of clock is 4us */
|
||||
usec_delay(IXGBE_I2C_T_HIGH);
|
||||
|
||||
/* Poll for ACK. Note that ACK in I2C spec is
|
||||
* transition from 1 to 0 */
|
||||
for (i = 0; i < timeout; i++) {
|
||||
i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
ack = ixgbe_get_i2c_data(&i2cctl);
|
||||
|
||||
usec_delay(1);
|
||||
if (ack == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ack == 1) {
|
||||
DEBUGOUT("I2C ack was not received.\n");
|
||||
status = IXGBE_ERR_I2C;
|
||||
}
|
||||
|
||||
ixgbe_lower_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Minimum low period of clock is 4.7 us */
|
||||
usec_delay(IXGBE_I2C_T_LOW);
|
||||
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
|
||||
* @hw: pointer to hardware structure
|
||||
* @data: read data value
|
||||
*
|
||||
* Clocks in one bit via I2C data/clock
|
||||
**/
|
||||
static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
|
||||
{
|
||||
s32 status;
|
||||
u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
|
||||
status = ixgbe_raise_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Minimum high period of clock is 4us */
|
||||
usec_delay(IXGBE_I2C_T_HIGH);
|
||||
|
||||
i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
*data = ixgbe_get_i2c_data(&i2cctl);
|
||||
|
||||
ixgbe_lower_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Minimum low period of clock is 4.7 us */
|
||||
usec_delay(IXGBE_I2C_T_LOW);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
|
||||
* @hw: pointer to hardware structure
|
||||
* @data: data value to write
|
||||
*
|
||||
* Clocks out one bit via I2C data/clock
|
||||
**/
|
||||
static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
|
||||
{
|
||||
s32 status;
|
||||
u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
|
||||
status = ixgbe_set_i2c_data(hw, &i2cctl, data);
|
||||
if (status == IXGBE_SUCCESS) {
|
||||
status = ixgbe_raise_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Minimum high period of clock is 4us */
|
||||
usec_delay(IXGBE_I2C_T_HIGH);
|
||||
|
||||
ixgbe_lower_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Minimum low period of clock is 4.7 us.
|
||||
* This also takes care of the data hold time.
|
||||
*/
|
||||
usec_delay(IXGBE_I2C_T_LOW);
|
||||
} else {
|
||||
status = IXGBE_ERR_I2C;
|
||||
DEBUGOUT1("I2C data was not set to %X\n", data);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* ixgbe_raise_i2c_clk - Raises the I2C SCL clock
|
||||
* @hw: pointer to hardware structure
|
||||
* @i2cctl: Current value of I2CCTL register
|
||||
*
|
||||
* Raises the I2C clock line '0'->'1'
|
||||
**/
|
||||
static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
|
||||
*i2cctl |= IXGBE_I2C_CLK_OUT;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
|
||||
|
||||
/* SCL rise time (1000ns) */
|
||||
usec_delay(IXGBE_I2C_T_RISE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
|
||||
* @hw: pointer to hardware structure
|
||||
* @i2cctl: Current value of I2CCTL register
|
||||
*
|
||||
* Lowers the I2C clock line '1'->'0'
|
||||
**/
|
||||
static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
|
||||
{
|
||||
|
||||
*i2cctl &= ~IXGBE_I2C_CLK_OUT;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
|
||||
|
||||
/* SCL fall time (300ns) */
|
||||
usec_delay(IXGBE_I2C_T_FALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_set_i2c_data - Sets the I2C data bit
|
||||
* @hw: pointer to hardware structure
|
||||
* @i2cctl: Current value of I2CCTL register
|
||||
* @data: I2C data value (0 or 1) to set
|
||||
*
|
||||
* Sets the I2C data bit
|
||||
**/
|
||||
static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
|
||||
if (data)
|
||||
*i2cctl |= IXGBE_I2C_DATA_OUT;
|
||||
else
|
||||
*i2cctl &= ~IXGBE_I2C_DATA_OUT;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
|
||||
|
||||
/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
|
||||
usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
|
||||
|
||||
/* Verify data was set correctly */
|
||||
*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
if (data != ixgbe_get_i2c_data(i2cctl)) {
|
||||
status = IXGBE_ERR_I2C;
|
||||
DEBUGOUT1("Error - I2C data was not set to %X.\n", data);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_get_i2c_data - Reads the I2C SDA data bit
|
||||
* @hw: pointer to hardware structure
|
||||
* @i2cctl: Current value of I2CCTL register
|
||||
*
|
||||
* Returns the I2C data bit value
|
||||
**/
|
||||
static bool ixgbe_get_i2c_data(u32 *i2cctl)
|
||||
{
|
||||
bool data;
|
||||
|
||||
if (*i2cctl & IXGBE_I2C_DATA_IN)
|
||||
data = 1;
|
||||
else
|
||||
data = 0;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_i2c_bus_clear - Clears the I2C bus
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Clears the I2C bus by sending nine clock pulses.
|
||||
* Used when data line is stuck low.
|
||||
**/
|
||||
void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
|
||||
{
|
||||
u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
|
||||
u32 i;
|
||||
|
||||
DEBUGFUNC("ixgbe_i2c_bus_clear");
|
||||
|
||||
ixgbe_i2c_start(hw);
|
||||
|
||||
ixgbe_set_i2c_data(hw, &i2cctl, 1);
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
ixgbe_raise_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Min high period of clock is 4us */
|
||||
usec_delay(IXGBE_I2C_T_HIGH);
|
||||
|
||||
ixgbe_lower_i2c_clk(hw, &i2cctl);
|
||||
|
||||
/* Min low period of clock is 4.7us*/
|
||||
usec_delay(IXGBE_I2C_T_LOW);
|
||||
}
|
||||
|
||||
ixgbe_i2c_start(hw);
|
||||
|
||||
/* Put the i2c bus back to default state */
|
||||
ixgbe_i2c_stop(hw);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
/* Bitmasks */
|
||||
#define IXGBE_SFF_TWIN_AX_CAPABLE 0x80
|
||||
#define IXGBE_SFF_1GBASESX_CAPABLE 0x1
|
||||
#define IXGBE_SFF_1GBASELX_CAPABLE 0x2
|
||||
#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
|
||||
#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
|
||||
#define IXGBE_I2C_EEPROM_READ_MASK 0x100
|
||||
|
|
@ -61,14 +62,15 @@
|
|||
#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
|
||||
|
||||
/* Bit-shift macros */
|
||||
#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 12
|
||||
#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 8
|
||||
#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 4
|
||||
#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24
|
||||
#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16
|
||||
#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 8
|
||||
|
||||
/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
|
||||
#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600
|
||||
#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500
|
||||
#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00
|
||||
#define IXGBE_SFF_VENDOR_OUI_INTEL 0x001B2100
|
||||
|
||||
/* I2C SDA and SCL timing parameters for standard mode */
|
||||
#define IXGBE_I2C_T_HD_STA 4
|
||||
|
|
@ -98,6 +100,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
|
|||
ixgbe_link_speed speed,
|
||||
bool autoneg,
|
||||
bool autoneg_wait_to_complete);
|
||||
s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
|
||||
ixgbe_link_speed *speed,
|
||||
bool *autoneg);
|
||||
|
||||
/* PHY specific */
|
||||
s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
|
||||
|
|
@ -105,10 +110,20 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
|
|||
bool *link_up);
|
||||
s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
|
||||
u16 *firmware_version);
|
||||
s32 ixgbe_get_phy_firmware_version_aq(struct ixgbe_hw *hw,
|
||||
u16 *firmware_version);
|
||||
|
||||
s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
|
||||
u16 *list_offset,
|
||||
u16 *data_offset);
|
||||
s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 dev_addr, u8 *data);
|
||||
s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 dev_addr, u8 data);
|
||||
s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 *eeprom_data);
|
||||
s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
|
||||
u8 eeprom_data);
|
||||
#endif /* _IXGBE_PHY_H_ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue