ixgbe: introduce new mailbox API

DPDK commit message

Current mailbox API does not work as described in documentation and
is prone to errors (for example, it is doing locks on read). Introduce
new mailbox API and provide compatibility functions with old API.

New error codes have been introduced:
- IXGBE_ERR_CONFIG - ixgbe_mbx_operations is not correctly set
- IXGBE_ERR_TIMEOUT - mailbox operation, e.g. poll for message, timedout
- IXGBE_ERR_MBX_NOMSG - no message available on read

In addition, some refactoring has been done: mailbox structures were
defined twice: in ixgbe_type.h and ixgbe_vf.h. Move them into
ixgbe_mbx.h as this header is dedicated for mailbox.

Signed-off-by: Jakub Chylkowski <jakubx.chylkowski@intel.com>
Reviewed-by: Alice Michael <alice.michael@intel.com>
Reviewed-by: Piotr Pietruszewski <piotr.pietruszewski@intel.com>
Tested-by: Alice Michael <alice.michael@intel.com>
Tested-by: Piotr Skajewski <piotrx.skajewski@intel.com>

Obtained from:	DPDK (6d243d2)

Reapply message

This reverts commit d80c12ba682a6f23791f3d6e657f9e603b152aa2.

(cherry picked from commit 7234c3099947d202702e98d844ecd2d649c834d2)
This commit is contained in:
Jakub Chylkowski 2024-09-19 19:30:39 -07:00 committed by Kevin Bowling
parent ddbbc129ae
commit 8abae0be0f
7 changed files with 701 additions and 291 deletions

View file

@ -879,6 +879,7 @@ ixgbe_if_attach_pre(if_ctx_t ctx)
struct ixgbe_hw *hw;
int error = 0;
u32 ctrl_ext;
size_t i;
INIT_DEBUGOUT("ixgbe_attach: begin");
@ -928,8 +929,11 @@ ixgbe_if_attach_pre(if_ctx_t ctx)
goto err_pci;
}
if (hw->mbx.ops.init_params)
hw->mbx.ops.init_params(hw);
/* 82598 Does not support SR-IOV, initialize everything else */
if (hw->mac.type >= ixgbe_mac_82599_vf) {
for (i = 0; i < sc->num_vfs; i++)
hw->mbx.ops[i].init_params(hw);
}
hw->allow_unsupported_sfp = allow_unsupported_sfp;

View file

@ -324,6 +324,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
struct ixgbe_phy_info *phy = &hw->phy;
struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
s32 ret_val;
u16 i;
DEBUGFUNC("ixgbe_init_ops_82599");
@ -385,7 +386,8 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))
& IXGBE_FWSM_MODE_MASK);
hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
for (i = 0; i < 64; i++)
hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf;
/* EEPROM */
eeprom->ops.read = ixgbe_read_eeprom_82599;

File diff suppressed because it is too large Load diff

View file

@ -37,8 +37,41 @@
#include "ixgbe_type.h"
struct ixgbe_mbx_operations {
void (*init_params)(struct ixgbe_hw *hw);
void (*release)(struct ixgbe_hw *hw, u16 mbx_id);
s32 (*read)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 (*write)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 (*check_for_msg)(struct ixgbe_hw *hw, u16 vf_number);
s32 (*check_for_ack)(struct ixgbe_hw *hw, u16 vf_number);
s32 (*check_for_rst)(struct ixgbe_hw *hw, u16 vf_number);
s32 (*clear)(struct ixgbe_hw *hw, u16 vf_number);
};
struct ixgbe_mbx_stats {
u32 msgs_tx;
u32 msgs_rx;
u32 acks;
u32 reqs;
u32 rsts;
};
struct ixgbe_mbx_info {
/*
* PF: One set of operations for each VF to handle various API versions
* at the same time
* VF: Only the very first (0) set should be used
*/
struct ixgbe_mbx_operations ops[64];
struct ixgbe_mbx_stats stats;
u32 timeout;
u32 usec_delay;
u32 vf_mailbox;
u16 size;
};
#define IXGBE_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
#define IXGBE_ERR_MBX -100
#define IXGBE_VFMAILBOX 0x002FC
#define IXGBE_VFMBMEM 0x00200
@ -92,6 +125,9 @@ enum ixgbe_pfvf_api_rev {
ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */
ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */
ixgbe_mbox_api_13, /* API version 1.3, linux/freebsd VF driver */
/* API 1.4 is being used in the upstream for IPsec */
ixgbe_mbox_api_14, /* API version 1.4, linux/freebsd VF driver */
ixgbe_mbox_api_15, /* API version 1.5, linux/freebsd VF driver */
/* This value should always be last */
ixgbe_mbox_api_unknown, /* indicates that API version is not known */
};
@ -153,15 +189,16 @@ enum ixgbevf_xcast_modes {
#define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
#define IXGBE_VF_MBX_INIT_DELAY 500 /* microseconds between retries */
s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16);
s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);
s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16);
s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16);
s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);
s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw);
void ixgbe_init_mbx_params_vf(struct ixgbe_hw *);
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id);
void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw);
void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw);
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw);
void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id);
void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id);
#endif /* _IXGBE_MBX_H_ */

View file

@ -4178,35 +4178,6 @@ struct ixgbe_phy_info {
#include "ixgbe_mbx.h"
struct ixgbe_mbx_operations {
void (*init_params)(struct ixgbe_hw *hw);
s32 (*read)(struct ixgbe_hw *, u32 *, u16, u16);
s32 (*write)(struct ixgbe_hw *, u32 *, u16, u16);
s32 (*read_posted)(struct ixgbe_hw *, u32 *, u16, u16);
s32 (*write_posted)(struct ixgbe_hw *, u32 *, u16, u16);
s32 (*check_for_msg)(struct ixgbe_hw *, u16);
s32 (*check_for_ack)(struct ixgbe_hw *, u16);
s32 (*check_for_rst)(struct ixgbe_hw *, u16);
};
struct ixgbe_mbx_stats {
u32 msgs_tx;
u32 msgs_rx;
u32 acks;
u32 reqs;
u32 rsts;
};
struct ixgbe_mbx_info {
struct ixgbe_mbx_operations ops;
struct ixgbe_mbx_stats stats;
u32 timeout;
u32 usec_delay;
u32 v2p_mailbox;
u16 size;
};
struct ixgbe_hw {
u8 IOMEM *hw_addr;
void *back;
@ -4277,6 +4248,9 @@ struct ixgbe_hw {
#define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38
#define IXGBE_ERR_FW_RESP_INVALID -39
#define IXGBE_ERR_TOKEN_RETRY -40
#define IXGBE_ERR_MBX -41
#define IXGBE_ERR_MBX_NOMSG -42
#define IXGBE_ERR_TIMEOUT -43
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF

View file

@ -49,6 +49,8 @@
**/
s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
{
u16 i;
/* MAC */
hw->mac.ops.init_hw = ixgbe_init_hw_vf;
hw->mac.ops.reset_hw = ixgbe_reset_hw_vf;
@ -82,7 +84,8 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
hw->mac.max_tx_queues = 1;
hw->mac.max_rx_queues = 1;
hw->mbx.ops.init_params = ixgbe_init_mbx_params_vf;
for (i = 0; i < 64; i++)
hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_vf;
return IXGBE_SUCCESS;
}
@ -185,6 +188,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
/* reset the api version */
hw->api_version = ixgbe_mbox_api_10;
ixgbe_init_mbx_params_vf(hw);
DEBUGOUT("Issuing a function level reset to MAC\n");
@ -194,7 +198,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
msec_delay(50);
/* we cannot reset while the RSTI / RSTD bits are asserted */
while (!mbx->ops.check_for_rst(hw, 0) && timeout) {
while (!mbx->ops[0].check_for_rst(hw, 0) && timeout) {
timeout--;
usec_delay(5);
}
@ -209,7 +213,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
msgbuf[0] = IXGBE_VF_RESET;
mbx->ops.write_posted(hw, msgbuf, 1, 0);
ixgbe_write_mbx(hw, msgbuf, 1, 0);
msec_delay(10);
@ -218,8 +222,8 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
* also set up the mc_filter_type which is piggy backed
* on the mac address in word 3
*/
ret_val = mbx->ops.read_posted(hw, msgbuf,
IXGBE_VF_PERMADDR_MSG_LEN, 0);
ret_val = ixgbe_poll_mbx(hw, msgbuf,
IXGBE_VF_PERMADDR_MSG_LEN, 0);
if (ret_val)
return ret_val;
@ -324,13 +328,12 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
static s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,
u32 *retmsg, u16 size)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
s32 retval = ixgbe_write_mbx(hw, msg, size, 0);
if (retval)
return retval;
return mbx->ops.read_posted(hw, retmsg, size, 0);
return ixgbe_poll_mbx(hw, retmsg, size, 0);
}
/**
@ -380,7 +383,6 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count, ixgbe_mc_addr_itr next,
bool clear)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
u16 *vector_list = (u16 *)&msgbuf[1];
u32 vector;
@ -412,7 +414,7 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
vector_list[i] = (u16)vector;
}
return mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0);
return ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, IXGBE_VFMAILBOX_SIZE);
}
/**
@ -434,6 +436,7 @@ s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
/* Fall through */
case ixgbe_mbox_api_13:
case ixgbe_mbox_api_15:
break;
default:
return IXGBE_ERR_FEATURE_NOT_SUPPORTED;
@ -608,12 +611,13 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
struct ixgbe_mbx_info *mbx = &hw->mbx;
struct ixgbe_mac_info *mac = &hw->mac;
s32 ret_val = IXGBE_SUCCESS;
u32 links_reg;
u32 in_msg = 0;
u32 links_reg;
UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
/* If we were hit with a reset drop the link */
if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)
if (!mbx->ops[0].check_for_rst(hw, 0) || !mbx->timeout)
mac->get_link_status = true;
if (!mac->get_link_status)
@ -670,21 +674,22 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
/* if the read failed it could just be a mailbox collision, best wait
* until we are called again and don't report an error
*/
if (mbx->ops.read(hw, &in_msg, 1, 0))
if (ixgbe_read_mbx(hw, &in_msg, 1, 0)) {
if (hw->api_version >= ixgbe_mbox_api_15)
mac->get_link_status = false;
goto out;
}
if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {
/* msg is not CTS and is FAILURE,
* we must have lost CTS status.
*/
/* msg is not CTS and is FAILURE we must have lost CTS status */
if (in_msg & IXGBE_VT_MSGTYPE_FAILURE)
ret_val = -1;
ret_val = IXGBE_ERR_MBX;
goto out;
}
/* the pf is talking, if we timed out in the past we reinit */
if (!mbx->timeout) {
ret_val = -1;
ret_val = IXGBE_ERR_TIMEOUT;
goto out;
}
@ -763,6 +768,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
case ixgbe_mbox_api_11:
case ixgbe_mbox_api_12:
case ixgbe_mbox_api_13:
case ixgbe_mbox_api_15:
break;
default:
return 0;

View file

@ -62,6 +62,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
struct ixgbe_phy_info *phy = &hw->phy;
struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
s32 ret_val;
u16 i;
DEBUGFUNC("ixgbe_init_ops_X540");
@ -145,7 +146,8 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))
& IXGBE_FWSM_MODE_MASK);
hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
for (i = 0; i < 64; i++)
hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf;
/* LEDs */
mac->ops.blink_led_start = ixgbe_blink_led_start_X540;