aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/falcon.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-09-01 07:44:59 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-03 09:53:42 -0400
commit60ac10658c2e234cf7bc27e0930e324c6c6fcf61 (patch)
treeb16ee9efd385806755c6912492db43997c4f4b98 /drivers/net/sfc/falcon.c
parent26c086771a8ad0a1a72699674fa712fe6aeacb02 (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/falcon.c')
-rw-r--r--drivers/net/sfc/falcon.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index c7aa2f61cb1c..b73f1ea8bd58 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -474,9 +474,9 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
474 TX_NON_IP_DROP_DIS_B0, 1); 474 TX_NON_IP_DROP_DIS_B0, 1);
475 475
476 if (falcon_rev(efx) >= FALCON_REV_B0) { 476 if (falcon_rev(efx) >= FALCON_REV_B0) {
477 int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM); 477 int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM;
478 EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum); 478 EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, !csum);
479 EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum); 479 EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, !csum);
480 } 480 }
481 481
482 falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, 482 falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
@@ -485,10 +485,11 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
485 if (falcon_rev(efx) < FALCON_REV_B0) { 485 if (falcon_rev(efx) < FALCON_REV_B0) {
486 efx_oword_t reg; 486 efx_oword_t reg;
487 487
488 BUG_ON(tx_queue->queue >= 128); /* HW limit */ 488 /* Only 128 bits in this register */
489 BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128);
489 490
490 falcon_read(efx, &reg, TX_CHKSM_CFG_REG_KER_A1); 491 falcon_read(efx, &reg, TX_CHKSM_CFG_REG_KER_A1);
491 if (efx->net_dev->features & NETIF_F_IP_CSUM) 492 if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM)
492 clear_bit_le(tx_queue->queue, (void *)&reg); 493 clear_bit_le(tx_queue->queue, (void *)&reg);
493 else 494 else
494 set_bit_le(tx_queue->queue, (void *)&reg); 495 set_bit_le(tx_queue->queue, (void *)&reg);