Re: [PATCH 5/5] ucc_geth: Add IRQ coalescing
From: Joakim Tjernlund <hidden>
Date: 2012-10-03 13:18:20
Ping? Got no comments and I can see it in net or net-next trees either. Joakim Tjernlund [off-list ref] wrote on 2012/09/18 18:56:25:
quoted hunk ↗ jump to hunk
From: Joakim Tjernlund <redacted> To: netdev@vger.kernel.org, Cc: Joakim Tjernlund <redacted> Date: 2012/09/18 18:56 Subject: [PATCH 5/5] ucc_geth: Add IRQ coalescing Enable modest IRQ coalescing(4 pks) to reduce IRQ load. Signed-off-by: Joakim Tjernlund <redacted> --- arch/powerpc/include/asm/qe.h | 1 + drivers/net/ethernet/freescale/ucc_geth.c | 18 +++++++++++++++--- drivers/net/ethernet/freescale/ucc_geth.h | 20 ++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-)diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h index 5e0b6d5..12a8ac8 100644 --- a/arch/powerpc/include/asm/qe.h +++ b/arch/powerpc/include/asm/qe.h@@ -373,6 +373,7 @@ enum comm_dir { #define QE_MCC_STOP_RX 0x00000009 #define QE_ATM_TRANSMIT 0x0000000a #define QE_HPAC_CLEAR_ALL 0x0000000b +#define QE_SET_LAST_RX_THLD 0x00000013 #define QE_GRACEFUL_STOP_RX 0x0000001a #define QE_RESTART_RX 0x0000001b #define QE_HPAC_SET_PRIORITY 0x0000010bdiff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 7d60b95..772f796 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c@@ -124,7 +124,7 @@ static struct ucc_geth_info ugeth_primary_info = { .ecamptr = ((uint32_t) NULL), .eventRegMask = UCCE_OTHER, .pausePeriod = 0xf000, - .interruptcoalescingmaxvalue = {1, 1, 1, 1, 1, 1, 1, 1}, + .interruptcoalescingmaxvalue = {4, 4, 4, 4, 4, 4, 4, 4}, .bdRingLenTx = { TX_BD_RING_LEN, TX_BD_RING_LEN,@@ -237,7 +237,7 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, DMA_FROM_DEVICE)); skb_reserve(skb, UCC_GETH_RX_IP_ALIGNMENT); out_be32((u32 __iomem *)bd, - (R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W))); + (R_E | (in_be32((u32 __iomem*)bd) & R_W))); return skb; }@@ -1606,6 +1606,7 @@ static void adjust_link(struct net_device *dev) struct ucc_fast __iomem *uf_regs; struct phy_device *phydev = ugeth->phydev; int new_state = 0; + u32 cecr_subblock; ug_regs = ugeth->ug_regs; uf_regs = ugeth->uccf->uf_regs;@@ -1657,6 +1658,17 @@ static void adjust_link(struct net_device *dev) dev->name, phydev->speed); break; } + cecr_subblock = ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); + if (phydev->speed == SPEED_10) + qe_issue_cmd(QE_SET_LAST_RX_THLD, cecr_subblock, + QE_CR_PROTOCOL_ETHERNET, UCC_10_TIME); + else if (phydev->speed == SPEED_100) + qe_issue_cmd(QE_SET_LAST_RX_THLD, cecr_subblock, + QE_CR_PROTOCOL_ETHERNET, UCC_100_TIME); + else if (phydev->speed == SPEED_1000) + qe_issue_cmd(QE_SET_LAST_RX_THLD, cecr_subblock, + QE_CR_PROTOCOL_ETHERNET, UCC_GBIT_TIME); + ugeth->oldspeed = phydev->speed; }@@ -2390,7 +2402,7 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth) bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { /* set bd status and length */ - out_be32((u32 __iomem *)bd, R_I); + out_be32((u32 __iomem *)bd, 0); /* clear bd buffer */ out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); bd += sizeof(struct qe_bd);diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h index b68637e..49165ce 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.h +++ b/drivers/net/ethernet/freescale/ucc_geth.h@@ -923,6 +923,26 @@ struct ucc_geth_hardware_statistics { #define UCC_GETH_MACCFG1_INIT 0 #define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1) +/* + * From QUICC Engine Block Reference Manual, Chap 8.9: + * This command is used to set a timeout value for the Ethernet receiver + * interrupt coalescing mechanism. + * The timeout period is measured from the time that the last Ethernet frame + * was received. When the timeout expires, an interrupt is issued to the CPU + * even if the interrupt coalescing counter did not reach its maximum value. The + * timeout value should be written in the two least significant bytes of CECDR, + * and it should be specified in terms of serial clocks. + * For example, a value of 1000 in CECDR sets the timeout period to 1000 serial + * clocks. + * ------------------------------------------------------------------- + * GBIT = 125MHz => 8ns/tick, 8 bits / tick + * 100 = 25 MHz => 40ns/tick, 4 bits / tick + * 10 = 2.5 MHz => 400ns/tick, 4 bits / tick + */ +#define UCC_GBIT_TIME 64 +#define UCC_100_TIME 64 +#define UCC_10_TIME 8 + /* Ethernet Address Type. */ enum enet_addr_type { ENET_ADDR_TYPE_INDIVIDUAL, --1.7.8.6