sfxge: add common code support for changing TX queue pace

To delay packets from a particular TX queue by a particular time, write a value
into the TX Pace table s.t. pace time <= TX Pace Clock Period * (2 ^ pace value)
- the TX pace clock is 1/13 of the system clock, so its period should be 104 or
52 ns depending on whether turbo mode is active.

EFX_TX_PACE_CLOCK_BASE added by me.

Submitted by:   Mark Spender <mspender at solarflare.com>
Sponsored by:   Solarflare Communications, Inc.
Approved by:    gnn (mentor)
This commit is contained in:
arybchik 2015-02-22 19:24:08 +00:00
parent 4ea1b01844
commit cb28467a38
3 changed files with 73 additions and 0 deletions

View File

@ -1736,6 +1736,11 @@ efx_tx_qpost(
__in unsigned int completed,
__inout unsigned int *addedp);
extern __checkReturn int
efx_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns);
extern void
efx_tx_qpush(
__in efx_txq_t *etp,

View File

@ -34,6 +34,13 @@ extern "C" {
#endif
/**************************************************************************
*
* Falcon/Siena registers and descriptors
*
**************************************************************************
*/
/*
* FR_AB_EE_VPD_CFG0_REG_SF(128bit):
* SPI/VPD configuration register 0
@ -3838,6 +3845,18 @@ extern "C" {
#define FSF_AZ_DRIVER_EV_RX_DESCQ_ID_WIDTH 12
/**************************************************************************
*
* Falcon non-volatile configuration
*
**************************************************************************
*/
#define FR_AZ_TX_PACE_TBL_OFST FR_BZ_TX_PACE_TBL_OFST
#ifdef __cplusplus
}
#endif

View File

@ -224,6 +224,53 @@ efx_tx_qpush(
etp->et_index, &dword, B_FALSE);
}
#define EFX_MAX_PACE_VALUE 20
#define EFX_TX_PACE_CLOCK_BASE 104
__checkReturn int
efx_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns)
{
efx_nic_t *enp = etp->et_enp;
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_oword_t oword;
unsigned int pace_val;
unsigned int timer_period;
int rc;
EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
if (ns == 0) {
pace_val = 0;
} else {
/*
* The pace_val to write into the table is s.t
* ns <= timer_period * (2 ^ pace_val)
*/
timer_period = EFX_TX_PACE_CLOCK_BASE / encp->enc_clk_mult;
for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
if ((timer_period << pace_val) >= ns)
break;
}
}
if (pace_val > EFX_MAX_PACE_VALUE) {
rc = EINVAL;
goto fail1;
}
/* Update the pacing table */
EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index, &oword);
return (0);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
void
efx_tx_qflush(
__in efx_txq_t *etp)
@ -234,6 +281,8 @@ efx_tx_qflush(
EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
efx_tx_qpace(etp, 0);
label = etp->et_index;
/* Flush the queue */