ixgbe: add 82599 bypass support
Signed-off-by: Intel
This commit is contained in:
parent
c3d0564cf0
commit
a1ebecb0a9
@ -386,6 +386,10 @@ RTE_PCI_DEV_ID_DECL_IGB(PCI_VENDOR_ID_INTEL, E1000_DEV_ID_DH89XXCC_SFP)
|
||||
#define IXGBE_DEV_ID_X540T 0x1528
|
||||
#define IXGBE_DEV_ID_X540T1 0x1560
|
||||
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
#define IXGBE_DEV_ID_82599_BYPASS 0x155D
|
||||
#endif
|
||||
|
||||
RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_82598)
|
||||
RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_82598_BX)
|
||||
RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT)
|
||||
@ -424,6 +428,10 @@ RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_82599_T3_LOM)
|
||||
RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_X540T)
|
||||
RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_X540T1)
|
||||
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
RTE_PCI_DEV_ID_DECL_IXGBE(PCI_VENDOR_ID_INTEL, IXGBE_DEV_ID_82599_BYPASS)
|
||||
#endif
|
||||
|
||||
/****************** Virtual IGB devices from e1000_hw.h ******************/
|
||||
|
||||
#define E1000_DEV_ID_82576_VF 0x10CA
|
||||
|
@ -86,6 +86,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_ethdev.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_fdir.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_pf.c
|
||||
|
||||
ifeq ($(CONFIG_RTE_NIC_BYPASS),y)
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_bypass.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c
|
||||
endif
|
||||
|
||||
|
||||
# this lib depends upon:
|
||||
DEPDIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += lib/librte_eal lib/librte_ether
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <rte_byteorder.h>
|
||||
|
||||
#include "../ixgbe_logs.h"
|
||||
#include "../ixgbe_bypass_defines.h"
|
||||
|
||||
#define ASSERT(x) if(!(x)) rte_panic("IXGBE: x")
|
||||
|
||||
|
309
lib/librte_pmd_ixgbe/ixgbe_82599_bypass.c
Normal file
309
lib/librte_pmd_ixgbe/ixgbe_82599_bypass.c
Normal file
@ -0,0 +1,309 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ixgbe/ixgbe_type.h"
|
||||
#include "ixgbe/ixgbe_82599.h"
|
||||
#include "ixgbe/ixgbe_api.h"
|
||||
#include "ixgbe/ixgbe_common.h"
|
||||
#include "ixgbe/ixgbe_phy.h"
|
||||
#include "ixgbe_bypass_defines.h"
|
||||
#include "ixgbe_bypass.h"
|
||||
|
||||
/**
|
||||
* ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
|
||||
* @hw: pointer to hardware structure
|
||||
* @speed: link speed to set
|
||||
*
|
||||
* We set the module speed differently for fixed fiber. For other
|
||||
* multi-speed devices we don't have an error value so here if we
|
||||
* detect an error we just log it and exit.
|
||||
*/
|
||||
static void
|
||||
ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed)
|
||||
{
|
||||
s32 status;
|
||||
u8 rs, eeprom_data;
|
||||
|
||||
switch (speed) {
|
||||
case IXGBE_LINK_SPEED_10GB_FULL:
|
||||
/* one bit mask same as setting on */
|
||||
rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
|
||||
break;
|
||||
case IXGBE_LINK_SPEED_1GB_FULL:
|
||||
rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
|
||||
break;
|
||||
default:
|
||||
DEBUGOUT("Invalid fixed module speed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set RS0 */
|
||||
status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
|
||||
IXGBE_I2C_EEPROM_DEV_ADDR2,
|
||||
&eeprom_data);
|
||||
if (status) {
|
||||
DEBUGOUT("Failed to read Rx Rate Select RS0\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
|
||||
|
||||
status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
|
||||
IXGBE_I2C_EEPROM_DEV_ADDR2,
|
||||
eeprom_data);
|
||||
if (status) {
|
||||
DEBUGOUT("Failed to write Rx Rate Select RS0\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set RS1 */
|
||||
status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
|
||||
IXGBE_I2C_EEPROM_DEV_ADDR2,
|
||||
&eeprom_data);
|
||||
if (status) {
|
||||
DEBUGOUT("Failed to read Rx Rate Select RS1\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
|
||||
|
||||
status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
|
||||
IXGBE_I2C_EEPROM_DEV_ADDR2,
|
||||
eeprom_data);
|
||||
if (status) {
|
||||
DEBUGOUT("Failed to write Rx Rate Select RS1\n");
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_setup_mac_link_multispeed_fixed_fiber - Set MAC link speed
|
||||
* @hw: pointer to hardware structure
|
||||
* @speed: new link speed
|
||||
* @autoneg: true if autonegotiation enabled
|
||||
* @autoneg_wait_to_complete: true when waiting for completion is needed
|
||||
*
|
||||
* Set the link speed in the AUTOC register and restarts link.
|
||||
**/
|
||||
static s32
|
||||
ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw *hw,
|
||||
ixgbe_link_speed speed, bool autoneg,
|
||||
bool autoneg_wait_to_complete)
|
||||
{
|
||||
s32 status = IXGBE_SUCCESS;
|
||||
ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
|
||||
ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
|
||||
u32 speedcnt = 0;
|
||||
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
|
||||
u32 i = 0;
|
||||
bool link_up = false;
|
||||
bool negotiation;
|
||||
|
||||
DEBUGFUNC("");
|
||||
|
||||
/* Mask off requested but non-supported speeds */
|
||||
status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
return status;
|
||||
|
||||
speed &= link_speed;
|
||||
|
||||
/*
|
||||
* Try each speed one by one, highest priority first. We do this in
|
||||
* software because 10gb fiber doesn't support speed autonegotiation.
|
||||
*/
|
||||
if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
|
||||
speedcnt++;
|
||||
highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
|
||||
|
||||
/* If we already have link at this speed, just jump out */
|
||||
status = ixgbe_check_link(hw, &link_speed, &link_up, false);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
return status;
|
||||
|
||||
if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
|
||||
goto out;
|
||||
/* Set the module link speed */
|
||||
ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_10GB_FULL);
|
||||
|
||||
/* Set the module link speed */
|
||||
esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
/* Allow module to change analog characteristics (1G->10G) */
|
||||
msec_delay(40);
|
||||
|
||||
status = ixgbe_setup_mac_link_82599(hw,
|
||||
IXGBE_LINK_SPEED_10GB_FULL,
|
||||
autoneg,
|
||||
autoneg_wait_to_complete);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Flap the tx laser if it has not already been done */
|
||||
ixgbe_flap_tx_laser(hw);
|
||||
|
||||
/*
|
||||
* Wait for the controller to acquire link. Per IEEE 802.3ap,
|
||||
* Section 73.10.2, we may have to wait up to 500ms if KR is
|
||||
* attempted. 82599 uses the same timing for 10g SFI.
|
||||
*/
|
||||
for (i = 0; i < 5; i++) {
|
||||
/* Wait for the link partner to also set speed */
|
||||
msec_delay(100);
|
||||
|
||||
/* If we have link, just jump out */
|
||||
status = ixgbe_check_link(hw, &link_speed,
|
||||
&link_up, false);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
return status;
|
||||
|
||||
if (link_up)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
|
||||
speedcnt++;
|
||||
if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
|
||||
highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
|
||||
|
||||
/* If we already have link at this speed, just jump out */
|
||||
status = ixgbe_check_link(hw, &link_speed, &link_up, false);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
return status;
|
||||
|
||||
if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
|
||||
goto out;
|
||||
|
||||
/* Set the module link speed */
|
||||
ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_1GB_FULL);
|
||||
|
||||
/* Allow module to change analog characteristics (10G->1G) */
|
||||
msec_delay(40);
|
||||
|
||||
status = ixgbe_setup_mac_link_82599(hw,
|
||||
IXGBE_LINK_SPEED_1GB_FULL,
|
||||
autoneg,
|
||||
autoneg_wait_to_complete);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Flap the tx laser if it has not already been done */
|
||||
ixgbe_flap_tx_laser(hw);
|
||||
|
||||
/* Wait for the link partner to also set speed */
|
||||
msec_delay(100);
|
||||
|
||||
/* If we have link, just jump out */
|
||||
status = ixgbe_check_link(hw, &link_speed, &link_up, false);
|
||||
if (status != IXGBE_SUCCESS)
|
||||
return status;
|
||||
|
||||
if (link_up)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* We didn't get link. Configure back to the highest speed we tried,
|
||||
* (if there was more than one). We call ourselves back with just the
|
||||
* single highest speed that the user requested.
|
||||
*/
|
||||
if (speedcnt > 1)
|
||||
status = ixgbe_setup_mac_link_multispeed_fixed_fiber(hw,
|
||||
highest_link_speed, autoneg, autoneg_wait_to_complete);
|
||||
|
||||
out:
|
||||
/* Set autoneg_advertised value based on input link speed */
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
|
||||
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
|
||||
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
|
||||
|
||||
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
|
||||
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper around ND functions to support BYPASS nic.
|
||||
*/
|
||||
s32
|
||||
ixgbe_bypass_init_shared_code(struct ixgbe_hw *hw)
|
||||
{
|
||||
if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
|
||||
hw->mac.type = ixgbe_mac_82599EB;
|
||||
}
|
||||
|
||||
return (ixgbe_init_shared_code(hw));
|
||||
}
|
||||
|
||||
static enum ixgbe_media_type
|
||||
ixgbe_bypass_get_media_type(struct ixgbe_hw *hw)
|
||||
{
|
||||
enum ixgbe_media_type media_type;
|
||||
|
||||
DEBUGFUNC("");
|
||||
|
||||
if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
|
||||
media_type = ixgbe_media_type_fiber;
|
||||
} else {
|
||||
media_type = ixgbe_get_media_type_82599(hw);
|
||||
}
|
||||
return (media_type);
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_init_hw(struct ixgbe_hw *hw)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = ixgbe_init_hw(hw)) == 0 &&
|
||||
hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
|
||||
|
||||
hw->mac.ops.setup_link =
|
||||
&ixgbe_setup_mac_link_multispeed_fixed_fiber;
|
||||
|
||||
hw->mac.ops.get_media_type = &ixgbe_bypass_get_media_type;
|
||||
|
||||
hw->mac.ops.disable_tx_laser = NULL;
|
||||
hw->mac.ops.enable_tx_laser = NULL;
|
||||
hw->mac.ops.flap_tx_laser = NULL;
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
414
lib/librte_pmd_ixgbe/ixgbe_bypass.c
Normal file
414
lib/librte_pmd_ixgbe/ixgbe_bypass.c
Normal file
@ -0,0 +1,414 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <rte_atomic.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include "ixgbe_ethdev.h"
|
||||
#include "ixgbe_bypass_api.h"
|
||||
|
||||
#define BYPASS_STATUS_OFF_MASK 3
|
||||
|
||||
/* Macros to check for invlaid function pointers. */
|
||||
#define FUNC_PTR_OR_ERR_RET(func, retval) do { \
|
||||
if ((func) == NULL) { \
|
||||
DEBUGOUT("%s:%d function not supported\n", \
|
||||
__func__, __LINE__); \
|
||||
return (retval); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define FUNC_PTR_OR_RET(func) do { \
|
||||
if ((func) == NULL) { \
|
||||
DEBUGOUT("%s:%d function not supported\n", \
|
||||
__func__, __LINE__); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
/**
|
||||
* ixgbe_bypass_set_time - Set bypass FW time epoc.
|
||||
*
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* This function with sync the FW date stamp with that of the
|
||||
* system clock.
|
||||
**/
|
||||
static void
|
||||
ixgbe_bypass_set_time(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
u32 mask, value;
|
||||
u32 sec;
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
||||
sec = 0;
|
||||
|
||||
/*
|
||||
* Send the FW our current time and turn on time_valid and
|
||||
* timer_reset bits.
|
||||
*/
|
||||
mask = BYPASS_CTL1_TIME_M |
|
||||
BYPASS_CTL1_VALID_M |
|
||||
BYPASS_CTL1_OFFTRST_M;
|
||||
value = (sec & BYPASS_CTL1_TIME_M) |
|
||||
BYPASS_CTL1_VALID |
|
||||
BYPASS_CTL1_OFFTRST;
|
||||
|
||||
FUNC_PTR_OR_RET(adapter->bps.ops.bypass_set);
|
||||
|
||||
/* Store FW reset time (in seconds from epoch). */
|
||||
adapter->bps.reset_tm = time(NULL);
|
||||
|
||||
/* reset FW timer. */
|
||||
adapter->bps.ops.bypass_set(hw, BYPASS_PAGE_CTL1, mask, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_bypass_init - Make some enviroment changes for bypass
|
||||
*
|
||||
* @adapter: pointer to ixgbe_adapter sturcture for access to state bits
|
||||
*
|
||||
* This function collects all the modifications needed by the bypass
|
||||
* driver.
|
||||
**/
|
||||
void
|
||||
ixgbe_bypass_init(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct ixgbe_adapter *adapter;
|
||||
struct ixgbe_hw *hw;
|
||||
|
||||
adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
hw = &adapter->hw;
|
||||
|
||||
/* Only allow BYPASS ops on the first port */
|
||||
if (hw->device_id != IXGBE_DEV_ID_82599_BYPASS ||
|
||||
hw->bus.func != 0) {
|
||||
DEBUGOUT("bypass function is not supported on that device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* set bypass ops. */
|
||||
adapter->bps.ops.bypass_rw = &ixgbe_bypass_rw_generic;
|
||||
adapter->bps.ops.bypass_valid_rd = &ixgbe_bypass_valid_rd_generic;
|
||||
adapter->bps.ops.bypass_set = &ixgbe_bypass_set_generic;
|
||||
adapter->bps.ops.bypass_rd_eep = &ixgbe_bypass_rd_eep_generic;
|
||||
|
||||
/* set the time for logging. */
|
||||
ixgbe_bypass_set_time(adapter);
|
||||
|
||||
/* Don't have the SDP to the laser */
|
||||
hw->mac.ops.disable_tx_laser = NULL;
|
||||
hw->mac.ops.enable_tx_laser = NULL;
|
||||
hw->mac.ops.flap_tx_laser = NULL;
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_state_show(struct rte_eth_dev *dev, u32 *state)
|
||||
{
|
||||
struct ixgbe_hw *hw;
|
||||
s32 ret_val;
|
||||
u32 cmd;
|
||||
u32 by_ctl = 0;
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
|
||||
hw = &adapter->hw;
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_rw, -ENOTSUP);
|
||||
|
||||
cmd = BYPASS_PAGE_CTL0;
|
||||
ret_val = adapter->bps.ops.bypass_rw(hw, cmd, &by_ctl);
|
||||
|
||||
/* Assume bypass_rw didn't error out, if it did state will
|
||||
* be ignored anyway.
|
||||
*/
|
||||
*state = (by_ctl >> BYPASS_STATUS_OFF_SHIFT) & BYPASS_STATUS_OFF_MASK;
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
|
||||
s32
|
||||
ixgbe_bypass_state_store(struct rte_eth_dev *dev, u32 *new_state)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
struct ixgbe_hw *hw;
|
||||
s32 ret_val;
|
||||
|
||||
hw = &adapter->hw;
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_set, -ENOTSUP);
|
||||
|
||||
/* Set the new state */
|
||||
ret_val = adapter->bps.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
|
||||
BYPASS_MODE_OFF_M, *new_state);
|
||||
if (ret_val)
|
||||
goto exit;
|
||||
|
||||
/* Set AUTO back on so FW can recieve events */
|
||||
ret_val = adapter->bps.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
|
||||
BYPASS_MODE_OFF_M, BYPASS_AUTO);
|
||||
|
||||
exit:
|
||||
return ret_val;
|
||||
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_event_show(struct rte_eth_dev *dev, u32 event,
|
||||
u32 *state)
|
||||
{
|
||||
struct ixgbe_hw *hw;
|
||||
s32 ret_val;
|
||||
u32 shift;
|
||||
u32 cmd;
|
||||
u32 by_ctl = 0;
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
|
||||
hw = &adapter->hw;
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_rw, -ENOTSUP);
|
||||
|
||||
cmd = BYPASS_PAGE_CTL0;
|
||||
ret_val = adapter->bps.ops.bypass_rw(hw, cmd, &by_ctl);
|
||||
|
||||
/* Assume bypass_rw didn't error out, if it did event will
|
||||
* be ignored anyway.
|
||||
*/
|
||||
switch (event) {
|
||||
case BYPASS_EVENT_WDT_TO:
|
||||
shift = BYPASS_WDTIMEOUT_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_MAIN_ON:
|
||||
shift = BYPASS_MAIN_ON_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_MAIN_OFF:
|
||||
shift = BYPASS_MAIN_OFF_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_AUX_ON:
|
||||
shift = BYPASS_AUX_ON_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_AUX_OFF:
|
||||
shift = BYPASS_AUX_OFF_SHIFT;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*state = (by_ctl >> shift) & 0x3;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_event_store(struct rte_eth_dev *dev, u32 event,
|
||||
u32 state)
|
||||
{
|
||||
struct ixgbe_hw *hw;
|
||||
u32 status;
|
||||
u32 off;
|
||||
s32 ret_val;
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
|
||||
hw = &adapter->hw;
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_set, -ENOTSUP);
|
||||
|
||||
switch (event) {
|
||||
case BYPASS_EVENT_WDT_TO:
|
||||
off = BYPASS_WDTIMEOUT_M;
|
||||
status = state << BYPASS_WDTIMEOUT_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_MAIN_ON:
|
||||
off = BYPASS_MAIN_ON_M;
|
||||
status = state << BYPASS_MAIN_ON_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_MAIN_OFF:
|
||||
off = BYPASS_MAIN_OFF_M;
|
||||
status = state << BYPASS_MAIN_OFF_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_AUX_ON:
|
||||
off = BYPASS_AUX_ON_M;
|
||||
status = state << BYPASS_AUX_ON_SHIFT;
|
||||
break;
|
||||
case BYPASS_EVENT_AUX_OFF:
|
||||
off = BYPASS_AUX_OFF_M;
|
||||
status = state << BYPASS_AUX_OFF_SHIFT;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ret_val = adapter->bps.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
|
||||
off, status);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_wd_timeout_store(struct rte_eth_dev *dev, u32 timeout)
|
||||
{
|
||||
struct ixgbe_hw *hw;
|
||||
u32 status;
|
||||
u32 mask;
|
||||
s32 ret_val;
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
|
||||
hw = &adapter->hw;
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_set, -ENOTSUP);
|
||||
|
||||
/* disable the timer with timeout of zero */
|
||||
if (timeout == RTE_BYPASS_TMT_OFF) {
|
||||
status = 0x0; /* WDG enable off */
|
||||
mask = BYPASS_WDT_ENABLE_M;
|
||||
} else {
|
||||
/* set time out value */
|
||||
mask = BYPASS_WDT_VALUE_M;
|
||||
|
||||
/* enable the timer */
|
||||
status = timeout << BYPASS_WDT_TIME_SHIFT;
|
||||
status |= 0x1 << BYPASS_WDT_ENABLE_SHIFT;
|
||||
mask |= BYPASS_WDT_ENABLE_M;
|
||||
}
|
||||
|
||||
ret_val = adapter->bps.ops.bypass_set(hw, BYPASS_PAGE_CTL0,
|
||||
mask, status);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_ver_show(struct rte_eth_dev *dev, u32 *ver)
|
||||
{
|
||||
struct ixgbe_hw *hw;
|
||||
u32 cmd;
|
||||
u32 status;
|
||||
s32 ret_val;
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
|
||||
hw = &adapter->hw;
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_rw, -ENOTSUP);
|
||||
|
||||
cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
|
||||
cmd |= (BYPASS_EEPROM_VER_ADD << BYPASS_CTL2_OFFSET_SHIFT) &
|
||||
BYPASS_CTL2_OFFSET_M;
|
||||
ret_val = adapter->bps.ops.bypass_rw(hw, cmd, &status);
|
||||
if (ret_val)
|
||||
goto exit;
|
||||
|
||||
/* wait for the write to stick */
|
||||
msleep(100);
|
||||
|
||||
/* Now read the results */
|
||||
cmd &= ~BYPASS_WE;
|
||||
ret_val = adapter->bps.ops.bypass_rw(hw, cmd, &status);
|
||||
if (ret_val)
|
||||
goto exit;
|
||||
|
||||
*ver = status & BYPASS_CTL2_DATA_M; /* only one byte of date */
|
||||
|
||||
exit:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_wd_timeout_show(struct rte_eth_dev *dev, u32 *wd_timeout)
|
||||
{
|
||||
struct ixgbe_hw *hw;
|
||||
u32 by_ctl = 0;
|
||||
u32 cmd;
|
||||
u32 wdg;
|
||||
s32 ret_val;
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
|
||||
hw = &adapter->hw;
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_rw, -ENOTSUP);
|
||||
|
||||
cmd = BYPASS_PAGE_CTL0;
|
||||
ret_val = adapter->bps.ops.bypass_rw(hw, cmd, &by_ctl);
|
||||
|
||||
wdg = by_ctl & BYPASS_WDT_ENABLE_M;
|
||||
if (!wdg)
|
||||
*wd_timeout = RTE_BYPASS_TMT_OFF;
|
||||
else
|
||||
*wd_timeout = (by_ctl >> BYPASS_WDT_TIME_SHIFT) &
|
||||
BYPASS_WDT_MASK;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
s32
|
||||
ixgbe_bypass_wd_reset(struct rte_eth_dev *dev)
|
||||
{
|
||||
u32 cmd;
|
||||
u32 status;
|
||||
u32 sec;
|
||||
u32 count = 0;
|
||||
s32 ret_val;
|
||||
struct ixgbe_hw *hw;
|
||||
struct ixgbe_adapter *adapter = IXGBE_DEV_TO_ADPATER(dev);
|
||||
|
||||
hw = &adapter->hw;
|
||||
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_rw, -ENOTSUP);
|
||||
FUNC_PTR_OR_ERR_RET(adapter->bps.ops.bypass_valid_rd, -ENOTSUP);
|
||||
|
||||
/* Use the lower level bit-bang functions since we don't need
|
||||
* to read the register first to get it's current state as we
|
||||
* are setting every thing in this write.
|
||||
*/
|
||||
/* Set up WD pet */
|
||||
cmd = BYPASS_PAGE_CTL1 | BYPASS_WE | BYPASS_CTL1_WDT_PET;
|
||||
|
||||
/* Resync the FW time while writing to CTL1 anyway */
|
||||
adapter->bps.reset_tm = time(NULL);
|
||||
sec = 0;
|
||||
|
||||
cmd |= (sec & BYPASS_CTL1_TIME_M) | BYPASS_CTL1_VALID;
|
||||
|
||||
/* reset FW timer offset since we are resetting the clock */
|
||||
cmd |= BYPASS_CTL1_OFFTRST;
|
||||
|
||||
ret_val = adapter->bps.ops.bypass_rw(hw, cmd, &status);
|
||||
|
||||
/* Read until it matches what we wrote, or we time out */
|
||||
do {
|
||||
if (count++ > 10) {
|
||||
ret_val = IXGBE_BYPASS_FW_WRITE_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (adapter->bps.ops.bypass_rw(hw, BYPASS_PAGE_CTL1, &status)) {
|
||||
ret_val = IXGBE_ERR_INVALID_ARGUMENT;
|
||||
break;
|
||||
}
|
||||
} while (!adapter->bps.ops.bypass_valid_rd(cmd, status));
|
||||
|
||||
return ret_val;
|
||||
}
|
68
lib/librte_pmd_ixgbe/ixgbe_bypass.h
Normal file
68
lib/librte_pmd_ixgbe/ixgbe_bypass.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _IXGBE_BYPASS_H_
|
||||
#define _IXGBE_BYPASS_H_
|
||||
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
|
||||
struct ixgbe_bypass_mac_ops {
|
||||
s32 (*bypass_rw) (struct ixgbe_hw *hw, u32 cmd, u32 *status);
|
||||
bool (*bypass_valid_rd) (u32 in_reg, u32 out_reg);
|
||||
s32 (*bypass_set) (struct ixgbe_hw *hw, u32 cmd, u32 event, u32 action);
|
||||
s32 (*bypass_rd_eep) (struct ixgbe_hw *hw, u32 addr, u8 *value);
|
||||
};
|
||||
|
||||
struct ixgbe_bypass_info {
|
||||
uint64_t reset_tm;
|
||||
struct ixgbe_bypass_mac_ops ops;
|
||||
};
|
||||
|
||||
struct rte_eth_dev;
|
||||
|
||||
void ixgbe_bypass_init(struct rte_eth_dev *dev);
|
||||
s32 ixgbe_bypass_state_show(struct rte_eth_dev *dev, u32 *state);
|
||||
s32 ixgbe_bypass_state_store(struct rte_eth_dev *dev, u32 *new_state);
|
||||
s32 ixgbe_bypass_event_show(struct rte_eth_dev *dev, u32 event, u32 *state);
|
||||
s32 ixgbe_bypass_event_store(struct rte_eth_dev *dev, u32 event, u32 state);
|
||||
s32 ixgbe_bypass_wd_timeout_store(struct rte_eth_dev *dev, u32 timeout);
|
||||
s32 ixgbe_bypass_ver_show(struct rte_eth_dev *dev, u32 *ver);
|
||||
s32 ixgbe_bypass_wd_timeout_show(struct rte_eth_dev *dev, u32 *wd_timeout);
|
||||
s32 ixgbe_bypass_wd_reset(struct rte_eth_dev *dev);
|
||||
|
||||
s32 ixgbe_bypass_init_shared_code(struct ixgbe_hw *hw);
|
||||
s32 ixgbe_bypass_init_hw(struct ixgbe_hw *hw);
|
||||
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
|
||||
#endif /* _IXGBE_BYPASS_H_ */
|
290
lib/librte_pmd_ixgbe/ixgbe_bypass_api.h
Normal file
290
lib/librte_pmd_ixgbe/ixgbe_bypass_api.h
Normal file
@ -0,0 +1,290 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _IXGBE_BYPASS_API_H_
|
||||
#define _IXGBE_BYPASS_API_H_
|
||||
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
|
||||
#include "ixgbe_bypass_defines.h"
|
||||
/**
|
||||
* ixgbe_bypass_rw_generic - Bit bang data into by_pass FW
|
||||
*
|
||||
* @hw: pointer to hardware structure
|
||||
* @cmd: Command we send to the FW
|
||||
* @status: The reply from the FW
|
||||
*
|
||||
* Bit-bangs the cmd to the by_pass FW status points to what is returned.
|
||||
**/
|
||||
#define IXGBE_BYPASS_BB_WAIT 1
|
||||
static s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status)
|
||||
{
|
||||
int i;
|
||||
u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo;
|
||||
u32 esdp;
|
||||
|
||||
if (!status)
|
||||
return IXGBE_ERR_PARAM;
|
||||
|
||||
*status = 0;
|
||||
|
||||
/* SDP vary by MAC type */
|
||||
switch (hw->mac.type) {
|
||||
case ixgbe_mac_82599EB:
|
||||
sck = IXGBE_ESDP_SDP7;
|
||||
sdi = IXGBE_ESDP_SDP0;
|
||||
sdo = IXGBE_ESDP_SDP6;
|
||||
dir_sck = IXGBE_ESDP_SDP7_DIR;
|
||||
dir_sdi = IXGBE_ESDP_SDP0_DIR;
|
||||
dir_sdo = IXGBE_ESDP_SDP6_DIR;
|
||||
break;
|
||||
case ixgbe_mac_X540:
|
||||
sck = IXGBE_ESDP_SDP2;
|
||||
sdi = IXGBE_ESDP_SDP0;
|
||||
sdo = IXGBE_ESDP_SDP1;
|
||||
dir_sck = IXGBE_ESDP_SDP2_DIR;
|
||||
dir_sdi = IXGBE_ESDP_SDP0_DIR;
|
||||
dir_sdo = IXGBE_ESDP_SDP1_DIR;
|
||||
break;
|
||||
default:
|
||||
return IXGBE_ERR_DEVICE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Set SDP pins direction */
|
||||
esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
|
||||
esdp |= dir_sck; /* SCK as output */
|
||||
esdp |= dir_sdi; /* SDI as output */
|
||||
esdp &= ~dir_sdo; /* SDO as input */
|
||||
esdp |= sck;
|
||||
esdp |= sdi;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
// TODO:
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
|
||||
/* Generate start condition */
|
||||
esdp &= ~sdi;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
|
||||
esdp &= ~sck;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
|
||||
/* Clock out the new control word and clock in the status */
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((cmd >> (31 - i)) & 0x01) {
|
||||
esdp |= sdi;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
} else {
|
||||
esdp &= ~sdi;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
}
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
|
||||
esdp |= sck;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
|
||||
esdp &= ~sck;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
|
||||
esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
|
||||
if (esdp & sdo)
|
||||
*status = (*status << 1) | 0x01;
|
||||
else
|
||||
*status = (*status << 1) | 0x00;
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
}
|
||||
|
||||
/* stop condition */
|
||||
esdp |= sck;
|
||||
esdp &= ~sdi;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
msleep(IXGBE_BYPASS_BB_WAIT);
|
||||
|
||||
esdp |= sdi;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
/* set the page bits to match the cmd that the status it belongs to */
|
||||
*status = (*status & 0x3fffffff) | (cmd & 0xc0000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang.
|
||||
*
|
||||
* If we send a write we can't be sure it took until we can read back
|
||||
* that same register. It can be a problem as some of the feilds may
|
||||
* for valid reasons change inbetween the time wrote the register and
|
||||
* we read it again to verify. So this function check everything we
|
||||
* can check and then assumes it worked.
|
||||
*
|
||||
* @u32 in_reg - The register cmd for the bit-bang read.
|
||||
* @u32 out_reg - The register returned from a bit-bang read.
|
||||
**/
|
||||
static bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg)
|
||||
{
|
||||
u32 mask;
|
||||
|
||||
/* Page must match for all control pages */
|
||||
if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M))
|
||||
return false;
|
||||
|
||||
switch (in_reg & BYPASS_PAGE_M) {
|
||||
case BYPASS_PAGE_CTL0:
|
||||
/* All the following can't change since the last write
|
||||
* - All the event actions
|
||||
* - The timeout value
|
||||
*/
|
||||
mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M |
|
||||
BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M |
|
||||
BYPASS_WDTIMEOUT_M |
|
||||
BYPASS_WDT_VALUE_M;
|
||||
if ((out_reg & mask) != (in_reg & mask))
|
||||
return false;
|
||||
|
||||
/* 0x0 is never a valid value for bypass status */
|
||||
if (!(out_reg & BYPASS_STATUS_OFF_M))
|
||||
return false;
|
||||
break;
|
||||
case BYPASS_PAGE_CTL1:
|
||||
/* All the following can't change since the last write
|
||||
* - time valid bit
|
||||
* - time we last sent
|
||||
*/
|
||||
mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M;
|
||||
if ((out_reg & mask) != (in_reg & mask))
|
||||
return false;
|
||||
break;
|
||||
case BYPASS_PAGE_CTL2:
|
||||
/* All we can check in this page is control number
|
||||
* which is already done above.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* We are as sure as we can be return true */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Regiter.
|
||||
*
|
||||
* @hw: pointer to hardware structure
|
||||
* @cmd: The control word we are setting.
|
||||
* @event: The event we are setting in the FW. This also happens to
|
||||
* be the mask for the event we are setting (handy)
|
||||
* @action: The action we set the event to in the FW. This is in a
|
||||
* bit field that happens to be what we want to put in
|
||||
* the event spot (also handy)
|
||||
**/
|
||||
static s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event,
|
||||
u32 action)
|
||||
{
|
||||
u32 by_ctl = 0;
|
||||
u32 cmd, verify;
|
||||
u32 count = 0;
|
||||
|
||||
/* Get current values */
|
||||
cmd = ctrl; /* just reading only need control number */
|
||||
if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
|
||||
return IXGBE_ERR_INVALID_ARGUMENT;
|
||||
|
||||
/* Set to new action */
|
||||
cmd = (by_ctl & ~event) | BYPASS_WE | action;
|
||||
if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
|
||||
return IXGBE_ERR_INVALID_ARGUMENT;
|
||||
|
||||
/* Page 0 force a FW eeprom write which is slow so verify */
|
||||
if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) {
|
||||
verify = BYPASS_PAGE_CTL0;
|
||||
do {
|
||||
if (count++ > 5)
|
||||
return IXGBE_BYPASS_FW_WRITE_FAILURE;
|
||||
|
||||
if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl))
|
||||
return IXGBE_ERR_INVALID_ARGUMENT;
|
||||
} while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl));
|
||||
} else {
|
||||
/* We have give the FW time for the write to stick */
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom addres.
|
||||
*
|
||||
* @hw: pointer to hardware structure
|
||||
* @addr: The bypass eeprom address to read.
|
||||
* @value: The 8b of data at the address above.
|
||||
**/
|
||||
static s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value)
|
||||
{
|
||||
u32 cmd;
|
||||
u32 status;
|
||||
|
||||
|
||||
/* send the request */
|
||||
cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
|
||||
cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
|
||||
if (ixgbe_bypass_rw_generic(hw, cmd, &status))
|
||||
return IXGBE_ERR_INVALID_ARGUMENT;
|
||||
|
||||
/* We have give the FW time for the write to stick */
|
||||
msleep(100);
|
||||
|
||||
/* now read the results */
|
||||
cmd &= ~BYPASS_WE;
|
||||
if (ixgbe_bypass_rw_generic(hw, cmd, &status))
|
||||
return IXGBE_ERR_INVALID_ARGUMENT;
|
||||
|
||||
*value = status & BYPASS_CTL2_DATA_M;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
|
||||
#endif /* _IXGBE_BYPASS_API_H_ */
|
160
lib/librte_pmd_ixgbe/ixgbe_bypass_defines.h
Normal file
160
lib/librte_pmd_ixgbe/ixgbe_bypass_defines.h
Normal file
@ -0,0 +1,160 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _IXGBE_BYPASS_DEFINES_H_
|
||||
#define _IXGBE_BYPASS_DEFINES_H_
|
||||
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
|
||||
#define msleep(x) rte_delay_us(x*1000)
|
||||
#define usleep_range(min, max) rte_delay_us(min)
|
||||
|
||||
#define BYPASS_PAGE_CTL0 0x00000000
|
||||
#define BYPASS_PAGE_CTL1 0x40000000
|
||||
#define BYPASS_PAGE_CTL2 0x80000000
|
||||
#define BYPASS_PAGE_M 0xc0000000
|
||||
#define BYPASS_WE 0x20000000
|
||||
|
||||
#define BYPASS_AUTO 0x0
|
||||
#define BYPASS_NOP 0x0
|
||||
#define BYPASS_NORM 0x1
|
||||
#define BYPASS_BYPASS 0x2
|
||||
#define BYPASS_ISOLATE 0x3
|
||||
|
||||
#define BYPASS_EVENT_MAIN_ON 0x1
|
||||
#define BYPASS_EVENT_AUX_ON 0x2
|
||||
#define BYPASS_EVENT_MAIN_OFF 0x3
|
||||
#define BYPASS_EVENT_AUX_OFF 0x4
|
||||
#define BYPASS_EVENT_WDT_TO 0x5
|
||||
#define BYPASS_EVENT_USR 0x6
|
||||
|
||||
#define BYPASS_MODE_OFF_M 0x00000003
|
||||
#define BYPASS_STATUS_OFF_M 0x0000000c
|
||||
#define BYPASS_AUX_ON_M 0x00000030
|
||||
#define BYPASS_MAIN_ON_M 0x000000c0
|
||||
#define BYPASS_MAIN_OFF_M 0x00000300
|
||||
#define BYPASS_AUX_OFF_M 0x00000c00
|
||||
#define BYPASS_WDTIMEOUT_M 0x00003000
|
||||
#define BYPASS_WDT_ENABLE_M 0x00004000
|
||||
#define BYPASS_WDT_VALUE_M 0x00070000
|
||||
|
||||
#define BYPASS_MODE_OFF_SHIFT 0
|
||||
#define BYPASS_STATUS_OFF_SHIFT 2
|
||||
#define BYPASS_AUX_ON_SHIFT 4
|
||||
#define BYPASS_MAIN_ON_SHIFT 6
|
||||
#define BYPASS_MAIN_OFF_SHIFT 8
|
||||
#define BYPASS_AUX_OFF_SHIFT 10
|
||||
#define BYPASS_WDTIMEOUT_SHIFT 12
|
||||
#define BYPASS_WDT_ENABLE_SHIFT 14
|
||||
#define BYPASS_WDT_TIME_SHIFT 16
|
||||
|
||||
#define BYPASS_WDT_1 0x0
|
||||
#define BYPASS_WDT_1_5 0x1
|
||||
#define BYPASS_WDT_2 0x2
|
||||
#define BYPASS_WDT_3 0x3
|
||||
#define BYPASS_WDT_4 0x4
|
||||
#define BYPASS_WDT_8 0x5
|
||||
#define BYPASS_WDT_16 0x6
|
||||
#define BYPASS_WDT_32 0x7
|
||||
#define BYPASS_WDT_OFF 0xffff
|
||||
|
||||
#define BYPASS_WDT_MASK 0x7
|
||||
|
||||
#define BYPASS_CTL1_TIME_M 0x01ffffff
|
||||
#define BYPASS_CTL1_VALID_M 0x02000000
|
||||
#define BYPASS_CTL1_OFFTRST_M 0x04000000
|
||||
#define BYPASS_CTL1_WDT_PET_M 0x08000000
|
||||
|
||||
#define BYPASS_CTL1_VALID 0x02000000
|
||||
#define BYPASS_CTL1_OFFTRST 0x04000000
|
||||
#define BYPASS_CTL1_WDT_PET 0x08000000
|
||||
|
||||
#define BYPASS_CTL2_DATA_M 0x000000ff
|
||||
#define BYPASS_CTL2_OFFSET_M 0x0000ff00
|
||||
#define BYPASS_CTL2_RW_M 0x00010000
|
||||
#define BYPASS_CTL2_HEAD_M 0x0ff00000
|
||||
|
||||
#define BYPASS_CTL2_OFFSET_SHIFT 8
|
||||
#define BYPASS_CTL2_HEAD_SHIFT 20
|
||||
|
||||
#define BYPASS_CTL2_RW 0x00010000
|
||||
|
||||
enum ixgbe_state_t {
|
||||
__IXGBE_TESTING,
|
||||
__IXGBE_RESETTING,
|
||||
__IXGBE_DOWN,
|
||||
__IXGBE_SERVICE_SCHED,
|
||||
__IXGBE_IN_SFP_INIT,
|
||||
__IXGBE_IN_BYPASS_LOW,
|
||||
__IXGBE_IN_BYPASS_HIGH,
|
||||
__IXGBE_IN_BYPASS_LOG,
|
||||
};
|
||||
|
||||
#define BYPASS_MAX_LOGS 43
|
||||
#define BYPASS_LOG_SIZE 5
|
||||
#define BYPASS_LOG_LINE_SIZE 37
|
||||
|
||||
#define BYPASS_EEPROM_VER_ADD 0x02
|
||||
|
||||
#define BYPASS_LOG_TIME_M 0x01ffffff
|
||||
#define BYPASS_LOG_TIME_VALID_M 0x02000000
|
||||
#define BYPASS_LOG_HEAD_M 0x04000000
|
||||
#define BYPASS_LOG_CLEAR_M 0x08000000
|
||||
#define BYPASS_LOG_EVENT_M 0xf0000000
|
||||
#define BYPASS_LOG_ACTION_M 0x03
|
||||
|
||||
#define BYPASS_LOG_EVENT_SHIFT 28
|
||||
#define BYPASS_LOG_CLEAR_SHIFT 24 /* bit offset */
|
||||
#define IXGBE_DEV_TO_ADPATER(dev) \
|
||||
((struct ixgbe_adapter*)(dev->data->dev_private))
|
||||
|
||||
/* extractions from ixgbe_phy.h */
|
||||
#define IXGBE_I2C_EEPROM_DEV_ADDR2 0xA2
|
||||
|
||||
#define IXGBE_SFF_SFF_8472_SWAP 0x5C
|
||||
#define IXGBE_SFF_SFF_8472_COMP 0x5E
|
||||
#define IXGBE_SFF_SFF_8472_OSCB 0x6E
|
||||
#define IXGBE_SFF_SFF_8472_ESCB 0x76
|
||||
|
||||
#define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8
|
||||
#define IXGBE_SFF_SOFT_RS_SELECT_10G 0x8
|
||||
#define IXGBE_SFF_SOFT_RS_SELECT_1G 0x0
|
||||
|
||||
/* extractions from ixgbe_type.h */
|
||||
#define IXGBE_DEV_ID_82599_BYPASS 0x155D
|
||||
|
||||
#define IXGBE_BYPASS_FW_WRITE_FAILURE -35
|
||||
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
|
||||
#endif /* _IXGBE_BYPASS_DEFINES_H_ */
|
@ -64,6 +64,7 @@
|
||||
#include "ixgbe/ixgbe_vf.h"
|
||||
#include "ixgbe/ixgbe_common.h"
|
||||
#include "ixgbe_ethdev.h"
|
||||
#include "ixgbe_bypass.h"
|
||||
|
||||
/*
|
||||
* High threshold controlling when to start sending XOFF frames. Must be at
|
||||
@ -288,6 +289,17 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
|
||||
.fdir_set_masks = ixgbe_fdir_set_masks,
|
||||
.reta_update = ixgbe_dev_rss_reta_update,
|
||||
.reta_query = ixgbe_dev_rss_reta_query,
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
.bypass_init = ixgbe_bypass_init,
|
||||
.bypass_state_set = ixgbe_bypass_state_store,
|
||||
.bypass_state_show = ixgbe_bypass_state_show,
|
||||
.bypass_event_set = ixgbe_bypass_event_store,
|
||||
.bypass_event_show = ixgbe_bypass_event_show,
|
||||
.bypass_wd_timeout_set = ixgbe_bypass_wd_timeout_store,
|
||||
.bypass_wd_timeout_show = ixgbe_bypass_wd_timeout_show,
|
||||
.bypass_ver_show = ixgbe_bypass_ver_show,
|
||||
.bypass_wd_reset = ixgbe_bypass_wd_reset,
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -620,7 +632,12 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
|
||||
#endif
|
||||
|
||||
/* Initialize the shared code */
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
diag = ixgbe_bypass_init_shared_code(hw);
|
||||
#else
|
||||
diag = ixgbe_init_shared_code(hw);
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
|
||||
if (diag != IXGBE_SUCCESS) {
|
||||
PMD_INIT_LOG(ERR, "Shared code init failed: %d", diag);
|
||||
return -EIO;
|
||||
@ -646,7 +663,11 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
diag = ixgbe_bypass_init_hw(hw);
|
||||
#else
|
||||
diag = ixgbe_init_hw(hw);
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
|
||||
/*
|
||||
* Devices with copper phys will fail to initialise if ixgbe_init_hw()
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "ixgbe/ixgbe_dcb.h"
|
||||
#include "ixgbe/ixgbe_dcb_82599.h"
|
||||
#include "ixgbe/ixgbe_dcb_82598.h"
|
||||
#include "ixgbe_bypass.h"
|
||||
|
||||
/* need update link, bit flag */
|
||||
#define IXGBE_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0)
|
||||
@ -140,6 +141,9 @@ struct ixgbe_adapter {
|
||||
struct ixgbe_mirror_info mr_data;
|
||||
struct ixgbe_vf_info *vfdata;
|
||||
struct ixgbe_uta_info uta_info;
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
struct ixgbe_bypass_info bps;
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
};
|
||||
|
||||
#define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
|
||||
|
Loading…
Reference in New Issue
Block a user