aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/nic.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2011-01-10 16:18:20 -0500
committerBen Hutchings <bhutchings@solarflare.com>2011-02-15 14:45:35 -0500
commit94b274bf5fba6c75b922c8a23ad4b5639a168780 (patch)
tree48f3bb2629ee14ba620a08098da1908d16bbe22f /drivers/net/sfc/nic.c
parent525da9072c28df815bff64bf00f3b11ab88face8 (diff)
sfc: Add TX queues for high-priority traffic
Implement the ndo_setup_tc() operation with 2 traffic classes. Current Solarstorm controllers do not implement TX queue priority, but they do allow queues to be 'paced' with an enforced delay between packets. Paced and unpaced queues are scheduled in round-robin within two separate hardware bins (paced queues with a large delay may be placed into a third bin temporarily, but we won't use that). If there are queues in both bins, the TX scheduler will alternate between them. If we make high-priority queues unpaced and best-effort queues paced, and high-priority queues are mostly empty, a single high-priority queue can then instantly take 50% of the packet rate regardless of how many of the best-effort queues have descriptors outstanding. We do not actually want an enforced delay between packets on best- effort queues, so we set the pace value to a reserved value that actually results in a delay of 0. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/sfc/nic.c')
-rw-r--r--drivers/net/sfc/nic.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index da386599ab6..1d0b8b6f25c 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -445,8 +445,8 @@ int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
445 445
446void efx_nic_init_tx(struct efx_tx_queue *tx_queue) 446void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
447{ 447{
448 efx_oword_t tx_desc_ptr;
449 struct efx_nic *efx = tx_queue->efx; 448 struct efx_nic *efx = tx_queue->efx;
449 efx_oword_t reg;
450 450
451 tx_queue->flushed = FLUSH_NONE; 451 tx_queue->flushed = FLUSH_NONE;
452 452
@@ -454,7 +454,7 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
454 efx_init_special_buffer(efx, &tx_queue->txd); 454 efx_init_special_buffer(efx, &tx_queue->txd);
455 455
456 /* Push TX descriptor ring to card */ 456 /* Push TX descriptor ring to card */
457 EFX_POPULATE_OWORD_10(tx_desc_ptr, 457 EFX_POPULATE_OWORD_10(reg,
458 FRF_AZ_TX_DESCQ_EN, 1, 458 FRF_AZ_TX_DESCQ_EN, 1,
459 FRF_AZ_TX_ISCSI_DDIG_EN, 0, 459 FRF_AZ_TX_ISCSI_DDIG_EN, 0,
460 FRF_AZ_TX_ISCSI_HDIG_EN, 0, 460 FRF_AZ_TX_ISCSI_HDIG_EN, 0,
@@ -470,17 +470,15 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
470 470
471 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { 471 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
472 int csum = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD; 472 int csum = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
473 EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_IP_CHKSM_DIS, !csum); 473 EFX_SET_OWORD_FIELD(reg, FRF_BZ_TX_IP_CHKSM_DIS, !csum);
474 EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_TCP_CHKSM_DIS, 474 EFX_SET_OWORD_FIELD(reg, FRF_BZ_TX_TCP_CHKSM_DIS,
475 !csum); 475 !csum);
476 } 476 }
477 477
478 efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, 478 efx_writeo_table(efx, &reg, efx->type->txd_ptr_tbl_base,
479 tx_queue->queue); 479 tx_queue->queue);
480 480
481 if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { 481 if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) {
482 efx_oword_t reg;
483
484 /* Only 128 bits in this register */ 482 /* Only 128 bits in this register */
485 BUILD_BUG_ON(EFX_MAX_TX_QUEUES > 128); 483 BUILD_BUG_ON(EFX_MAX_TX_QUEUES > 128);
486 484
@@ -491,6 +489,16 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
491 set_bit_le(tx_queue->queue, (void *)&reg); 489 set_bit_le(tx_queue->queue, (void *)&reg);
492 efx_writeo(efx, &reg, FR_AA_TX_CHKSM_CFG); 490 efx_writeo(efx, &reg, FR_AA_TX_CHKSM_CFG);
493 } 491 }
492
493 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
494 EFX_POPULATE_OWORD_1(reg,
495 FRF_BZ_TX_PACE,
496 (tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ?
497 FFE_BZ_TX_PACE_OFF :
498 FFE_BZ_TX_PACE_RESERVED);
499 efx_writeo_table(efx, &reg, FR_BZ_TX_PACE_TBL,
500 tx_queue->queue);
501 }
494} 502}
495 503
496static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue) 504static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue)
@@ -1238,8 +1246,10 @@ int efx_nic_flush_queues(struct efx_nic *efx)
1238 1246
1239 /* Flush all tx queues in parallel */ 1247 /* Flush all tx queues in parallel */
1240 efx_for_each_channel(channel, efx) { 1248 efx_for_each_channel(channel, efx) {
1241 efx_for_each_channel_tx_queue(tx_queue, channel) 1249 efx_for_each_possible_channel_tx_queue(tx_queue, channel) {
1242 efx_flush_tx_queue(tx_queue); 1250 if (tx_queue->initialised)
1251 efx_flush_tx_queue(tx_queue);
1252 }
1243 } 1253 }
1244 1254
1245 /* The hardware supports four concurrent rx flushes, each of which may 1255 /* The hardware supports four concurrent rx flushes, each of which may
@@ -1262,8 +1272,9 @@ int efx_nic_flush_queues(struct efx_nic *efx)
1262 ++rx_pending; 1272 ++rx_pending;
1263 } 1273 }
1264 } 1274 }
1265 efx_for_each_channel_tx_queue(tx_queue, channel) { 1275 efx_for_each_possible_channel_tx_queue(tx_queue, channel) {
1266 if (tx_queue->flushed != FLUSH_DONE) 1276 if (tx_queue->initialised &&
1277 tx_queue->flushed != FLUSH_DONE)
1267 ++tx_pending; 1278 ++tx_pending;
1268 } 1279 }
1269 } 1280 }
@@ -1278,8 +1289,9 @@ int efx_nic_flush_queues(struct efx_nic *efx)
1278 /* Mark the queues as all flushed. We're going to return failure 1289 /* Mark the queues as all flushed. We're going to return failure
1279 * leading to a reset, or fake up success anyway */ 1290 * leading to a reset, or fake up success anyway */
1280 efx_for_each_channel(channel, efx) { 1291 efx_for_each_channel(channel, efx) {
1281 efx_for_each_channel_tx_queue(tx_queue, channel) { 1292 efx_for_each_possible_channel_tx_queue(tx_queue, channel) {
1282 if (tx_queue->flushed != FLUSH_DONE) 1293 if (tx_queue->initialised &&
1294 tx_queue->flushed != FLUSH_DONE)
1283 netif_err(efx, hw, efx->net_dev, 1295 netif_err(efx, hw, efx->net_dev,
1284 "tx queue %d flush command timed out\n", 1296 "tx queue %d flush command timed out\n",
1285 tx_queue->queue); 1297 tx_queue->queue);
@@ -1682,6 +1694,19 @@ void efx_nic_init_common(struct efx_nic *efx)
1682 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) 1694 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
1683 EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); 1695 EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
1684 efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); 1696 efx_writeo(efx, &temp, FR_AZ_TX_RESERVED);
1697
1698 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
1699 EFX_POPULATE_OWORD_4(temp,
1700 /* Default values */
1701 FRF_BZ_TX_PACE_SB_NOT_AF, 0x15,
1702 FRF_BZ_TX_PACE_SB_AF, 0xb,
1703 FRF_BZ_TX_PACE_FB_BASE, 0,
1704 /* Allow large pace values in the
1705 * fast bin. */
1706 FRF_BZ_TX_PACE_BIN_TH,
1707 FFE_BZ_TX_PACE_RESERVED);
1708 efx_writeo(efx, &temp, FR_BZ_TX_PACE);
1709 }
1685} 1710}
1686 1711
1687/* Register dump */ 1712/* Register dump */