mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
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:
parent
b73e56f162
commit
46761fd52a
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
497
drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
Normal file
497
drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
Normal 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++;
|
||||
}
|
||||
}
|
||||
19
drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h
Normal file
19
drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h
Normal 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_ */
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
1066
drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
Normal file
1066
drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user