diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-09-01 07:44:59 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-03 09:53:42 -0400 |
commit | 60ac10658c2e234cf7bc27e0930e324c6c6fcf61 (patch) | |
tree | b16ee9efd385806755c6912492db43997c4f4b98 /drivers/net/sfc/efx.c | |
parent | 26c086771a8ad0a1a72699674fa712fe6aeacb02 (diff) |
sfc: Use separate hardware TX queues to select checksum generation
Checksum generation is an attribute of our hardware TX queues, not TX
descriptors. We previously used a single queue and turned checksum
generation on or off as requested through ethtool. However, this can
result in regenerating checksums in raw packets that should not be
modified. We now create 2 hardware TX queues with checksum generation
on or off. They are presented to the net core as one queue since it
does not know how to select between them.
The self-test verifies that a bad checksum is unaltered on the queue
with checksum generation off.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r-- | drivers/net/sfc/efx.c | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 42539802b7ae..2a2300571cbf 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -923,22 +923,13 @@ static void efx_select_used(struct efx_nic *efx) | |||
923 | struct efx_rx_queue *rx_queue; | 923 | struct efx_rx_queue *rx_queue; |
924 | int i; | 924 | int i; |
925 | 925 | ||
926 | /* TX queues. One per port per channel with TX capability | 926 | efx_for_each_tx_queue(tx_queue, efx) { |
927 | * (more than one per port won't work on Linux, due to out | 927 | if (!EFX_INT_MODE_USE_MSI(efx) && separate_tx_and_rx_channels) |
928 | * of order issues... but will be fine on Solaris) | 928 | tx_queue->channel = &efx->channel[1]; |
929 | */ | 929 | else |
930 | tx_queue = &efx->tx_queue[0]; | 930 | tx_queue->channel = &efx->channel[0]; |
931 | 931 | tx_queue->channel->used_flags |= EFX_USED_BY_TX; | |
932 | /* Perform this for each channel with TX capabilities. | 932 | } |
933 | * At the moment, we only support a single TX queue | ||
934 | */ | ||
935 | tx_queue->used = 1; | ||
936 | if ((!EFX_INT_MODE_USE_MSI(efx)) && separate_tx_and_rx_channels) | ||
937 | tx_queue->channel = &efx->channel[1]; | ||
938 | else | ||
939 | tx_queue->channel = &efx->channel[0]; | ||
940 | tx_queue->channel->used_flags |= EFX_USED_BY_TX; | ||
941 | tx_queue++; | ||
942 | 933 | ||
943 | /* RX queues. Each has a dedicated channel. */ | 934 | /* RX queues. Each has a dedicated channel. */ |
944 | for (i = 0; i < EFX_MAX_RX_QUEUES; i++) { | 935 | for (i = 0; i < EFX_MAX_RX_QUEUES; i++) { |
@@ -1881,7 +1872,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1881 | channel->evqnum = i; | 1872 | channel->evqnum = i; |
1882 | channel->work_pending = 0; | 1873 | channel->work_pending = 0; |
1883 | } | 1874 | } |
1884 | for (i = 0; i < EFX_MAX_TX_QUEUES; i++) { | 1875 | for (i = 0; i < EFX_TX_QUEUE_COUNT; i++) { |
1885 | tx_queue = &efx->tx_queue[i]; | 1876 | tx_queue = &efx->tx_queue[i]; |
1886 | tx_queue->efx = efx; | 1877 | tx_queue->efx = efx; |
1887 | tx_queue->queue = i; | 1878 | tx_queue->queue = i; |