Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2024-11-05 (ice, ixgbe, igc. igb, igbvf, e1000)

For ice:

Mateusz refactors and adds additional SerDes configuration values to be
output.

Przemek refactors processing of DDP and adds support for a flag field in
the DDP's signature segment header.

Joe Damato adds support for persistent NAPI config.

Brett adjusts setting of Tx promiscuous based on unicast/multicast
setting.

Jake moves setting of pf->supported_rxdids to occur directly after DDP
load and changes a small struct to use stack memory.

Frederic Weisbecker adds WQ_UNBOUND flag to the workqueue.

For ixgbe:

Diomidis Spinellis removes a circular dependency.

For igc:

Vitaly removes an unneeded autoneg parameter.

For igb:

Johnny Park fixes a couple of typos.

For igbvf:

Wander Lairson Costa removes an unused spinlock.

For e1000:

Joe Damato adds RTNL lock to some calls where it is expected to be held.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  e1000: Hold RTNL when e1000_down can be called
  igbvf: remove unused spinlock
  igb: Fix 2 typos in comments in igb_main.c
  igc: remove autoneg parameter from igc_mac_info
  ixgbe: Break include dependency cycle
  ice: Unbind the workqueue
  ice: use stack variable for virtchnl_supported_rxdids
  ice: initialize pf->supported_rxdids immediately after loading DDP
  ice: only allow Tx promiscuous for multicast
  ice: Add support for persistent NAPI config
  ice: support optional flags in signature segment header
  ice: refactor "last" segment of DDP pkg
  ice: extend dump serdes equalizer values feature
  ice: rework of dump serdes equalizer values feature
====================

Link: https://patch.msgid.link/20241113185431.1289708-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-11-15 18:21:34 -08:00
commit 1c9786163b
27 changed files with 513 additions and 481 deletions

View File

@ -3509,7 +3509,9 @@ static void e1000_reset_task(struct work_struct *work)
container_of(work, struct e1000_adapter, reset_task);
e_err(drv, "Reset adapter\n");
rtnl_lock();
e1000_reinit_locked(adapter);
rtnl_unlock();
}
/**
@ -5074,7 +5076,9 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
usleep_range(10000, 20000);
WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
rtnl_lock();
e1000_down(adapter);
rtnl_unlock();
}
status = er32(STATUS);
@ -5235,16 +5239,20 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
rtnl_lock();
netif_device_detach(netdev);
if (state == pci_channel_io_perm_failure)
if (state == pci_channel_io_perm_failure) {
rtnl_unlock();
return PCI_ERS_RESULT_DISCONNECT;
}
if (netif_running(netdev))
e1000_down(adapter);
if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags))
pci_disable_device(pdev);
rtnl_unlock();
/* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;

View File

@ -181,11 +181,9 @@
#define ice_for_each_chnl_tc(i) \
for ((i) = ICE_CHNL_START_TC; (i) < ICE_CHNL_MAX_TC; (i)++)
#define ICE_UCAST_PROMISC_BITS (ICE_PROMISC_UCAST_TX | ICE_PROMISC_UCAST_RX)
#define ICE_UCAST_PROMISC_BITS ICE_PROMISC_UCAST_RX
#define ICE_UCAST_VLAN_PROMISC_BITS (ICE_PROMISC_UCAST_TX | \
ICE_PROMISC_UCAST_RX | \
ICE_PROMISC_VLAN_TX | \
#define ICE_UCAST_VLAN_PROMISC_BITS (ICE_PROMISC_UCAST_RX | \
ICE_PROMISC_VLAN_RX)
#define ICE_MCAST_PROMISC_BITS (ICE_PROMISC_MCAST_TX | ICE_PROMISC_MCAST_RX)

View File

@ -1492,6 +1492,23 @@ struct ice_aqc_dnl_equa_param {
#define ICE_AQC_RX_EQU_BFLF (0x13 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_BFHF (0x14 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DRATE (0x15 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_CTLE_GAINHF (0x20 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_CTLE_GAINLF (0x21 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_CTLE_GAINDC (0x22 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_CTLE_BW (0x23 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_GAIN (0x30 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_GAIN2 (0x31 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_2 (0x32 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_3 (0x33 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_4 (0x34 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_5 (0x35 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_6 (0x36 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_7 (0x37 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_8 (0x38 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_9 (0x39 << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_10 (0x3A << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_11 (0x3B << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_RX_EQU_DFE_12 (0x3C << ICE_AQC_RX_EQU_SHIFT)
#define ICE_AQC_TX_EQU_PRE1 0x0
#define ICE_AQC_TX_EQU_PRE3 0x3
#define ICE_AQC_TX_EQU_ATTEN 0x4

View File

@ -156,7 +156,8 @@ static int ice_vsi_alloc_q_vector(struct ice_vsi *vsi, u16 v_idx)
* handler here (i.e. resume, reset/rebuild, etc.)
*/
if (vsi->netdev)
netif_napi_add(vsi->netdev, &q_vector->napi, ice_napi_poll);
netif_napi_add_config(vsi->netdev, &q_vector->napi,
ice_napi_poll, v_idx);
out:
/* tie q_vector and VSI together */

View File

@ -1210,6 +1210,131 @@ ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
return status;
}
/**
* ice_is_buffer_metadata - determine if package buffer is a metadata buffer
* @buf: pointer to buffer header
* Return: whether given @buf is a metadata one.
*/
static bool ice_is_buffer_metadata(struct ice_buf_hdr *buf)
{
return le32_to_cpu(buf->section_entry[0].type) & ICE_METADATA_BUF;
}
/**
* struct ice_ddp_send_ctx - sending context of current DDP segment
* @hw: pointer to the hardware struct
*
* Keeps current sending state (header, error) for the purpose of proper "last"
* bit setting in ice_aq_download_pkg(). Use via calls to ice_ddp_send_hunk().
*/
struct ice_ddp_send_ctx {
struct ice_hw *hw;
/* private: only for ice_ddp_send_hunk() */
struct ice_buf_hdr *hdr;
int err;
};
static void ice_ddp_send_ctx_set_err(struct ice_ddp_send_ctx *ctx, int err)
{
ctx->err = err;
}
/**
* ice_ddp_send_hunk - send one hunk of data to FW
* @ctx: current segment sending context
* @hunk: next hunk to send, size is always ICE_PKG_BUF_SIZE
*
* Send the next hunk of data to FW, retrying if needed.
*
* Notice: must be called once more with a NULL @hunk to finish up; such call
* will set up the "last" bit of an AQ request. After such call @ctx.hdr is
* cleared, @hw is still valid.
*
* Return: %ICE_DDP_PKG_SUCCESS if there were no problems; a sticky @err
* otherwise.
*/
static enum ice_ddp_state ice_ddp_send_hunk(struct ice_ddp_send_ctx *ctx,
struct ice_buf_hdr *hunk)
{
struct ice_buf_hdr *prev_hunk = ctx->hdr;
struct ice_hw *hw = ctx->hw;
bool prev_was_last = !hunk;
enum ice_aq_err aq_err;
u32 offset, info;
int attempt, err;
if (ctx->err)
return ctx->err;
ctx->hdr = hunk;
if (!prev_hunk)
return ICE_DDP_PKG_SUCCESS; /* no problem so far */
for (attempt = 0; attempt < 5; attempt++) {
if (attempt)
msleep(20);
err = ice_aq_download_pkg(hw, prev_hunk, ICE_PKG_BUF_SIZE,
prev_was_last, &offset, &info, NULL);
aq_err = hw->adminq.sq_last_status;
if (aq_err != ICE_AQ_RC_ENOSEC && aq_err != ICE_AQ_RC_EBADSIG)
break;
}
if (err) {
ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n",
err, offset, info);
ctx->err = ice_map_aq_err_to_ddp_state(aq_err);
} else if (attempt) {
dev_dbg(ice_hw_to_dev(hw),
"ice_aq_download_pkg number of retries: %d\n", attempt);
}
return ctx->err;
}
/**
* ice_dwnld_cfg_bufs_no_lock
* @ctx: context of the current buffers section to send
* @bufs: pointer to an array of buffers
* @start: buffer index of first buffer to download
* @count: the number of buffers to download
*
* Downloads package configuration buffers to the firmware. Metadata buffers
* are skipped, and the first metadata buffer found indicates that the rest
* of the buffers are all metadata buffers.
*/
static enum ice_ddp_state
ice_dwnld_cfg_bufs_no_lock(struct ice_ddp_send_ctx *ctx, struct ice_buf *bufs,
u32 start, u32 count)
{
struct ice_buf_hdr *bh;
enum ice_ddp_state err;
if (!bufs || !count) {
ice_ddp_send_ctx_set_err(ctx, ICE_DDP_PKG_ERR);
return ICE_DDP_PKG_ERR;
}
bufs += start;
for (int i = 0; i < count; i++, bufs++) {
bh = (struct ice_buf_hdr *)bufs;
/* Metadata buffers should not be sent to FW,
* their presence means "we are done here".
*/
if (ice_is_buffer_metadata(bh))
break;
err = ice_ddp_send_hunk(ctx, bh);
if (err)
return err;
}
return 0;
}
/**
* ice_get_pkg_seg_by_idx
* @pkg_hdr: pointer to the package header to be searched
@ -1269,137 +1394,21 @@ ice_is_signing_seg_type_at_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx,
return false;
}
/**
* ice_is_buffer_metadata - determine if package buffer is a metadata buffer
* @buf: pointer to buffer header
*/
static bool ice_is_buffer_metadata(struct ice_buf_hdr *buf)
{
if (le32_to_cpu(buf->section_entry[0].type) & ICE_METADATA_BUF)
return true;
return false;
}
/**
* ice_is_last_download_buffer
* @buf: pointer to current buffer header
* @idx: index of the buffer in the current sequence
* @count: the buffer count in the current sequence
*
* Note: this routine should only be called if the buffer is not the last buffer
*/
static bool
ice_is_last_download_buffer(struct ice_buf_hdr *buf, u32 idx, u32 count)
{
struct ice_buf *next_buf;
if ((idx + 1) == count)
return true;
/* A set metadata flag in the next buffer will signal that the current
* buffer will be the last buffer downloaded
*/
next_buf = ((struct ice_buf *)buf) + 1;
return ice_is_buffer_metadata((struct ice_buf_hdr *)next_buf);
}
/**
* ice_dwnld_cfg_bufs_no_lock
* @hw: pointer to the hardware structure
* @bufs: pointer to an array of buffers
* @start: buffer index of first buffer to download
* @count: the number of buffers to download
* @indicate_last: if true, then set last buffer flag on last buffer download
*
* Downloads package configuration buffers to the firmware. Metadata buffers
* are skipped, and the first metadata buffer found indicates that the rest
* of the buffers are all metadata buffers.
*/
static enum ice_ddp_state
ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start,
u32 count, bool indicate_last)
{
enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;
struct ice_buf_hdr *bh;
enum ice_aq_err err;
u32 offset, info, i;
if (!bufs || !count)
return ICE_DDP_PKG_ERR;
/* If the first buffer's first section has its metadata bit set
* then there are no buffers to be downloaded, and the operation is
* considered a success.
*/
bh = (struct ice_buf_hdr *)(bufs + start);
if (le32_to_cpu(bh->section_entry[0].type) & ICE_METADATA_BUF)
return ICE_DDP_PKG_SUCCESS;
for (i = 0; i < count; i++) {
bool last = false;
int try_cnt = 0;
int status;
bh = (struct ice_buf_hdr *)(bufs + start + i);
if (indicate_last)
last = ice_is_last_download_buffer(bh, i, count);
while (1) {
status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE,
last, &offset, &info,
NULL);
if (hw->adminq.sq_last_status != ICE_AQ_RC_ENOSEC &&
hw->adminq.sq_last_status != ICE_AQ_RC_EBADSIG)
break;
try_cnt++;
if (try_cnt == 5)
break;
msleep(20);
}
if (try_cnt)
dev_dbg(ice_hw_to_dev(hw),
"ice_aq_download_pkg number of retries: %d\n",
try_cnt);
/* Save AQ status from download package */
if (status) {
ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n",
status, offset, info);
err = hw->adminq.sq_last_status;
state = ice_map_aq_err_to_ddp_state(err);
break;
}
if (last)
break;
}
return state;
}
/**
* ice_download_pkg_sig_seg - download a signature segment
* @hw: pointer to the hardware structure
* @ctx: context of the current buffers section to send
* @seg: pointer to signature segment
*/
static enum ice_ddp_state
ice_download_pkg_sig_seg(struct ice_hw *hw, struct ice_sign_seg *seg)
ice_download_pkg_sig_seg(struct ice_ddp_send_ctx *ctx, struct ice_sign_seg *seg)
{
return ice_dwnld_cfg_bufs_no_lock(hw, seg->buf_tbl.buf_array, 0,
le32_to_cpu(seg->buf_tbl.buf_count),
false);
return ice_dwnld_cfg_bufs_no_lock(ctx, seg->buf_tbl.buf_array, 0,
le32_to_cpu(seg->buf_tbl.buf_count));
}
/**
* ice_download_pkg_config_seg - download a config segment
* @hw: pointer to the hardware structure
* @ctx: context of the current buffers section to send
* @pkg_hdr: pointer to package header
* @idx: segment index
* @start: starting buffer
@ -1408,8 +1417,9 @@ ice_download_pkg_sig_seg(struct ice_hw *hw, struct ice_sign_seg *seg)
* Note: idx must reference a ICE segment
*/
static enum ice_ddp_state
ice_download_pkg_config_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,
u32 idx, u32 start, u32 count)
ice_download_pkg_config_seg(struct ice_ddp_send_ctx *ctx,
struct ice_pkg_hdr *pkg_hdr, u32 idx, u32 start,
u32 count)
{
struct ice_buf_table *bufs;
struct ice_seg *seg;
@ -1425,46 +1435,56 @@ ice_download_pkg_config_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,
if (start >= buf_count || start + count > buf_count)
return ICE_DDP_PKG_ERR;
return ice_dwnld_cfg_bufs_no_lock(hw, bufs->buf_array, start, count,
true);
return ice_dwnld_cfg_bufs_no_lock(ctx, bufs->buf_array, start, count);
}
static bool ice_is_last_sign_seg(u32 flags)
{
return !(flags & ICE_SIGN_SEG_FLAGS_VALID) || /* behavior prior to valid */
(flags & ICE_SIGN_SEG_FLAGS_LAST);
}
/**
* ice_dwnld_sign_and_cfg_segs - download a signing segment and config segment
* @hw: pointer to the hardware structure
* @ctx: context of the current buffers section to send
* @pkg_hdr: pointer to package header
* @idx: segment index (must be a signature segment)
*
* Note: idx must reference a signature segment
*/
static enum ice_ddp_state
ice_dwnld_sign_and_cfg_segs(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,
u32 idx)
ice_dwnld_sign_and_cfg_segs(struct ice_ddp_send_ctx *ctx,
struct ice_pkg_hdr *pkg_hdr, u32 idx)
{
u32 conf_idx, start, count, flags;
enum ice_ddp_state state;
struct ice_sign_seg *seg;
u32 conf_idx;
u32 start;
u32 count;
seg = (struct ice_sign_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);
if (!seg) {
state = ICE_DDP_PKG_ERR;
goto exit;
ice_ddp_send_ctx_set_err(ctx, state);
return state;
}
count = le32_to_cpu(seg->signed_buf_count);
state = ice_download_pkg_sig_seg(hw, seg);
state = ice_download_pkg_sig_seg(ctx, seg);
if (state || !count)
goto exit;
return state;
conf_idx = le32_to_cpu(seg->signed_seg_idx);
start = le32_to_cpu(seg->signed_buf_start);
state = ice_download_pkg_config_seg(hw, pkg_hdr, conf_idx, start,
state = ice_download_pkg_config_seg(ctx, pkg_hdr, conf_idx, start,
count);
exit:
/* finish up by sending last hunk with "last" flag set if requested by
* DDP content
*/
flags = le32_to_cpu(seg->flags);
if (ice_is_last_sign_seg(flags))
state = ice_ddp_send_hunk(ctx, NULL);
return state;
}
@ -1519,6 +1539,7 @@ ice_download_pkg_with_sig_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
{
enum ice_aq_err aq_err = hw->adminq.sq_last_status;
enum ice_ddp_state state = ICE_DDP_PKG_ERR;
struct ice_ddp_send_ctx ctx = { .hw = hw };
int status;
u32 i;
@ -1539,7 +1560,7 @@ ice_download_pkg_with_sig_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
hw->pkg_sign_type))
continue;
state = ice_dwnld_sign_and_cfg_segs(hw, pkg_hdr, i);
state = ice_dwnld_sign_and_cfg_segs(&ctx, pkg_hdr, i);
if (state)
break;
}
@ -1564,6 +1585,7 @@ ice_download_pkg_with_sig_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
static enum ice_ddp_state
ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
{
struct ice_ddp_send_ctx ctx = { .hw = hw };
enum ice_ddp_state state;
struct ice_buf_hdr *bh;
int status;
@ -1576,7 +1598,7 @@ ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
* considered a success.
*/
bh = (struct ice_buf_hdr *)bufs;
if (le32_to_cpu(bh->section_entry[0].type) & ICE_METADATA_BUF)
if (ice_is_buffer_metadata(bh))
return ICE_DDP_PKG_SUCCESS;
status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);
@ -1586,7 +1608,9 @@ ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
return ice_map_aq_err_to_ddp_state(hw->adminq.sq_last_status);
}
state = ice_dwnld_cfg_bufs_no_lock(hw, bufs, 0, count, true);
ice_dwnld_cfg_bufs_no_lock(&ctx, bufs, 0, count);
/* finish up by sending last hunk with "last" flag set */
state = ice_ddp_send_hunk(&ctx, NULL);
if (!state)
state = ice_post_dwnld_pkg_actions(hw);

View File

@ -181,7 +181,10 @@ struct ice_sign_seg {
__le32 signed_seg_idx;
__le32 signed_buf_start;
__le32 signed_buf_count;
#define ICE_SIGN_SEG_RESERVED_COUNT 44
#define ICE_SIGN_SEG_FLAGS_VALID 0x80000000
#define ICE_SIGN_SEG_FLAGS_LAST 0x00000001
__le32 flags;
#define ICE_SIGN_SEG_RESERVED_COUNT 40
u8 reserved[ICE_SIGN_SEG_RESERVED_COUNT];
struct ice_buf_table buf_tbl;
};

View File

@ -693,75 +693,53 @@ static int ice_get_port_topology(struct ice_hw *hw, u8 lport,
static int ice_get_tx_rx_equa(struct ice_hw *hw, u8 serdes_num,
struct ice_serdes_equalization_to_ethtool *ptr)
{
static const int tx = ICE_AQC_OP_CODE_TX_EQU;
static const int rx = ICE_AQC_OP_CODE_RX_EQU;
struct {
int data_in;
int opcode;
int *out;
} aq_params[] = {
{ ICE_AQC_TX_EQU_PRE1, tx, &ptr->tx_equ_pre1 },
{ ICE_AQC_TX_EQU_PRE3, tx, &ptr->tx_equ_pre3 },
{ ICE_AQC_TX_EQU_ATTEN, tx, &ptr->tx_equ_atten },
{ ICE_AQC_TX_EQU_POST1, tx, &ptr->tx_equ_post1 },
{ ICE_AQC_TX_EQU_PRE2, tx, &ptr->tx_equ_pre2 },
{ ICE_AQC_RX_EQU_PRE2, rx, &ptr->rx_equ_pre2 },
{ ICE_AQC_RX_EQU_PRE1, rx, &ptr->rx_equ_pre1 },
{ ICE_AQC_RX_EQU_POST1, rx, &ptr->rx_equ_post1 },
{ ICE_AQC_RX_EQU_BFLF, rx, &ptr->rx_equ_bflf },
{ ICE_AQC_RX_EQU_BFHF, rx, &ptr->rx_equ_bfhf },
{ ICE_AQC_RX_EQU_DRATE, rx, &ptr->rx_equ_drate },
{ ICE_AQC_RX_EQU_CTLE_GAINHF, rx, &ptr->rx_equ_ctle_gainhf },
{ ICE_AQC_RX_EQU_CTLE_GAINLF, rx, &ptr->rx_equ_ctle_gainlf },
{ ICE_AQC_RX_EQU_CTLE_GAINDC, rx, &ptr->rx_equ_ctle_gaindc },
{ ICE_AQC_RX_EQU_CTLE_BW, rx, &ptr->rx_equ_ctle_bw },
{ ICE_AQC_RX_EQU_DFE_GAIN, rx, &ptr->rx_equ_dfe_gain },
{ ICE_AQC_RX_EQU_DFE_GAIN2, rx, &ptr->rx_equ_dfe_gain_2 },
{ ICE_AQC_RX_EQU_DFE_2, rx, &ptr->rx_equ_dfe_2 },
{ ICE_AQC_RX_EQU_DFE_3, rx, &ptr->rx_equ_dfe_3 },
{ ICE_AQC_RX_EQU_DFE_4, rx, &ptr->rx_equ_dfe_4 },
{ ICE_AQC_RX_EQU_DFE_5, rx, &ptr->rx_equ_dfe_5 },
{ ICE_AQC_RX_EQU_DFE_6, rx, &ptr->rx_equ_dfe_6 },
{ ICE_AQC_RX_EQU_DFE_7, rx, &ptr->rx_equ_dfe_7 },
{ ICE_AQC_RX_EQU_DFE_8, rx, &ptr->rx_equ_dfe_8 },
{ ICE_AQC_RX_EQU_DFE_9, rx, &ptr->rx_equ_dfe_9 },
{ ICE_AQC_RX_EQU_DFE_10, rx, &ptr->rx_equ_dfe_10 },
{ ICE_AQC_RX_EQU_DFE_11, rx, &ptr->rx_equ_dfe_11 },
{ ICE_AQC_RX_EQU_DFE_12, rx, &ptr->rx_equ_dfe_12 },
};
int err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_TX_EQU_PRE1,
ICE_AQC_OP_CODE_TX_EQU, serdes_num,
&ptr->tx_equalization_pre1);
if (err)
return err;
for (int i = 0; i < ARRAY_SIZE(aq_params); i++) {
err = ice_aq_get_phy_equalization(hw, aq_params[i].data_in,
aq_params[i].opcode,
serdes_num, aq_params[i].out);
if (err)
break;
}
err = ice_aq_get_phy_equalization(hw, ICE_AQC_TX_EQU_PRE3,
ICE_AQC_OP_CODE_TX_EQU, serdes_num,
&ptr->tx_equalization_pre3);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_TX_EQU_ATTEN,
ICE_AQC_OP_CODE_TX_EQU, serdes_num,
&ptr->tx_equalization_atten);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_TX_EQU_POST1,
ICE_AQC_OP_CODE_TX_EQU, serdes_num,
&ptr->tx_equalization_post1);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_TX_EQU_PRE2,
ICE_AQC_OP_CODE_TX_EQU, serdes_num,
&ptr->tx_equalization_pre2);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_RX_EQU_PRE2,
ICE_AQC_OP_CODE_RX_EQU, serdes_num,
&ptr->rx_equalization_pre2);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_RX_EQU_PRE1,
ICE_AQC_OP_CODE_RX_EQU, serdes_num,
&ptr->rx_equalization_pre1);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_RX_EQU_POST1,
ICE_AQC_OP_CODE_RX_EQU, serdes_num,
&ptr->rx_equalization_post1);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_RX_EQU_BFLF,
ICE_AQC_OP_CODE_RX_EQU, serdes_num,
&ptr->rx_equalization_bflf);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_RX_EQU_BFHF,
ICE_AQC_OP_CODE_RX_EQU, serdes_num,
&ptr->rx_equalization_bfhf);
if (err)
return err;
err = ice_aq_get_phy_equalization(hw, ICE_AQC_RX_EQU_DRATE,
ICE_AQC_OP_CODE_RX_EQU, serdes_num,
&ptr->rx_equalization_drate);
if (err)
return err;
return 0;
return err;
}
/**

View File

@ -10,17 +10,34 @@ struct ice_phy_type_to_ethtool {
};
struct ice_serdes_equalization_to_ethtool {
int rx_equalization_pre2;
int rx_equalization_pre1;
int rx_equalization_post1;
int rx_equalization_bflf;
int rx_equalization_bfhf;
int rx_equalization_drate;
int tx_equalization_pre1;
int tx_equalization_pre3;
int tx_equalization_atten;
int tx_equalization_post1;
int tx_equalization_pre2;
int rx_equ_pre2;
int rx_equ_pre1;
int rx_equ_post1;
int rx_equ_bflf;
int rx_equ_bfhf;
int rx_equ_drate;
int rx_equ_ctle_gainhf;
int rx_equ_ctle_gainlf;
int rx_equ_ctle_gaindc;
int rx_equ_ctle_bw;
int rx_equ_dfe_gain;
int rx_equ_dfe_gain_2;
int rx_equ_dfe_2;
int rx_equ_dfe_3;
int rx_equ_dfe_4;
int rx_equ_dfe_5;
int rx_equ_dfe_6;
int rx_equ_dfe_7;
int rx_equ_dfe_8;
int rx_equ_dfe_9;
int rx_equ_dfe_10;
int rx_equ_dfe_11;
int rx_equ_dfe_12;
int tx_equ_pre1;
int tx_equ_pre3;
int tx_equ_atten;
int tx_equ_post1;
int tx_equ_pre2;
};
struct ice_regdump_to_ethtool {

View File

@ -2777,8 +2777,10 @@ void ice_napi_add(struct ice_vsi *vsi)
return;
ice_for_each_q_vector(vsi, v_idx)
netif_napi_add(vsi->netdev, &vsi->q_vectors[v_idx]->napi,
ice_napi_poll);
netif_napi_add_config(vsi->netdev,
&vsi->q_vectors[v_idx]->napi,
ice_napi_poll,
v_idx);
}
/**

View File

@ -4554,6 +4554,34 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
return 0;
}
/**
* ice_init_supported_rxdids - Initialize supported Rx descriptor IDs
* @hw: pointer to the hardware structure
* @pf: pointer to pf structure
*
* The pf->supported_rxdids bitmap is used to indicate to VFs which descriptor
* formats the PF hardware supports. The exact list of supported RXDIDs
* depends on the loaded DDP package. The IDs can be determined by reading the
* GLFLXP_RXDID_FLAGS register after the DDP package is loaded.
*
* Note that the legacy 32-byte RXDID 0 is always supported but is not listed
* in the DDP package. The 16-byte legacy descriptor is never supported by
* VFs.
*/
static void ice_init_supported_rxdids(struct ice_hw *hw, struct ice_pf *pf)
{
pf->supported_rxdids = BIT(ICE_RXDID_LEGACY_1);
for (int i = ICE_RXDID_FLEX_NIC; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) {
u32 regval;
regval = rd32(hw, GLFLXP_RXDID_FLAGS(i, 0));
if ((regval >> GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S)
& GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M)
pf->supported_rxdids |= BIT(i);
}
}
/**
* ice_init_ddp_config - DDP related configuration
* @hw: pointer to the hardware structure
@ -4588,6 +4616,9 @@ static int ice_init_ddp_config(struct ice_hw *hw, struct ice_pf *pf)
ice_load_pkg(firmware, pf);
release_firmware(firmware);
/* Initialize the supported Rx descriptor IDs after loading DDP */
ice_init_supported_rxdids(hw, pf);
return 0;
}
@ -5900,7 +5931,7 @@ static int __init ice_module_init(void)
ice_adv_lnk_speed_maps_init();
ice_wq = alloc_workqueue("%s", 0, 0, KBUILD_MODNAME);
ice_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, KBUILD_MODNAME);
if (!ice_wq) {
pr_err("Failed to create workqueue\n");
return status;

View File

@ -2554,17 +2554,27 @@ static bool ice_is_vlan_promisc_allowed(struct ice_vf *vf)
/**
* ice_vf_ena_vlan_promisc - Enable Tx/Rx VLAN promiscuous for the VLAN
* @vf: VF to enable VLAN promisc on
* @vsi: VF's VSI used to enable VLAN promiscuous mode
* @vlan: VLAN used to enable VLAN promiscuous
*
* This function should only be called if VLAN promiscuous mode is allowed,
* which can be determined via ice_is_vlan_promisc_allowed().
*/
static int ice_vf_ena_vlan_promisc(struct ice_vsi *vsi, struct ice_vlan *vlan)
static int ice_vf_ena_vlan_promisc(struct ice_vf *vf, struct ice_vsi *vsi,
struct ice_vlan *vlan)
{
u8 promisc_m = ICE_PROMISC_VLAN_TX | ICE_PROMISC_VLAN_RX;
u8 promisc_m = 0;
int status;
if (test_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
promisc_m |= ICE_UCAST_VLAN_PROMISC_BITS;
if (test_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
promisc_m |= ICE_MCAST_VLAN_PROMISC_BITS;
if (!promisc_m)
return 0;
status = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx, promisc_m,
vlan->vid);
if (status && status != -EEXIST)
@ -2583,7 +2593,7 @@ static int ice_vf_ena_vlan_promisc(struct ice_vsi *vsi, struct ice_vlan *vlan)
*/
static int ice_vf_dis_vlan_promisc(struct ice_vsi *vsi, struct ice_vlan *vlan)
{
u8 promisc_m = ICE_PROMISC_VLAN_TX | ICE_PROMISC_VLAN_RX;
u8 promisc_m = ICE_UCAST_VLAN_PROMISC_BITS | ICE_MCAST_VLAN_PROMISC_BITS;
int status;
status = ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx, promisc_m,
@ -2738,7 +2748,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
goto error_param;
}
} else if (vlan_promisc) {
status = ice_vf_ena_vlan_promisc(vsi, &vlan);
status = ice_vf_ena_vlan_promisc(vf, vsi, &vlan);
if (status) {
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
dev_err(dev, "Enable Unicast/multicast promiscuous mode on VLAN ID:%d failed error-%d\n",
@ -3021,12 +3031,8 @@ static int ice_vc_set_rss_hena(struct ice_vf *vf, u8 *msg)
static int ice_vc_query_rxdid(struct ice_vf *vf)
{
enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
struct virtchnl_supported_rxdids *rxdid = NULL;
struct ice_hw *hw = &vf->pf->hw;
struct virtchnl_supported_rxdids rxdid = {};
struct ice_pf *pf = vf->pf;
int len = 0;
int ret, i;
u32 regval;
if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
@ -3038,35 +3044,11 @@ static int ice_vc_query_rxdid(struct ice_vf *vf)
goto err;
}
len = sizeof(struct virtchnl_supported_rxdids);
rxdid = kzalloc(len, GFP_KERNEL);
if (!rxdid) {
v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY;
len = 0;
goto err;
}
/* RXDIDs supported by DDP package can be read from the register
* to get the supported RXDID bitmap. But the legacy 32byte RXDID
* is not listed in DDP package, add it in the bitmap manually.
* Legacy 16byte descriptor is not supported.
*/
rxdid->supported_rxdids |= BIT(ICE_RXDID_LEGACY_1);
for (i = ICE_RXDID_FLEX_NIC; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) {
regval = rd32(hw, GLFLXP_RXDID_FLAGS(i, 0));
if ((regval >> GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S)
& GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M)
rxdid->supported_rxdids |= BIT(i);
}
pf->supported_rxdids = rxdid->supported_rxdids;
rxdid.supported_rxdids = pf->supported_rxdids;
err:
ret = ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_SUPPORTED_RXDIDS,
v_ret, (u8 *)rxdid, len);
kfree(rxdid);
return ret;
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_SUPPORTED_RXDIDS,
v_ret, (u8 *)&rxdid, sizeof(rxdid));
}
/**
@ -3575,7 +3557,7 @@ ice_vc_add_vlans(struct ice_vf *vf, struct ice_vsi *vsi,
return err;
if (vlan_promisc) {
err = ice_vf_ena_vlan_promisc(vsi, &vlan);
err = ice_vf_ena_vlan_promisc(vf, vsi, &vlan);
if (err)
return err;
}
@ -3603,7 +3585,8 @@ ice_vc_add_vlans(struct ice_vf *vf, struct ice_vsi *vsi,
*/
if (!ice_is_dvm_ena(&vsi->back->hw)) {
if (vlan_promisc) {
err = ice_vf_ena_vlan_promisc(vsi, &vlan);
err = ice_vf_ena_vlan_promisc(vf, vsi,
&vlan);
if (err)
return err;
}

View File

@ -1204,7 +1204,7 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
/* initialize pointer to rings */
ring = q_vector->ring;
/* intialize ITR */
/* initialize ITR */
if (rxr_count) {
/* rx or rx/tx vector */
if (!adapter->rx_itr_setting || adapter->rx_itr_setting > 3)
@ -3906,7 +3906,7 @@ static void igb_remove(struct pci_dev *pdev)
*
* This function initializes the vf specific data storage and then attempts to
* allocate the VFs. The reason for ordering it this way is because it is much
* mor expensive time wise to disable SR-IOV than it is to allocate and free
* more expensive time wise to disable SR-IOV than it is to allocate and free
* the memory for the VFs.
**/
static void igb_probe_vfs(struct igb_adapter *adapter)

View File

@ -169,8 +169,6 @@ struct igbvf_adapter {
u16 link_speed;
u16 link_duplex;
spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
/* track device up/down/testing state */
unsigned long state;
@ -220,7 +218,6 @@ struct igbvf_adapter {
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
spinlock_t stats_lock; /* prevent concurrent stats updates */
/* structs defined in e1000_hw.h */
struct e1000_hw hw;

View File

@ -1656,12 +1656,9 @@ static int igbvf_sw_init(struct igbvf_adapter *adapter)
if (igbvf_alloc_queues(adapter))
return -ENOMEM;
spin_lock_init(&adapter->tx_queue_lock);
/* Explicitly disable IRQ since the NIC can be in any state. */
igbvf_irq_disable(adapter);
spin_lock_init(&adapter->stats_lock);
spin_lock_init(&adapter->hw.mbx_lock);
set_bit(__IGBVF_DOWN, &adapter->state);

View File

@ -173,8 +173,7 @@ bool igc_link_test(struct igc_adapter *adapter, u64 *data)
*data = 0;
/* add delay to give enough time for autonegotioation to finish */
if (adapter->hw.mac.autoneg)
ssleep(5);
ssleep(5);
link_up = igc_has_link(adapter);
if (!link_up) {

View File

@ -1821,11 +1821,8 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev,
ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full);
/* set autoneg settings */
if (hw->mac.autoneg == 1) {
ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
ethtool_link_ksettings_add_link_mode(cmd, advertising,
Autoneg);
}
ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
/* Set pause flow control settings */
ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
@ -1878,10 +1875,7 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev,
cmd->base.duplex = DUPLEX_UNKNOWN;
}
cmd->base.speed = speed;
if (hw->mac.autoneg)
cmd->base.autoneg = AUTONEG_ENABLE;
else
cmd->base.autoneg = AUTONEG_DISABLE;
cmd->base.autoneg = AUTONEG_ENABLE;
/* MDI-X => 2; MDI =>1; Invalid =>0 */
if (hw->phy.media_type == igc_media_type_copper)
@ -1955,7 +1949,6 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev,
advertised |= ADVERTISE_10_HALF;
if (cmd->base.autoneg == AUTONEG_ENABLE) {
hw->mac.autoneg = 1;
hw->phy.autoneg_advertised = advertised;
if (adapter->fc_autoneg)
hw->fc.requested_mode = igc_fc_default;

View File

@ -92,7 +92,6 @@ struct igc_mac_info {
bool asf_firmware_present;
bool arc_subsystem_valid;
bool autoneg;
bool autoneg_failed;
bool get_link_status;
};

View File

@ -386,14 +386,6 @@ s32 igc_check_for_copper_link(struct igc_hw *hw)
*/
igc_check_downshift(hw);
/* If we are forcing speed/duplex, then we simply return since
* we have already determined whether we have link or not.
*/
if (!mac->autoneg) {
ret_val = -IGC_ERR_CONFIG;
goto out;
}
/* Auto-Neg is enabled. Auto Speed Detection takes care
* of MAC speed/duplex configuration. So we only need to
* configure Collision Distance in the MAC.
@ -468,173 +460,171 @@ s32 igc_config_fc_after_link_up(struct igc_hw *hw)
goto out;
}
/* Check for the case where we have copper media and auto-neg is
* enabled. In this case, we need to check and see if Auto-Neg
* has completed, and if so, how the PHY and link partner has
* flow control configured.
/* In auto-neg, we need to check and see if Auto-Neg has completed,
* and if so, how the PHY and link partner has flow control
* configured.
*/
if (mac->autoneg) {
/* Read the MII Status Register and check to see if AutoNeg
* has completed. We read this twice because this reg has
* some "sticky" (latched) bits.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
hw_dbg("Copper PHY and Auto Neg has not completed.\n");
goto out;
}
/* Read the MII Status Register and check to see if AutoNeg
* has completed. We read this twice because this reg has
* some "sticky" (latched) bits.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
/* The AutoNeg process has completed, so we now need to
* read both the Auto Negotiation Advertisement
* Register (Address 4) and the Auto_Negotiation Base
* Page Ability Register (Address 5) to determine how
* flow control was negotiated.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
&mii_nway_adv_reg);
if (ret_val)
goto out;
ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
&mii_nway_lp_ability_reg);
if (ret_val)
goto out;
/* Two bits in the Auto Negotiation Advertisement Register
* (Address 4) and two bits in the Auto Negotiation Base
* Page Ability Register (Address 5) determine flow control
* for both the PHY and the link partner. The following
* table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
* 1999, describes these PAUSE resolution bits and how flow
* control is determined based upon these settings.
* NOTE: DC = Don't Care
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
*-------|---------|-------|---------|--------------------
* 0 | 0 | DC | DC | igc_fc_none
* 0 | 1 | 0 | DC | igc_fc_none
* 0 | 1 | 1 | 0 | igc_fc_none
* 0 | 1 | 1 | 1 | igc_fc_tx_pause
* 1 | 0 | 0 | DC | igc_fc_none
* 1 | DC | 1 | DC | igc_fc_full
* 1 | 1 | 0 | 0 | igc_fc_none
* 1 | 1 | 0 | 1 | igc_fc_rx_pause
*
* Are both PAUSE bits set to 1? If so, this implies
* Symmetric Flow Control is enabled at both ends. The
* ASM_DIR bits are irrelevant per the spec.
*
* For Symmetric Flow Control:
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 1 | DC | 1 | DC | IGC_fc_full
*
*/
if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
/* Now we need to check if the user selected RX ONLY
* of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise RX
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
if (hw->fc.requested_mode == igc_fc_full) {
hw->fc.current_mode = igc_fc_full;
hw_dbg("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
}
if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
hw_dbg("Copper PHY and Auto Neg has not completed.\n");
goto out;
}
/* For receiving PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 0 | 1 | 1 | 1 | igc_fc_tx_pause
/* The AutoNeg process has completed, so we now need to
* read both the Auto Negotiation Advertisement
* Register (Address 4) and the Auto_Negotiation Base
* Page Ability Register (Address 5) to determine how
* flow control was negotiated.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
&mii_nway_adv_reg);
if (ret_val)
goto out;
ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
&mii_nway_lp_ability_reg);
if (ret_val)
goto out;
/* Two bits in the Auto Negotiation Advertisement Register
* (Address 4) and two bits in the Auto Negotiation Base
* Page Ability Register (Address 5) determine flow control
* for both the PHY and the link partner. The following
* table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
* 1999, describes these PAUSE resolution bits and how flow
* control is determined based upon these settings.
* NOTE: DC = Don't Care
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
*-------|---------|-------|---------|--------------------
* 0 | 0 | DC | DC | igc_fc_none
* 0 | 1 | 0 | DC | igc_fc_none
* 0 | 1 | 1 | 0 | igc_fc_none
* 0 | 1 | 1 | 1 | igc_fc_tx_pause
* 1 | 0 | 0 | DC | igc_fc_none
* 1 | DC | 1 | DC | igc_fc_full
* 1 | 1 | 0 | 0 | igc_fc_none
* 1 | 1 | 0 | 1 | igc_fc_rx_pause
*
* Are both PAUSE bits set to 1? If so, this implies
* Symmetric Flow Control is enabled at both ends. The
* ASM_DIR bits are irrelevant per the spec.
*
* For Symmetric Flow Control:
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 1 | DC | 1 | DC | IGC_fc_full
*
*/
if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
/* Now we need to check if the user selected RX ONLY
* of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise RX
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = igc_fc_tx_pause;
hw_dbg("Flow Control = TX PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 1 | 1 | 0 | 1 | igc_fc_rx_pause
*/
else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Per the IEEE spec, at this point flow control should be
* disabled. However, we want to consider that we could
* be connected to a legacy switch that doesn't advertise
* desired flow control, but can be forced on the link
* partner. So if we advertised no flow control, that is
* what we will resolve to. If we advertised some kind of
* receive capability (Rx Pause Only or Full Flow Control)
* and the link partner advertised none, we will configure
* ourselves to enable Rx Flow Control only. We can do
* this safely for two reasons: If the link partner really
* didn't want flow control enabled, and we enable Rx, no
* harm done since we won't be receiving any PAUSE frames
* anyway. If the intent on the link partner was to have
* flow control enabled, then by us enabling RX only, we
* can at least receive pause frames and process them.
* This is a good idea because in most cases, since we are
* predominantly a server NIC, more times than not we will
* be asked to delay transmission of packets than asking
* our link partner to pause transmission of frames.
*/
else if ((hw->fc.requested_mode == igc_fc_none) ||
(hw->fc.requested_mode == igc_fc_tx_pause) ||
(hw->fc.strict_ieee)) {
hw->fc.current_mode = igc_fc_none;
hw_dbg("Flow Control = NONE.\n");
if (hw->fc.requested_mode == igc_fc_full) {
hw->fc.current_mode = igc_fc_full;
hw_dbg("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
}
/* Now we need to do one last check... If we auto-
* negotiated to HALF DUPLEX, flow control should not be
* enabled per IEEE 802.3 spec.
*/
ret_val = hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex);
if (ret_val) {
hw_dbg("Error getting link speed and duplex\n");
goto out;
}
/* For receiving PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 0 | 1 | 1 | 1 | igc_fc_tx_pause
*/
else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = igc_fc_tx_pause;
hw_dbg("Flow Control = TX PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 1 | 1 | 0 | 1 | igc_fc_rx_pause
*/
else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Per the IEEE spec, at this point flow control should be
* disabled. However, we want to consider that we could
* be connected to a legacy switch that doesn't advertise
* desired flow control, but can be forced on the link
* partner. So if we advertised no flow control, that is
* what we will resolve to. If we advertised some kind of
* receive capability (Rx Pause Only or Full Flow Control)
* and the link partner advertised none, we will configure
* ourselves to enable Rx Flow Control only. We can do
* this safely for two reasons: If the link partner really
* didn't want flow control enabled, and we enable Rx, no
* harm done since we won't be receiving any PAUSE frames
* anyway. If the intent on the link partner was to have
* flow control enabled, then by us enabling RX only, we
* can at least receive pause frames and process them.
* This is a good idea because in most cases, since we are
* predominantly a server NIC, more times than not we will
* be asked to delay transmission of packets than asking
* our link partner to pause transmission of frames.
*/
else if ((hw->fc.requested_mode == igc_fc_none) ||
(hw->fc.requested_mode == igc_fc_tx_pause) ||
(hw->fc.strict_ieee)) {
hw->fc.current_mode = igc_fc_none;
hw_dbg("Flow Control = NONE.\n");
} else {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
if (duplex == HALF_DUPLEX)
hw->fc.current_mode = igc_fc_none;
/* Now we need to do one last check... If we auto-
* negotiated to HALF DUPLEX, flow control should not be
* enabled per IEEE 802.3 spec.
*/
ret_val = hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex);
if (ret_val) {
hw_dbg("Error getting link speed and duplex\n");
goto out;
}
/* Now we call a subroutine to actually force the MAC
* controller to use the correct flow control settings.
*/
ret_val = igc_force_mac_fc(hw);
if (ret_val) {
hw_dbg("Error forcing flow control settings\n");
goto out;
}
if (duplex == HALF_DUPLEX)
hw->fc.current_mode = igc_fc_none;
/* Now we call a subroutine to actually force the MAC
* controller to use the correct flow control settings.
*/
ret_val = igc_force_mac_fc(hw);
if (ret_val) {
hw_dbg("Error forcing flow control settings\n");
goto out;
}
out:

View File

@ -7108,7 +7108,6 @@ static int igc_probe(struct pci_dev *pdev,
/* Initialize link properties that are user-changeable */
adapter->fc_autoneg = true;
hw->mac.autoneg = true;
hw->phy.autoneg_advertised = 0xaf;
hw->fc.requested_mode = igc_fc_default;

View File

@ -494,24 +494,12 @@ s32 igc_setup_copper_link(struct igc_hw *hw)
s32 ret_val = 0;
bool link;
if (hw->mac.autoneg) {
/* Setup autoneg and flow control advertisement and perform
* autonegotiation.
*/
ret_val = igc_copper_link_autoneg(hw);
if (ret_val)
goto out;
} else {
/* PHY will be set to 10H, 10F, 100H or 100F
* depending on user settings.
*/
hw_dbg("Forcing Speed and Duplex\n");
ret_val = hw->phy.ops.force_speed_duplex(hw);
if (ret_val) {
hw_dbg("Error Forcing Speed and Duplex\n");
goto out;
}
}
/* Setup autoneg and flow control advertisement and perform
* autonegotiation.
*/
ret_val = igc_copper_link_autoneg(hw);
if (ret_val)
goto out;
/* Check link status. Wait up to 100 microseconds for link to become
* valid.

View File

@ -6,6 +6,7 @@
#include <linux/sched.h>
#include "ixgbe.h"
#include "ixgbe_mbx.h"
#include "ixgbe_phy.h"
#define IXGBE_82598_MAX_TX_QUEUES 32

View File

@ -43,6 +43,7 @@
#include "ixgbe.h"
#include "ixgbe_common.h"
#include "ixgbe_dcb_82599.h"
#include "ixgbe_mbx.h"
#include "ixgbe_phy.h"
#include "ixgbe_sriov.h"
#include "ixgbe_model.h"

View File

@ -4,7 +4,7 @@
#ifndef _IXGBE_MBX_H_
#define _IXGBE_MBX_H_
#include "ixgbe_type.h"
#include <linux/types.h>
#define IXGBE_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
@ -96,6 +96,8 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
#define IXGBE_VF_MBX_INIT_DELAY 500 /* microseconds between retries */
struct ixgbe_hw;
int ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16);
int ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);
int ixgbe_check_for_msg(struct ixgbe_hw *, u16);
@ -105,6 +107,18 @@ int ixgbe_check_for_rst(struct ixgbe_hw *, u16);
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
#endif /* CONFIG_PCI_IOV */
struct ixgbe_mbx_operations {
int (*init_params)(struct ixgbe_hw *hw);
int (*read)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 vf_number);
int (*write)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 vf_number);
int (*read_posted)(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
int (*write_posted)(struct ixgbe_hw *hw, u32 *msg, u16 size,
u16 mbx_id);
int (*check_for_msg)(struct ixgbe_hw *hw, u16 vf_number);
int (*check_for_ack)(struct ixgbe_hw *hw, u16 vf_number);
int (*check_for_rst)(struct ixgbe_hw *hw, u16 vf_number);
};
extern const struct ixgbe_mbx_operations mbx_ops_generic;
#endif /* _IXGBE_MBX_H_ */

View File

@ -18,6 +18,7 @@
#include "ixgbe.h"
#include "ixgbe_type.h"
#include "ixgbe_mbx.h"
#include "ixgbe_sriov.h"
#ifdef CONFIG_PCI_IOV

View File

@ -3601,19 +3601,6 @@ struct ixgbe_phy_info {
u32 nw_mng_if_sel;
};
#include "ixgbe_mbx.h"
struct ixgbe_mbx_operations {
int (*init_params)(struct ixgbe_hw *hw);
int (*read)(struct ixgbe_hw *, u32 *, u16, u16);
int (*write)(struct ixgbe_hw *, u32 *, u16, u16);
int (*read_posted)(struct ixgbe_hw *, u32 *, u16, u16);
int (*write_posted)(struct ixgbe_hw *, u32 *, u16, u16);
int (*check_for_msg)(struct ixgbe_hw *, u16);
int (*check_for_ack)(struct ixgbe_hw *, u16);
int (*check_for_rst)(struct ixgbe_hw *, u16);
};
struct ixgbe_mbx_stats {
u32 msgs_tx;
u32 msgs_rx;
@ -3623,6 +3610,8 @@ struct ixgbe_mbx_stats {
u32 rsts;
};
struct ixgbe_mbx_operations;
struct ixgbe_mbx_info {
const struct ixgbe_mbx_operations *ops;
struct ixgbe_mbx_stats stats;

View File

@ -6,6 +6,7 @@
#include <linux/sched.h>
#include "ixgbe.h"
#include "ixgbe_mbx.h"
#include "ixgbe_phy.h"
#include "ixgbe_x540.h"

View File

@ -4,6 +4,7 @@
#include "ixgbe_x540.h"
#include "ixgbe_type.h"
#include "ixgbe_common.h"
#include "ixgbe_mbx.h"
#include "ixgbe_phy.h"
static int ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *, ixgbe_link_speed);