Skip to content

Commit

Permalink
Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/jkirsher/next-queue

Jeff Kirsher says:

====================
10GbE Intel Wired LAN Driver Updates 2018-03-23

This series contains updates to ixgbe and ixgbevf only.

Paul adds status register reads to reduce a potential race condition
where registers can read 0xFFFFFFFF during a PCI reset, which in turn
causes the driver to remove the adapter.  Then fixes an assignment
operation with an "OR" operation.

Shannon Nelson provides several IPsec offload cleanups to ixgbe, as well as a
patch to enable TSO with IPsec offload.

Tony provides the much anticipated XDP support for ixgbevf.  Currently,
pass, drop and XDP_TX actions are supported, as well as meta data and
stats reporting.

Björn Töpel tweaks the page counting for XDP_REDIRECT, since a page can
have its reference count decreased via the xdp_do_redirect() call.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 25, 2018
2 parents ee7a60c + ed93a39 commit 0374016
Show file tree
Hide file tree
Showing 7 changed files with 596 additions and 121 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
ixgbe_link_speed speed);

#define IXGBE_FAILED_READ_RETRIES 5
#define IXGBE_FAILED_READ_REG 0xffffffffU
#define IXGBE_FAILED_READ_CFG_DWORD 0xffffffffU
#define IXGBE_FAILED_READ_CFG_WORD 0xffffU
Expand Down
46 changes: 28 additions & 18 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,11 +774,7 @@ int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,

first->tx_flags |= IXGBE_TX_FLAGS_IPSEC | IXGBE_TX_FLAGS_CC;

itd->flags = 0;
if (xs->id.proto == IPPROTO_ESP) {
struct sk_buff *skb = first->skb;
int ret, authlen, trailerlen;
u8 padlen;

itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
IXGBE_ADVTXD_TUCMD_L4T_TCP;
Expand All @@ -790,19 +786,28 @@ int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
* padlen bytes of padding. This ends up not the same
* as the static value found in xs->props.trailer_len (21).
*
* The "correct" way to get the auth length would be to use
* authlen = crypto_aead_authsize(xs->data);
* but since we know we only have one size to worry about
* we can let the compiler use the constant and save us a
* few CPU cycles.
* ... but if we're doing GSO, don't bother as the stack
* doesn't add a trailer for those.
*/
authlen = IXGBE_IPSEC_AUTH_BITS / 8;

ret = skb_copy_bits(skb, skb->len - (authlen + 2), &padlen, 1);
if (unlikely(ret))
return 0;
trailerlen = authlen + 2 + padlen;
itd->trailer_len = trailerlen;
if (!skb_is_gso(first->skb)) {
/* The "correct" way to get the auth length would be
* to use
* authlen = crypto_aead_authsize(xs->data);
* but since we know we only have one size to worry
* about * we can let the compiler use the constant
* and save us a few CPU cycles.
*/
const int authlen = IXGBE_IPSEC_AUTH_BITS / 8;
struct sk_buff *skb = first->skb;
u8 padlen;
int ret;

ret = skb_copy_bits(skb, skb->len - (authlen + 2),
&padlen, 1);
if (unlikely(ret))
return 0;
itd->trailer_len = authlen + 2 + padlen;
}
}
if (tsa->encrypt)
itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;
Expand Down Expand Up @@ -924,8 +929,13 @@ void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
ixgbe_ipsec_clear_hw_tables(adapter);

adapter->netdev->xfrmdev_ops = &ixgbe_xfrmdev_ops;
adapter->netdev->features |= NETIF_F_HW_ESP;
adapter->netdev->hw_enc_features |= NETIF_F_HW_ESP;

#define IXGBE_ESP_FEATURES (NETIF_F_HW_ESP | \
NETIF_F_HW_ESP_TX_CSUM | \
NETIF_F_GSO_ESP)

adapter->netdev->features |= IXGBE_ESP_FEATURES;
adapter->netdev->hw_enc_features |= IXGBE_ESP_FEATURES;

return;

Expand Down
79 changes: 47 additions & 32 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,23 +353,32 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
ixgbe_service_event_schedule(adapter);
}

static void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
static u32 ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
{
u8 __iomem *reg_addr;
u32 value;
int i;

reg_addr = READ_ONCE(hw->hw_addr);
if (ixgbe_removed(reg_addr))
return IXGBE_FAILED_READ_REG;

/* The following check not only optimizes a bit by not
* performing a read on the status register when the
* register just read was a status register read that
* returned IXGBE_FAILED_READ_REG. It also blocks any
* potential recursion.
/* Register read of 0xFFFFFFF can indicate the adapter has been removed,
* so perform several status register reads to determine if the adapter
* has been removed.
*/
if (reg == IXGBE_STATUS) {
ixgbe_remove_adapter(hw);
return;
for (i = 0; i < IXGBE_FAILED_READ_RETRIES; i++) {
value = readl(reg_addr + IXGBE_STATUS);
if (value != IXGBE_FAILED_READ_REG)
break;
mdelay(3);
}
value = ixgbe_read_reg(hw, IXGBE_STATUS);

if (value == IXGBE_FAILED_READ_REG)
ixgbe_remove_adapter(hw);
else
value = readl(reg_addr + reg);
return value;
}

/**
Expand Down Expand Up @@ -415,7 +424,7 @@ u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg)
writes_completed:
value = readl(reg_addr + reg);
if (unlikely(value == IXGBE_FAILED_READ_REG))
ixgbe_check_remove(hw, reg);
value = ixgbe_check_remove(hw, reg);
return value;
}

Expand Down Expand Up @@ -1620,7 +1629,8 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
bi->dma = dma;
bi->page = page;
bi->page_offset = ixgbe_rx_offset(rx_ring);
bi->pagecnt_bias = 1;
page_ref_add(page, USHRT_MAX - 1);
bi->pagecnt_bias = USHRT_MAX;
rx_ring->rx_stats.alloc_rx_page++;

return true;
Expand Down Expand Up @@ -2030,8 +2040,8 @@ static bool ixgbe_can_reuse_rx_page(struct ixgbe_rx_buffer *rx_buffer)
* the pagecnt_bias and page count so that we fully restock the
* number of references the driver holds.
*/
if (unlikely(!pagecnt_bias)) {
page_ref_add(page, USHRT_MAX);
if (unlikely(pagecnt_bias == 1)) {
page_ref_add(page, USHRT_MAX - 1);
rx_buffer->pagecnt_bias = USHRT_MAX;
}

Expand Down Expand Up @@ -7721,7 +7731,8 @@ static void ixgbe_service_task(struct work_struct *work)

static int ixgbe_tso(struct ixgbe_ring *tx_ring,
struct ixgbe_tx_buffer *first,
u8 *hdr_len)
u8 *hdr_len,
struct ixgbe_ipsec_tx_data *itd)
{
u32 vlan_macip_lens, type_tucmd, mss_l4len_idx;
struct sk_buff *skb = first->skb;
Expand All @@ -7735,6 +7746,7 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
unsigned char *hdr;
} l4;
u32 paylen, l4_offset;
u32 fceof_saidx = 0;
int err;

if (skb->ip_summed != CHECKSUM_PARTIAL)
Expand All @@ -7760,13 +7772,15 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
if (ip.v4->version == 4) {
unsigned char *csum_start = skb_checksum_start(skb);
unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
int len = csum_start - trans_start;

/* IP header will have to cancel out any data that
* is not a part of the outer IP header
* is not a part of the outer IP header, so set to
* a reverse csum if needed, else init check to 0.
*/
ip.v4->check = csum_fold(csum_partial(trans_start,
csum_start - trans_start,
0));
ip.v4->check = (skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) ?
csum_fold(csum_partial(trans_start,
len, 0)) : 0;
type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;

ip.v4->tot_len = 0;
Expand Down Expand Up @@ -7797,12 +7811,15 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
mss_l4len_idx = (*hdr_len - l4_offset) << IXGBE_ADVTXD_L4LEN_SHIFT;
mss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;

fceof_saidx |= itd->sa_idx;
type_tucmd |= itd->flags | itd->trailer_len;

/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
vlan_macip_lens = l4.hdr - ip.hdr;
vlan_macip_lens |= (ip.hdr - skb->data) << IXGBE_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;

ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd,
ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fceof_saidx, type_tucmd,
mss_l4len_idx);

return 1;
Expand Down Expand Up @@ -7864,10 +7881,8 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;

if (first->tx_flags & IXGBE_TX_FLAGS_IPSEC) {
fceof_saidx |= itd->sa_idx;
type_tucmd |= itd->flags | itd->trailer_len;
}
fceof_saidx |= itd->sa_idx;
type_tucmd |= itd->flags | itd->trailer_len;

ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fceof_saidx, type_tucmd, 0);
}
Expand Down Expand Up @@ -8495,7 +8510,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
if (skb->sp && !ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
goto out_drop;
#endif
tso = ixgbe_tso(tx_ring, first, &hdr_len);
tso = ixgbe_tso(tx_ring, first, &hdr_len, &ipsec_tx);
if (tso < 0)
goto out_drop;
else if (!tso)
Expand Down Expand Up @@ -9904,15 +9919,15 @@ ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,

/* We can only support IPV4 TSO in tunnels if we can mangle the
* inner IP ID field, so strip TSO if MANGLEID is not supported.
* IPsec offoad sets skb->encapsulation but still can handle
* the TSO, so it's the exception.
*/
if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID))
features &= ~NETIF_F_TSO;

#ifdef CONFIG_XFRM_OFFLOAD
/* IPsec offload doesn't get along well with others *yet* */
if (skb->sp)
features &= ~(NETIF_F_TSO | NETIF_F_HW_CSUM);
if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID)) {
#ifdef CONFIG_XFRM
if (!skb->sp)
#endif
features &= ~NETIF_F_TSO;
}

return features;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
Original file line number Diff line number Diff line change
Expand Up @@ -1847,9 +1847,9 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed,
(IXGBE_CS4227_EDC_MODE_SR << 1));

if (setup_linear)
reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
else
reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
reg_phy_ext |= (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;

ret_val = hw->phy.ops.write_reg(hw, reg_slice,
IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
Expand Down
Loading

0 comments on commit 0374016

Please sign in to comment.