Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 321455
b: refs/heads/master
c: 7e6d06f
h: refs/heads/master
i:
  321453: 5a3539f
  321451: 1a12e45
  321447: 276d02a
  321439: 74c2f87
v: v3
  • Loading branch information
Ben Hutchings authored and David S. Miller committed Aug 2, 2012
1 parent 21811b6 commit d2c2ae5
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 30b678d844af3305cda5953467005cebb5d7b687
refs/heads/master: 7e6d06f0de3f74ca929441add094518ae332257c
6 changes: 6 additions & 0 deletions trunk/drivers/net/ethernet/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,11 @@ static int efx_probe_all(struct efx_nic *efx)
goto fail2;
}

BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT);
if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) {
rc = -EINVAL;
goto fail3;
}
efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;

rc = efx_probe_filters(efx);
Expand Down Expand Up @@ -2070,6 +2075,7 @@ static int efx_register_netdev(struct efx_nic *efx)
net_dev->irq = efx->pci_dev->irq;
net_dev->netdev_ops = &efx_netdev_ops;
SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
net_dev->gso_max_segs = EFX_TSO_MAX_SEGS;

rtnl_lock();

Expand Down
14 changes: 10 additions & 4 deletions trunk/drivers/net/ethernet/sfc/efx.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern netdev_tx_t
efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc);
extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);

/* RX */
extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
Expand All @@ -52,10 +53,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
#define EFX_MAX_EVQ_SIZE 16384UL
#define EFX_MIN_EVQ_SIZE 512UL

/* The smallest [rt]xq_entries that the driver supports. Callers of
* efx_wake_queue() assume that they can subsequently send at least one
* skb. Falcon/A1 may require up to three descriptors per skb_frag. */
#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
/* Maximum number of TCP segments we support for soft-TSO */
#define EFX_TSO_MAX_SEGS 100

/* The smallest [rt]xq_entries that the driver supports. RX minimum
* is a bit arbitrary. For TX, we must have space for at least 2
* TSO skbs.
*/
#define EFX_RXQ_MIN_ENT 128U
#define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx))

/* Filters */
extern int efx_probe_filters(struct efx_nic *efx);
Expand Down
16 changes: 11 additions & 5 deletions trunk/drivers/net/ethernet/sfc/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,21 +680,27 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev,
struct ethtool_ringparam *ring)
{
struct efx_nic *efx = netdev_priv(net_dev);
u32 txq_entries;

if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
ring->tx_pending > EFX_MAX_DMAQ_SIZE)
return -EINVAL;

if (ring->rx_pending < EFX_MIN_RING_SIZE ||
ring->tx_pending < EFX_MIN_RING_SIZE) {
if (ring->rx_pending < EFX_RXQ_MIN_ENT) {
netif_err(efx, drv, efx->net_dev,
"TX and RX queues cannot be smaller than %ld\n",
EFX_MIN_RING_SIZE);
"RX queues cannot be smaller than %u\n",
EFX_RXQ_MIN_ENT);
return -EINVAL;
}

return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx));
if (txq_entries != ring->tx_pending)
netif_warn(efx, drv, efx->net_dev,
"increasing TX queue size to minimum of %u\n",
txq_entries);

return efx_realloc_channels(efx, ring->rx_pending, txq_entries);
}

static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
Expand Down
19 changes: 19 additions & 0 deletions trunk/drivers/net/ethernet/sfc/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,25 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr)
return len;
}

unsigned int efx_tx_max_skb_descs(struct efx_nic *efx)
{
/* Header and payload descriptor for each output segment, plus
* one for every input fragment boundary within a segment
*/
unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS;

/* Possibly one more per segment for the alignment workaround */
if (EFX_WORKAROUND_5391(efx))
max_descs += EFX_TSO_MAX_SEGS;

/* Possibly more for PCIe page boundaries within input fragments */
if (PAGE_SIZE > EFX_PAGE_SIZE)
max_descs += max_t(unsigned int, MAX_SKB_FRAGS,
DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE));

return max_descs;
}

/*
* Add a socket buffer to a TX queue
*
Expand Down

0 comments on commit d2c2ae5

Please sign in to comment.