Skip to content

Commit

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

Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2015-12-05

This series contains updates to fm10k only.

Jacob provides the remaining fm10k patches in the series.  First change
ensures that all the logic regarding the setting of netdev features is
consolidated in one place of the driver.  Fixed an issue where an assumption
was being made on how many queues are available, especially when init_hw_vf()
errors out.  Fixed up an number of issues with init_hw() where failures
were not being handled properly or at all, so update the driver to check
returned error codes and respond appropriately.  Fixed up typecasting
issues found where either the incorrect typecast size was used or
explicitly typecast values.  Added additional debugging statistics and
rename statistic to better reflect its true value.  Added support for
ITR scaling based on PCIe link speed for fm10k.  Fixed up code comment
where "hardware" was misspelled.

v2: Dropped patches #1 and #10 from original submission, patch #1 was from
    Nick Krause and due to his past kernel interactions, dropping his patch.
    Patch #10 had questions and concerns from Tom Herbert which cannot be
    addressed at this time since the author (Jacob Keller) is currently on
    sabbatical, so dropping this patch for now until we can properly address
    Tom's questions and concerns.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 6, 2015
2 parents b82583e + 03d13a5 commit b48565f
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 69 deletions.
8 changes: 7 additions & 1 deletion drivers/net/ethernet/intel/fm10k/fm10k.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,20 @@ struct fm10k_ring_container {
unsigned int total_packets; /* total packets processed this int */
u16 work_limit; /* total work allowed per interrupt */
u16 itr; /* interrupt throttle rate value */
u8 itr_scale; /* ITR adjustment scaler based on PCI speed */
u8 count; /* total number of rings in vector */
};

#define FM10K_ITR_MAX 0x0FFF /* maximum value for ITR */
#define FM10K_ITR_10K 100 /* 100us */
#define FM10K_ITR_20K 50 /* 50us */
#define FM10K_ITR_40K 25 /* 25us */
#define FM10K_ITR_ADAPTIVE 0x8000 /* adaptive interrupt moderation flag */

#define ITR_IS_ADAPTIVE(itr) (!!(itr & FM10K_ITR_ADAPTIVE))

#define FM10K_TX_ITR_DEFAULT FM10K_ITR_40K
#define FM10K_RX_ITR_DEFAULT FM10K_ITR_20K
#define FM10K_ITR_ENABLE (FM10K_ITR_AUTOMASK | FM10K_ITR_MASK_CLEAR)

static inline struct netdev_queue *txring_txq(const struct fm10k_ring *ring)
Expand Down Expand Up @@ -484,7 +490,7 @@ void fm10k_netpoll(struct net_device *netdev);
#endif

/* Netdev */
struct net_device *fm10k_alloc_netdev(void);
struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info);
int fm10k_setup_rx_resources(struct fm10k_ring *);
int fm10k_setup_tx_resources(struct fm10k_ring *);
void fm10k_free_rx_resources(struct fm10k_ring *);
Expand Down
14 changes: 7 additions & 7 deletions drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,14 @@ static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {

static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
FM10K_MBX_STAT("mbx_tx_oversized", tx_dropped),
FM10K_MBX_STAT("mbx_tx_dropped", tx_dropped),
FM10K_MBX_STAT("mbx_tx_messages", tx_messages),
FM10K_MBX_STAT("mbx_tx_dwords", tx_dwords),
FM10K_MBX_STAT("mbx_tx_mbmem_pulled", tx_mbmem_pulled),
FM10K_MBX_STAT("mbx_rx_messages", rx_messages),
FM10K_MBX_STAT("mbx_rx_dwords", rx_dwords),
FM10K_MBX_STAT("mbx_rx_parse_err", rx_parse_err),
FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed),
};

#define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
Expand Down Expand Up @@ -699,12 +701,10 @@ static int fm10k_get_coalesce(struct net_device *dev,
{
struct fm10k_intfc *interface = netdev_priv(dev);

ec->use_adaptive_tx_coalesce =
!!(interface->tx_itr & FM10K_ITR_ADAPTIVE);
ec->use_adaptive_tx_coalesce = ITR_IS_ADAPTIVE(interface->tx_itr);
ec->tx_coalesce_usecs = interface->tx_itr & ~FM10K_ITR_ADAPTIVE;

ec->use_adaptive_rx_coalesce =
!!(interface->rx_itr & FM10K_ITR_ADAPTIVE);
ec->use_adaptive_rx_coalesce = ITR_IS_ADAPTIVE(interface->rx_itr);
ec->rx_coalesce_usecs = interface->rx_itr & ~FM10K_ITR_ADAPTIVE;

return 0;
Expand All @@ -729,10 +729,10 @@ static int fm10k_set_coalesce(struct net_device *dev,

/* set initial values for adaptive ITR */
if (ec->use_adaptive_tx_coalesce)
tx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_10K;
tx_itr = FM10K_ITR_ADAPTIVE | FM10K_TX_ITR_DEFAULT;

if (ec->use_adaptive_rx_coalesce)
rx_itr = FM10K_ITR_ADAPTIVE | FM10K_ITR_20K;
rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;

/* update interface */
interface->tx_itr = tx_itr;
Expand Down
60 changes: 44 additions & 16 deletions drivers/net/ethernet/intel/fm10k/fm10k_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1094,11 +1094,11 @@ static void fm10k_tx_map(struct fm10k_ring *tx_ring,
netdev_tx_t fm10k_xmit_frame_ring(struct sk_buff *skb,
struct fm10k_ring *tx_ring)
{
u16 count = TXD_USE_COUNT(skb_headlen(skb));
struct fm10k_tx_buffer *first;
int tso;
u32 tx_flags = 0;
unsigned short f;
u16 count = TXD_USE_COUNT(skb_headlen(skb));
u32 tx_flags = 0;
int tso;

/* need: 1 descriptor per page * PAGE_SIZE/FM10K_MAX_DATA_PER_TXD,
* + 1 desc for skb_headlen/FM10K_MAX_DATA_PER_TXD,
Expand Down Expand Up @@ -1363,10 +1363,10 @@ static bool fm10k_clean_tx_irq(struct fm10k_q_vector *q_vector,
**/
static void fm10k_update_itr(struct fm10k_ring_container *ring_container)
{
unsigned int avg_wire_size, packets;
unsigned int avg_wire_size, packets, itr_round;

/* Only update ITR if we are using adaptive setting */
if (!(ring_container->itr & FM10K_ITR_ADAPTIVE))
if (!ITR_IS_ADAPTIVE(ring_container->itr))
goto clear_counts;

packets = ring_container->total_packets;
Expand All @@ -1375,18 +1375,44 @@ static void fm10k_update_itr(struct fm10k_ring_container *ring_container)

avg_wire_size = ring_container->total_bytes / packets;

/* Add 24 bytes to size to account for CRC, preamble, and gap */
avg_wire_size += 24;

/* Don't starve jumbo frames */
if (avg_wire_size > 3000)
avg_wire_size = 3000;
/* The following is a crude approximation of:
* wmem_default / (size + overhead) = desired_pkts_per_int
* rate / bits_per_byte / (size + ethernet overhead) = pkt_rate
* (desired_pkt_rate / pkt_rate) * usecs_per_sec = ITR value
*
* Assuming wmem_default is 212992 and overhead is 640 bytes per
* packet, (256 skb, 64 headroom, 320 shared info), we can reduce the
* formula down to
*
* (34 * (size + 24)) / (size + 640) = ITR
*
* We first do some math on the packet size and then finally bitshift
* by 8 after rounding up. We also have to account for PCIe link speed
* difference as ITR scales based on this.
*/
if (avg_wire_size <= 360) {
/* Start at 250K ints/sec and gradually drop to 77K ints/sec */
avg_wire_size *= 8;
avg_wire_size += 376;
} else if (avg_wire_size <= 1152) {
/* 77K ints/sec to 45K ints/sec */
avg_wire_size *= 3;
avg_wire_size += 2176;
} else if (avg_wire_size <= 1920) {
/* 45K ints/sec to 38K ints/sec */
avg_wire_size += 4480;
} else {
/* plateau at a limit of 38K ints/sec */
avg_wire_size = 6656;
}

/* Give a little boost to mid-size frames */
if ((avg_wire_size > 300) && (avg_wire_size < 1200))
avg_wire_size /= 3;
else
avg_wire_size /= 2;
/* Perform final bitshift for division after rounding up to ensure
* that the calculation will never get below a 1. The bit shift
* accounts for changes in the ITR due to PCIe link speed.
*/
itr_round = ACCESS_ONCE(ring_container->itr_scale) + 8;
avg_wire_size += (1 << itr_round) - 1;
avg_wire_size >>= itr_round;

/* write back value and retain adaptive flag */
ring_container->itr = avg_wire_size | FM10K_ITR_ADAPTIVE;
Expand Down Expand Up @@ -1604,6 +1630,7 @@ static int fm10k_alloc_q_vector(struct fm10k_intfc *interface,
q_vector->tx.ring = ring;
q_vector->tx.work_limit = FM10K_DEFAULT_TX_WORK;
q_vector->tx.itr = interface->tx_itr;
q_vector->tx.itr_scale = interface->hw.mac.itr_scale;
q_vector->tx.count = txr_count;

while (txr_count) {
Expand Down Expand Up @@ -1632,6 +1659,7 @@ static int fm10k_alloc_q_vector(struct fm10k_intfc *interface,
/* save Rx ring container info */
q_vector->rx.ring = ring;
q_vector->rx.itr = interface->rx_itr;
q_vector->rx.itr_scale = interface->hw.mac.itr_scale;
q_vector->rx.count = rxr_count;

while (rxr_count) {
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ static void fm10k_mbx_write_copy(struct fm10k_hw *hw,
if (!tail)
tail++;

mbx->tx_mbmem_pulled++;

/* write message to hardware FIFO */
fm10k_write_reg(hw, mbmem + tail++, *(head++));
} while (--len && --end);
Expand Down Expand Up @@ -459,6 +461,8 @@ static void fm10k_mbx_read_copy(struct fm10k_hw *hw,
if (!head)
head++;

mbx->rx_mbmem_pushed++;

/* read message from hardware FIFO */
*(tail++) = fm10k_read_reg(hw, mbmem + head++);
} while (--len && --end);
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/intel/fm10k/fm10k_mbx.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Intel Ethernet Switch Host Interface Driver
* Copyright(c) 2013 - 2014 Intel Corporation.
* Copyright(c) 2013 - 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
Expand Down Expand Up @@ -291,8 +291,10 @@ struct fm10k_mbx_info {
u64 tx_dropped;
u64 tx_messages;
u64 tx_dwords;
u64 tx_mbmem_pulled;
u64 rx_messages;
u64 rx_dwords;
u64 rx_mbmem_pushed;
u64 rx_parse_err;

/* Buffer to store messages */
Expand Down
31 changes: 19 additions & 12 deletions drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1388,8 +1388,9 @@ static const struct net_device_ops fm10k_netdev_ops = {

#define DEFAULT_DEBUG_LEVEL_SHIFT 3

struct net_device *fm10k_alloc_netdev(void)
struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info)
{
netdev_features_t hw_features;
struct fm10k_intfc *interface;
struct net_device *dev;

Expand All @@ -1412,27 +1413,31 @@ struct net_device *fm10k_alloc_netdev(void)
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_TSO_ECN |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_RXHASH |
NETIF_F_RXCSUM;

/* Only the PF can support VXLAN and NVGRE tunnel offloads */
if (info->mac == fm10k_mac_pf) {
dev->hw_enc_features = NETIF_F_IP_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_TSO_ECN |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_IPV6_CSUM |
NETIF_F_SG;

dev->features |= NETIF_F_GSO_UDP_TUNNEL;
}

/* all features defined to this point should be changeable */
dev->hw_features |= dev->features;
hw_features = dev->features;

/* allow user to enable L2 forwarding acceleration */
dev->hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;
hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;

/* configure VLAN features */
dev->vlan_features |= dev->features;

/* configure tunnel offloads */
dev->hw_enc_features |= NETIF_F_IP_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_TSO_ECN |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_IPV6_CSUM;

/* we want to leave these both on as we cannot disable VLAN tag
* insertion or stripping on the hardware since it is contained
* in the FTAG and not in the frame itself.
Expand All @@ -1443,5 +1448,7 @@ struct net_device *fm10k_alloc_netdev(void)

dev->priv_flags |= IFF_UNICAST_FLT;

dev->hw_features |= hw_features;

return dev;
}
Loading

0 comments on commit b48565f

Please sign in to comment.