Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 111324
b: refs/heads/master
c: 60ac106
h: refs/heads/master
v: v3
  • Loading branch information
Ben Hutchings authored and Jeff Garzik committed Sep 3, 2008
1 parent f10a646 commit 81c865d
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 93 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: 26c086771a8ad0a1a72699674fa712fe6aeacb02
refs/heads/master: 60ac10658c2e234cf7bc27e0930e324c6c6fcf61
25 changes: 8 additions & 17 deletions trunk/drivers/net/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,22 +923,13 @@ static void efx_select_used(struct efx_nic *efx)
struct efx_rx_queue *rx_queue;
int i;

/* TX queues. One per port per channel with TX capability
* (more than one per port won't work on Linux, due to out
* of order issues... but will be fine on Solaris)
*/
tx_queue = &efx->tx_queue[0];

/* Perform this for each channel with TX capabilities.
* At the moment, we only support a single TX queue
*/
tx_queue->used = 1;
if ((!EFX_INT_MODE_USE_MSI(efx)) && separate_tx_and_rx_channels)
tx_queue->channel = &efx->channel[1];
else
tx_queue->channel = &efx->channel[0];
tx_queue->channel->used_flags |= EFX_USED_BY_TX;
tx_queue++;
efx_for_each_tx_queue(tx_queue, efx) {
if (!EFX_INT_MODE_USE_MSI(efx) && separate_tx_and_rx_channels)
tx_queue->channel = &efx->channel[1];
else
tx_queue->channel = &efx->channel[0];
tx_queue->channel->used_flags |= EFX_USED_BY_TX;
}

/* RX queues. Each has a dedicated channel. */
for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
Expand Down Expand Up @@ -1881,7 +1872,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
channel->evqnum = i;
channel->work_pending = 0;
}
for (i = 0; i < EFX_MAX_TX_QUEUES; i++) {
for (i = 0; i < EFX_TX_QUEUE_COUNT; i++) {
tx_queue = &efx->tx_queue[i];
tx_queue->efx = efx;
tx_queue->queue = i;
Expand Down
45 changes: 2 additions & 43 deletions trunk/drivers/net/sfc/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ const char *efx_loopback_mode_names[] = {
[LOOPBACK_NETWORK] = "NETWORK",
};

static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable);

struct ethtool_string {
char name[ETH_GSTRING_LEN];
};
Expand Down Expand Up @@ -442,45 +440,6 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
}
}

static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
{
int rc;

/* Our TSO requires TX checksumming, so force TX checksumming
* on when TSO is enabled.
*/
if (enable) {
rc = efx_ethtool_set_tx_csum(net_dev, 1);
if (rc)
return rc;
}

return ethtool_op_set_tso(net_dev, enable);
}

static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
{
struct efx_nic *efx = netdev_priv(net_dev);
int rc;

rc = ethtool_op_set_tx_csum(net_dev, enable);
if (rc)
return rc;

efx_flush_queues(efx);

/* Our TSO requires TX checksumming, so disable TSO when
* checksumming is disabled
*/
if (!enable) {
rc = efx_ethtool_set_tso(net_dev, 0);
if (rc)
return rc;
}

return 0;
}

static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
{
struct efx_nic *efx = netdev_priv(net_dev);
Expand Down Expand Up @@ -701,11 +660,11 @@ struct ethtool_ops efx_ethtool_ops = {
.get_rx_csum = efx_ethtool_get_rx_csum,
.set_rx_csum = efx_ethtool_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = efx_ethtool_set_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
.set_tso = efx_ethtool_set_tso,
.set_tso = ethtool_op_set_tso,
.get_flags = ethtool_op_get_flags,
.set_flags = ethtool_op_set_flags,
.self_test_count = efx_ethtool_self_test_count,
Expand Down
11 changes: 6 additions & 5 deletions trunk/drivers/net/sfc/falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,9 +474,9 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
TX_NON_IP_DROP_DIS_B0, 1);

if (falcon_rev(efx) >= FALCON_REV_B0) {
int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM);
EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum);
EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum);
int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM;
EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, !csum);
EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, !csum);
}

falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
Expand All @@ -485,10 +485,11 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
if (falcon_rev(efx) < FALCON_REV_B0) {
efx_oword_t reg;

BUG_ON(tx_queue->queue >= 128); /* HW limit */
/* Only 128 bits in this register */
BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128);

falcon_read(efx, &reg, TX_CHKSM_CFG_REG_KER_A1);
if (efx->net_dev->features & NETIF_F_IP_CSUM)
if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM)
clear_bit_le(tx_queue->queue, (void *)&reg);
else
set_bit_le(tx_queue->queue, (void *)&reg);
Expand Down
21 changes: 9 additions & 12 deletions trunk/drivers/net/sfc/net_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ do {if (net_ratelimit()) EFX_LOG(efx, fmt, ##args); } while (0)
**************************************************************************/

#define EFX_MAX_CHANNELS 32
#define EFX_MAX_TX_QUEUES 1
#define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS

#define EFX_TX_QUEUE_OFFLOAD_CSUM 0
#define EFX_TX_QUEUE_NO_CSUM 1
#define EFX_TX_QUEUE_COUNT 2

/**
* struct efx_special_buffer - An Efx special buffer
* @addr: CPU base address of the buffer
Expand Down Expand Up @@ -156,7 +159,6 @@ struct efx_tx_buffer {
*
* @efx: The associated Efx NIC
* @queue: DMA queue number
* @used: Queue is used by net driver
* @channel: The associated channel
* @buffer: The software buffer ring
* @txd: The hardware descriptor ring
Expand Down Expand Up @@ -188,7 +190,6 @@ struct efx_tx_queue {
/* Members which don't change on the fast path */
struct efx_nic *efx ____cacheline_aligned_in_smp;
int queue;
int used;
struct efx_channel *channel;
struct efx_nic *nic;
struct efx_tx_buffer *buffer;
Expand Down Expand Up @@ -699,7 +700,7 @@ struct efx_nic {
enum nic_state state;
enum reset_type reset_pending;

struct efx_tx_queue tx_queue[EFX_MAX_TX_QUEUES];
struct efx_tx_queue tx_queue[EFX_TX_QUEUE_COUNT];
struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES];
struct efx_channel channel[EFX_MAX_CHANNELS];

Expand Down Expand Up @@ -840,19 +841,15 @@ struct efx_nic_type {
/* Iterate over all used TX queues */
#define efx_for_each_tx_queue(_tx_queue, _efx) \
for (_tx_queue = &_efx->tx_queue[0]; \
_tx_queue < &_efx->tx_queue[EFX_MAX_TX_QUEUES]; \
_tx_queue++) \
if (!_tx_queue->used) \
continue; \
else
_tx_queue < &_efx->tx_queue[EFX_TX_QUEUE_COUNT]; \
_tx_queue++)

/* Iterate over all TX queues belonging to a channel */
#define efx_for_each_channel_tx_queue(_tx_queue, _channel) \
for (_tx_queue = &_channel->efx->tx_queue[0]; \
_tx_queue < &_channel->efx->tx_queue[EFX_MAX_TX_QUEUES]; \
_tx_queue < &_channel->efx->tx_queue[EFX_TX_QUEUE_COUNT]; \
_tx_queue++) \
if ((!_tx_queue->used) || \
(_tx_queue->channel != _channel)) \
if (_tx_queue->channel != _channel) \
continue; \
else

Expand Down
11 changes: 9 additions & 2 deletions trunk/drivers/net/sfc/selftest.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ struct efx_selftest_state {
int flush;
int packet_count;
struct sk_buff **skbs;

/* Checksums are being offloaded */
int offload_csum;

atomic_t rx_good;
atomic_t rx_bad;
struct efx_loopback_payload payload;
Expand Down Expand Up @@ -292,8 +296,9 @@ void efx_loopback_rx_packet(struct efx_nic *efx,

received = (struct efx_loopback_payload *) buf_ptr;
received->ip.saddr = payload->ip.saddr;
received->ip.check = payload->ip.check;

if (state->offload_csum)
received->ip.check = payload->ip.check;

/* Check that header exists */
if (pkt_len < sizeof(received->header)) {
EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback "
Expand Down Expand Up @@ -634,6 +639,8 @@ static int efx_test_loopbacks(struct efx_nic *efx,

/* Test every TX queue */
efx_for_each_tx_queue(tx_queue, efx) {
state->offload_csum = (tx_queue->queue ==
EFX_TX_QUEUE_OFFLOAD_CSUM);
rc |= efx_test_loopback(tx_queue,
&tests->loopback[mode]);
if (rc)
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/net/sfc/selftest.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
*/

struct efx_loopback_self_tests {
int tx_sent[EFX_MAX_TX_QUEUES];
int tx_done[EFX_MAX_TX_QUEUES];
int tx_sent[EFX_TX_QUEUE_COUNT];
int tx_done[EFX_TX_QUEUE_COUNT];
int rx_good;
int rx_bad;
};
Expand Down
23 changes: 12 additions & 11 deletions trunk/drivers/net/sfc/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,14 @@ inline int efx_xmit(struct efx_nic *efx,
int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
return efx_xmit(efx, &efx->tx_queue[0], skb);
struct efx_tx_queue *tx_queue;

if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM];
else
tx_queue = &efx->tx_queue[EFX_TX_QUEUE_NO_CSUM];

return efx_xmit(efx, tx_queue, skb);
}

void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
Expand Down Expand Up @@ -412,26 +419,21 @@ int efx_probe_tx_queue(struct efx_tx_queue *tx_queue)
/* Allocate software ring */
txq_size = (efx->type->txd_ring_mask + 1) * sizeof(*tx_queue->buffer);
tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL);
if (!tx_queue->buffer) {
rc = -ENOMEM;
goto fail1;
}
if (!tx_queue->buffer)
return -ENOMEM;
for (i = 0; i <= efx->type->txd_ring_mask; ++i)
tx_queue->buffer[i].continuation = 1;

/* Allocate hardware ring */
rc = falcon_probe_tx(tx_queue);
if (rc)
goto fail2;
goto fail;

return 0;

fail2:
fail:
kfree(tx_queue->buffer);
tx_queue->buffer = NULL;
fail1:
tx_queue->used = 0;

return rc;
}

Expand Down Expand Up @@ -494,7 +496,6 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)

kfree(tx_queue->buffer);
tx_queue->buffer = NULL;
tx_queue->used = 0;
}


Expand Down

0 comments on commit 81c865d

Please sign in to comment.