ixgbe: Add support for E610 FW Admin Command Interface

Add low level support for Admin Command Interface (ACI). ACI is the
Firmware interface used by a driver to communicate with E610 adapter. Add
the following ACI features:
- data structures, macros, register definitions
- commands handling
- events handling

Co-developed-by: Stefan Wegrzyn <stefan.wegrzyn@intel.com>
Signed-off-by: Stefan Wegrzyn <stefan.wegrzyn@intel.com>
Co-developed-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Tested-by: Bharath R <bharath.r@intel.com>
Signed-off-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
Piotr Kwapulinski 2024-12-05 09:44:43 +01:00 committed by Tony Nguyen
parent b73e56f162
commit 46761fd52a
6 changed files with 1657 additions and 7 deletions

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright(c) 1999 - 2018 Intel Corporation.
# Copyright(c) 1999 - 2024 Intel Corporation.
#
# Makefile for the Intel(R) 10GbE PCI Express ethernet driver
#
@ -9,7 +9,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o
ixgbe-y := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o \
ixgbe_xsk.o
ixgbe_xsk.o ixgbe_e610.o
ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
ixgbe_dcb_82599.o ixgbe_dcb_nl.o

View File

@ -660,7 +660,11 @@ int ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
hw->bus.type = ixgbe_bus_type_pci_express;
/* Get the negotiated link width and speed from PCI config space */
link_status = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_LINK_STATUS);
if (hw->mac.type == ixgbe_mac_e610)
link_status = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_LINK_STATUS_E610);
else
link_status = ixgbe_read_pci_cfg_word(hw,
IXGBE_PCI_LINK_STATUS);
hw->bus.width = ixgbe_convert_bus_width(link_status);
hw->bus.speed = ixgbe_convert_bus_speed(link_status);

View File

@ -0,0 +1,497 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2024 Intel Corporation. */
#include "ixgbe_common.h"
#include "ixgbe_e610.h"
#include "ixgbe_type.h"
#include "ixgbe_x540.h"
#include "ixgbe_phy.h"
/**
* ixgbe_should_retry_aci_send_cmd_execute - decide if ACI command should
* be resent
* @opcode: ACI opcode
*
* Check if ACI command should be sent again depending on the provided opcode.
* It may happen when CSR is busy during link state changes.
*
* Return: true if the sending command routine should be repeated,
* otherwise false.
*/
static bool ixgbe_should_retry_aci_send_cmd_execute(u16 opcode)
{
switch (opcode) {
case ixgbe_aci_opc_disable_rxen:
case ixgbe_aci_opc_get_phy_caps:
case ixgbe_aci_opc_get_link_status:
case ixgbe_aci_opc_get_link_topo:
return true;
}
return false;
}
/**
* ixgbe_aci_send_cmd_execute - execute sending FW Admin Command to FW Admin
* Command Interface
* @hw: pointer to the HW struct
* @desc: descriptor describing the command
* @buf: buffer to use for indirect commands (NULL for direct commands)
* @buf_size: size of buffer for indirect commands (0 for direct commands)
*
* Admin Command is sent using CSR by setting descriptor and buffer in specific
* registers.
*
* Return: the exit code of the operation.
* * - 0 - success.
* * - -EIO - CSR mechanism is not enabled.
* * - -EBUSY - CSR mechanism is busy.
* * - -EINVAL - buf_size is too big or
* invalid argument buf or buf_size.
* * - -ETIME - Admin Command X command timeout.
* * - -EIO - Admin Command X invalid state of HICR register or
* Admin Command failed because of bad opcode was returned or
* Admin Command failed with error Y.
*/
static int ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw,
struct ixgbe_aci_desc *desc,
void *buf, u16 buf_size)
{
u16 opcode, buf_tail_size = buf_size % 4;
u32 *raw_desc = (u32 *)desc;
u32 hicr, i, buf_tail = 0;
bool valid_buf = false;
hw->aci.last_status = IXGBE_ACI_RC_OK;
/* It's necessary to check if mechanism is enabled */
hicr = IXGBE_READ_REG(hw, IXGBE_PF_HICR);
if (!(hicr & IXGBE_PF_HICR_EN))
return -EIO;
if (hicr & IXGBE_PF_HICR_C) {
hw->aci.last_status = IXGBE_ACI_RC_EBUSY;
return -EBUSY;
}
opcode = le16_to_cpu(desc->opcode);
if (buf_size > IXGBE_ACI_MAX_BUFFER_SIZE)
return -EINVAL;
if (buf)
desc->flags |= cpu_to_le16(IXGBE_ACI_FLAG_BUF);
if (desc->flags & cpu_to_le16(IXGBE_ACI_FLAG_BUF)) {
if ((buf && !buf_size) ||
(!buf && buf_size))
return -EINVAL;
if (buf && buf_size)
valid_buf = true;
}
if (valid_buf) {
if (buf_tail_size)
memcpy(&buf_tail, buf + buf_size - buf_tail_size,
buf_tail_size);
if (((buf_size + 3) & ~0x3) > IXGBE_ACI_LG_BUF)
desc->flags |= cpu_to_le16(IXGBE_ACI_FLAG_LB);
desc->datalen = cpu_to_le16(buf_size);
if (desc->flags & cpu_to_le16(IXGBE_ACI_FLAG_RD)) {
for (i = 0; i < buf_size / 4; i++)
IXGBE_WRITE_REG(hw, IXGBE_PF_HIBA(i), ((u32 *)buf)[i]);
if (buf_tail_size)
IXGBE_WRITE_REG(hw, IXGBE_PF_HIBA(i), buf_tail);
}
}
/* Descriptor is written to specific registers */
for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++)
IXGBE_WRITE_REG(hw, IXGBE_PF_HIDA(i), raw_desc[i]);
/* SW has to set PF_HICR.C bit and clear PF_HICR.SV and
* PF_HICR_EV
*/
hicr = (IXGBE_READ_REG(hw, IXGBE_PF_HICR) | IXGBE_PF_HICR_C) &
~(IXGBE_PF_HICR_SV | IXGBE_PF_HICR_EV);
IXGBE_WRITE_REG(hw, IXGBE_PF_HICR, hicr);
#define MAX_SLEEP_RESP_US 1000
#define MAX_TMOUT_RESP_SYNC_US 100000000
/* Wait for sync Admin Command response */
read_poll_timeout(IXGBE_READ_REG, hicr,
(hicr & IXGBE_PF_HICR_SV) ||
!(hicr & IXGBE_PF_HICR_C),
MAX_SLEEP_RESP_US, MAX_TMOUT_RESP_SYNC_US, true, hw,
IXGBE_PF_HICR);
#define MAX_TMOUT_RESP_ASYNC_US 150000000
/* Wait for async Admin Command response */
read_poll_timeout(IXGBE_READ_REG, hicr,
(hicr & IXGBE_PF_HICR_EV) ||
!(hicr & IXGBE_PF_HICR_C),
MAX_SLEEP_RESP_US, MAX_TMOUT_RESP_ASYNC_US, true, hw,
IXGBE_PF_HICR);
/* Read sync Admin Command response */
if ((hicr & IXGBE_PF_HICR_SV)) {
for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) {
raw_desc[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIDA(i));
raw_desc[i] = raw_desc[i];
}
}
/* Read async Admin Command response */
if ((hicr & IXGBE_PF_HICR_EV) && !(hicr & IXGBE_PF_HICR_C)) {
for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) {
raw_desc[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIDA_2(i));
raw_desc[i] = raw_desc[i];
}
}
/* Handle timeout and invalid state of HICR register */
if (hicr & IXGBE_PF_HICR_C)
return -ETIME;
if (!(hicr & IXGBE_PF_HICR_SV) && !(hicr & IXGBE_PF_HICR_EV))
return -EIO;
/* For every command other than 0x0014 treat opcode mismatch
* as an error. Response to 0x0014 command read from HIDA_2
* is a descriptor of an event which is expected to contain
* different opcode than the command.
*/
if (desc->opcode != cpu_to_le16(opcode) &&
opcode != ixgbe_aci_opc_get_fw_event)
return -EIO;
if (desc->retval) {
hw->aci.last_status = (enum ixgbe_aci_err)
le16_to_cpu(desc->retval);
return -EIO;
}
/* Write a response values to a buf */
if (valid_buf) {
for (i = 0; i < buf_size / 4; i++)
((u32 *)buf)[i] = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
if (buf_tail_size) {
buf_tail = IXGBE_READ_REG(hw, IXGBE_PF_HIBA(i));
memcpy(buf + buf_size - buf_tail_size, &buf_tail,
buf_tail_size);
}
}
return 0;
}
/**
* ixgbe_aci_send_cmd - send FW Admin Command to FW Admin Command Interface
* @hw: pointer to the HW struct
* @desc: descriptor describing the command
* @buf: buffer to use for indirect commands (NULL for direct commands)
* @buf_size: size of buffer for indirect commands (0 for direct commands)
*
* Helper function to send FW Admin Commands to the FW Admin Command Interface.
*
* Retry sending the FW Admin Command multiple times to the FW ACI
* if the EBUSY Admin Command error is returned.
*
* Return: the exit code of the operation.
*/
int ixgbe_aci_send_cmd(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
void *buf, u16 buf_size)
{
u16 opcode = le16_to_cpu(desc->opcode);
struct ixgbe_aci_desc desc_cpy;
enum ixgbe_aci_err last_status;
u8 idx = 0, *buf_cpy = NULL;
bool is_cmd_for_retry;
unsigned long timeout;
int err;
is_cmd_for_retry = ixgbe_should_retry_aci_send_cmd_execute(opcode);
if (is_cmd_for_retry) {
if (buf) {
buf_cpy = kmalloc(buf_size, GFP_KERNEL);
if (!buf_cpy)
return -ENOMEM;
*buf_cpy = *(u8 *)buf;
}
desc_cpy = *desc;
}
timeout = jiffies + msecs_to_jiffies(IXGBE_ACI_SEND_TIMEOUT_MS);
do {
mutex_lock(&hw->aci.lock);
err = ixgbe_aci_send_cmd_execute(hw, desc, buf, buf_size);
last_status = hw->aci.last_status;
mutex_unlock(&hw->aci.lock);
if (!is_cmd_for_retry || !err ||
last_status != IXGBE_ACI_RC_EBUSY)
break;
if (buf)
memcpy(buf, buf_cpy, buf_size);
*desc = desc_cpy;
msleep(IXGBE_ACI_SEND_DELAY_TIME_MS);
} while (++idx < IXGBE_ACI_SEND_MAX_EXECUTE &&
time_before(jiffies, timeout));
kfree(buf_cpy);
return err;
}
/**
* ixgbe_aci_check_event_pending - check if there are any pending events
* @hw: pointer to the HW struct
*
* Determine if there are any pending events.
*
* Return: true if there are any currently pending events
* otherwise false.
*/
bool ixgbe_aci_check_event_pending(struct ixgbe_hw *hw)
{
u32 ep_bit_mask = hw->bus.func ? GL_FWSTS_EP_PF1 : GL_FWSTS_EP_PF0;
u32 fwsts = IXGBE_READ_REG(hw, GL_FWSTS);
return (fwsts & ep_bit_mask) ? true : false;
}
/**
* ixgbe_aci_get_event - get an event from ACI
* @hw: pointer to the HW struct
* @e: event information structure
* @pending: optional flag signaling that there are more pending events
*
* Obtain an event from ACI and return its content
* through 'e' using ACI command (0x0014).
* Provide information if there are more events
* to retrieve through 'pending'.
*
* Return: the exit code of the operation.
*/
int ixgbe_aci_get_event(struct ixgbe_hw *hw, struct ixgbe_aci_event *e,
bool *pending)
{
struct ixgbe_aci_desc desc;
int err;
if (!e || (!e->msg_buf && e->buf_len))
return -EINVAL;
mutex_lock(&hw->aci.lock);
/* Check if there are any events pending */
if (!ixgbe_aci_check_event_pending(hw)) {
err = -ENOENT;
goto aci_get_event_exit;
}
/* Obtain pending event */
ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_fw_event);
err = ixgbe_aci_send_cmd_execute(hw, &desc, e->msg_buf, e->buf_len);
if (err)
goto aci_get_event_exit;
/* Returned 0x0014 opcode indicates that no event was obtained */
if (desc.opcode == cpu_to_le16(ixgbe_aci_opc_get_fw_event)) {
err = -ENOENT;
goto aci_get_event_exit;
}
/* Determine size of event data */
e->msg_len = min_t(u16, le16_to_cpu(desc.datalen), e->buf_len);
/* Write event descriptor to event info structure */
memcpy(&e->desc, &desc, sizeof(e->desc));
/* Check if there are any further events pending */
if (pending)
*pending = ixgbe_aci_check_event_pending(hw);
aci_get_event_exit:
mutex_unlock(&hw->aci.lock);
return err;
}
/**
* ixgbe_fill_dflt_direct_cmd_desc - fill ACI descriptor with default values.
* @desc: pointer to the temp descriptor (non DMA mem)
* @opcode: the opcode can be used to decide which flags to turn off or on
*
* Helper function to fill the descriptor desc with default values
* and the provided opcode.
*/
void ixgbe_fill_dflt_direct_cmd_desc(struct ixgbe_aci_desc *desc, u16 opcode)
{
/* Zero out the desc. */
memset(desc, 0, sizeof(*desc));
desc->opcode = cpu_to_le16(opcode);
desc->flags = cpu_to_le16(IXGBE_ACI_FLAG_SI);
}
/**
* ixgbe_aci_req_res - request a common resource
* @hw: pointer to the HW struct
* @res: resource ID
* @access: access type
* @sdp_number: resource number
* @timeout: the maximum time in ms that the driver may hold the resource
*
* Requests a common resource using the ACI command (0x0008).
* Specifies the maximum time the driver may hold the resource.
* If the requested resource is currently occupied by some other driver,
* a busy return value is returned and the timeout field value indicates the
* maximum time the current owner has to free it.
*
* Return: the exit code of the operation.
*/
static int ixgbe_aci_req_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res,
enum ixgbe_aci_res_access_type access,
u8 sdp_number, u32 *timeout)
{
struct ixgbe_aci_cmd_req_res *cmd_resp;
struct ixgbe_aci_desc desc;
int err;
cmd_resp = &desc.params.res_owner;
ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_req_res);
cmd_resp->res_id = cpu_to_le16(res);
cmd_resp->access_type = cpu_to_le16(access);
cmd_resp->res_number = cpu_to_le32(sdp_number);
cmd_resp->timeout = cpu_to_le32(*timeout);
*timeout = 0;
err = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
/* If the resource is held by some other driver, the command completes
* with a busy return value and the timeout field indicates the maximum
* time the current owner of the resource has to free it.
*/
if (!err || hw->aci.last_status == IXGBE_ACI_RC_EBUSY)
*timeout = le32_to_cpu(cmd_resp->timeout);
return err;
}
/**
* ixgbe_aci_release_res - release a common resource using ACI
* @hw: pointer to the HW struct
* @res: resource ID
* @sdp_number: resource number
*
* Release a common resource using ACI command (0x0009).
*
* Return: the exit code of the operation.
*/
static int ixgbe_aci_release_res(struct ixgbe_hw *hw,
enum ixgbe_aci_res_ids res, u8 sdp_number)
{
struct ixgbe_aci_cmd_req_res *cmd;
struct ixgbe_aci_desc desc;
cmd = &desc.params.res_owner;
ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_release_res);
cmd->res_id = cpu_to_le16(res);
cmd->res_number = cpu_to_le32(sdp_number);
return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
}
/**
* ixgbe_acquire_res - acquire the ownership of a resource
* @hw: pointer to the HW structure
* @res: resource ID
* @access: access type (read or write)
* @timeout: timeout in milliseconds
*
* Make an attempt to acquire the ownership of a resource using
* the ixgbe_aci_req_res to utilize ACI.
* In case if some other driver has previously acquired the resource and
* performed any necessary updates, the -EALREADY is returned,
* and the caller does not obtain the resource and has no further work to do.
* If needed, the function will poll until the current lock owner timeouts.
*
* Return: the exit code of the operation.
*/
int ixgbe_acquire_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res,
enum ixgbe_aci_res_access_type access, u32 timeout)
{
#define IXGBE_RES_POLLING_DELAY_MS 10
u32 delay = IXGBE_RES_POLLING_DELAY_MS;
u32 res_timeout = timeout;
u32 retry_timeout;
int err;
err = ixgbe_aci_req_res(hw, res, access, 0, &res_timeout);
/* A return code of -EALREADY means that another driver has
* previously acquired the resource and performed any necessary updates;
* in this case the caller does not obtain the resource and has no
* further work to do.
*/
if (err == -EALREADY)
return err;
/* If necessary, poll until the current lock owner timeouts.
* Set retry_timeout to the timeout value reported by the FW in the
* response to the "Request Resource Ownership" (0x0008) Admin Command
* as it indicates the maximum time the current owner of the resource
* is allowed to hold it.
*/
retry_timeout = res_timeout;
while (err && retry_timeout && res_timeout) {
msleep(delay);
retry_timeout = (retry_timeout > delay) ?
retry_timeout - delay : 0;
err = ixgbe_aci_req_res(hw, res, access, 0, &res_timeout);
/* Success - lock acquired.
* -EALREADY - lock free, no work to do.
*/
if (!err || err == -EALREADY)
break;
}
return err;
}
/**
* ixgbe_release_res - release a common resource
* @hw: pointer to the HW structure
* @res: resource ID
*
* Release a common resource using ixgbe_aci_release_res.
*/
void ixgbe_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res)
{
u32 total_delay = 0;
int err;
err = ixgbe_aci_release_res(hw, res, 0);
/* There are some rare cases when trying to release the resource
* results in an admin command timeout, so handle them correctly.
*/
while (err == -ETIME &&
total_delay < IXGBE_ACI_RELEASE_RES_TIMEOUT) {
usleep_range(1000, 1500);
err = ixgbe_aci_release_res(hw, res, 0);
total_delay++;
}
}

View File

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2024 Intel Corporation. */
#ifndef _IXGBE_E610_H_
#define _IXGBE_E610_H_
#include "ixgbe_type.h"
int ixgbe_aci_send_cmd(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
void *buf, u16 buf_size);
bool ixgbe_aci_check_event_pending(struct ixgbe_hw *hw);
int ixgbe_aci_get_event(struct ixgbe_hw *hw, struct ixgbe_aci_event *e,
bool *pending);
void ixgbe_fill_dflt_direct_cmd_desc(struct ixgbe_aci_desc *desc, u16 opcode);
int ixgbe_acquire_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res,
enum ixgbe_aci_res_access_type access, u32 timeout);
void ixgbe_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res);
#endif /* _IXGBE_E610_H_ */

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 1999 - 2018 Intel Corporation. */
/* Copyright(c) 1999 - 2024 Intel Corporation. */
#ifndef _IXGBE_TYPE_H_
#define _IXGBE_TYPE_H_
@ -7,6 +7,7 @@
#include <linux/types.h>
#include <linux/mdio.h>
#include <linux/netdevice.h>
#include "ixgbe_type_e610.h"
/* Device IDs */
#define IXGBE_DEV_ID_82598 0x10B6
@ -71,12 +72,19 @@
#define IXGBE_DEV_ID_X550EM_A_1G_T 0x15E4
#define IXGBE_DEV_ID_X550EM_A_1G_T_L 0x15E5
#define IXGBE_DEV_ID_E610_BACKPLANE 0x57AE
#define IXGBE_DEV_ID_E610_SFP 0x57AF
#define IXGBE_DEV_ID_E610_10G_T 0x57B0
#define IXGBE_DEV_ID_E610_2_5G_T 0x57B1
#define IXGBE_DEV_ID_E610_SGMII 0x57B2
/* VF Device IDs */
#define IXGBE_DEV_ID_82599_VF 0x10ED
#define IXGBE_DEV_ID_X540_VF 0x1515
#define IXGBE_DEV_ID_X550_VF 0x1565
#define IXGBE_DEV_ID_X550EM_X_VF 0x15A8
#define IXGBE_DEV_ID_X550EM_A_VF 0x15C5
#define IXGBE_DEV_ID_E610_VF 0x57AD
#define IXGBE_CAT(r, m) IXGBE_##r##_##m
@ -1600,7 +1608,7 @@ enum {
#define IXGBE_EICR_PCI 0x00040000 /* PCI Exception */
#define IXGBE_EICR_MAILBOX 0x00080000 /* VF to PF Mailbox Interrupt */
#define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */
#define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */
#define IXGBE_EICR_FW_EVENT 0x00200000 /* Async FW event */
#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */
#define IXGBE_EICR_TS 0x00800000 /* Thermal Sensor Event */
#define IXGBE_EICR_TIMESYNC 0x01000000 /* Timesync Event */
@ -1636,6 +1644,7 @@ enum {
#define IXGBE_EICS_PCI IXGBE_EICR_PCI /* PCI Exception */
#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EICS_FW_EVENT IXGBE_EICR_FW_EVENT /* Async FW event */
#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EICS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */
#define IXGBE_EICS_GPI_SDP0(_hw) IXGBE_EICR_GPI_SDP0(_hw)
@ -1654,6 +1663,7 @@ enum {
#define IXGBE_EIMS_PCI IXGBE_EICR_PCI /* PCI Exception */
#define IXGBE_EIMS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMS_FW_EVENT IXGBE_EICR_FW_EVENT /* Async FW event */
#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EIMS_TS IXGBE_EICR_TS /* Thermel Sensor Event */
#define IXGBE_EIMS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */
@ -1673,6 +1683,7 @@ enum {
#define IXGBE_EIMC_PCI IXGBE_EICR_PCI /* PCI Exception */
#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMC_FW_EVENT IXGBE_EICR_FW_EVENT /* Async FW event */
#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EIMC_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */
#define IXGBE_EIMC_GPI_SDP0(_hw) IXGBE_EICR_GPI_SDP0(_hw)
@ -2068,6 +2079,7 @@ enum {
#define IXGBE_SAN_MAC_ADDR_PTR 0x28
#define IXGBE_DEVICE_CAPS 0x2C
#define IXGBE_SERIAL_NUMBER_MAC_ADDR 0x11
#define IXGBE_PCIE_MSIX_E610_CAPS 0xB2
#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
#define IXGBE_MAX_MSIX_VECTORS_82599 0x40
#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
@ -2168,6 +2180,7 @@ enum {
#define IXGBE_PCI_DEVICE_STATUS 0xAA
#define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020
#define IXGBE_PCI_LINK_STATUS 0xB2
#define IXGBE_PCI_LINK_STATUS_E610 0x82
#define IXGBE_PCI_DEVICE_CONTROL2 0xC8
#define IXGBE_PCI_LINK_WIDTH 0x3F0
#define IXGBE_PCI_LINK_WIDTH_1 0x10
@ -2288,6 +2301,7 @@ enum {
#define IXGBE_RXMTRL_V2_MGMT_MSG 0x0D00
#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
#define IXGBE_FCTRL_TPE 0x00000080 /* Tag Promiscuous Ena*/
#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
#define IXGBE_FCTRL_UPE 0x00000200 /* Unicast Promiscuous Ena */
#define IXGBE_FCTRL_BAM 0x00000400 /* Broadcast Accept Mode */
@ -2351,6 +2365,7 @@ enum {
/* Multiple Transmit Queue Command Register */
#define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */
#define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */
#define IXGBE_MTQC_NUM_TC_OR_Q 0xC /* Number of TCs or TxQs per pool */
#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */
#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */
#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */
@ -2970,6 +2985,29 @@ typedef u32 ixgbe_link_speed;
IXGBE_LINK_SPEED_1GB_FULL | \
IXGBE_LINK_SPEED_10GB_FULL)
/* Physical layer type */
typedef u64 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x00001
#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x00002
#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x00004
#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x00008
#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x00010
#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x00020
#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x00040
#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x00080
#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x00100
#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x00200
#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x00400
#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x00800
#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x01000
#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x02000
#define IXGBE_PHYSICAL_LAYER_1000BASE_SX 0x04000
#define IXGBE_PHYSICAL_LAYER_10BASE_T 0x08000
#define IXGBE_PHYSICAL_LAYER_2500BASE_KX 0x10000
#define IXGBE_PHYSICAL_LAYER_2500BASE_T 0x20000
#define IXGBE_PHYSICAL_LAYER_5000BASE_T 0x40000
/* Flow Control Data Sheet defined values
* Calculation and defines taken from 802.1bb Annex O
*/
@ -3145,6 +3183,8 @@ enum ixgbe_mac_type {
ixgbe_mac_X550,
ixgbe_mac_X550EM_x,
ixgbe_mac_x550em_a,
ixgbe_mac_e610,
ixgbe_mac_e610_vf,
ixgbe_num_macs
};
@ -3224,7 +3264,9 @@ enum ixgbe_media_type {
ixgbe_media_type_copper,
ixgbe_media_type_backplane,
ixgbe_media_type_cx4,
ixgbe_media_type_virtual
ixgbe_media_type_virtual,
ixgbe_media_type_da,
ixgbe_media_type_aui,
};
/* Flow Control Settings */
@ -3233,7 +3275,8 @@ enum ixgbe_fc_mode {
ixgbe_fc_rx_pause,
ixgbe_fc_tx_pause,
ixgbe_fc_full,
ixgbe_fc_default
ixgbe_fc_default,
ixgbe_fc_pfc,
};
/* Smart Speed Settings */
@ -3533,6 +3576,9 @@ struct ixgbe_link_operations {
struct ixgbe_link_info {
struct ixgbe_link_operations ops;
u8 addr;
struct ixgbe_link_status link_info;
struct ixgbe_link_status link_info_old;
u8 get_link_info;
};
struct ixgbe_eeprom_info {
@ -3575,6 +3621,7 @@ struct ixgbe_mac_info {
u8 san_mac_rar_index;
struct ixgbe_thermal_sensor_data thermal_sensor_data;
bool set_lben;
u32 max_link_up_time;
u8 led_link_act;
};
@ -3599,6 +3646,10 @@ struct ixgbe_phy_info {
bool reset_if_overtemp;
bool qsfp_shared_i2c_bus;
u32 nw_mng_if_sel;
u64 phy_type_low;
u64 phy_type_high;
u16 curr_user_speed_req;
struct ixgbe_aci_cmd_set_phy_cfg_data curr_user_phy_cfg;
};
struct ixgbe_mbx_stats {
@ -3643,6 +3694,19 @@ struct ixgbe_hw {
bool allow_unsupported_sfp;
bool wol_enabled;
bool need_crosstalk_fix;
u8 api_branch;
u8 api_maj_ver;
u8 api_min_ver;
u8 api_patch;
u8 fw_branch;
u8 fw_maj_ver;
u8 fw_min_ver;
u8 fw_patch;
u32 fw_build;
struct ixgbe_aci_info aci;
struct ixgbe_flash_info flash;
struct ixgbe_hw_dev_caps dev_caps;
struct ixgbe_hw_func_caps func_caps;
};
struct ixgbe_info {

File diff suppressed because it is too large Load Diff