diff options
author | Hariprasad Shenai <hariprasad@chelsio.com> | 2014-09-25 14:53:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-28 17:32:11 -0400 |
commit | e553ec3ff95ad8ad0176939e9b5c195dc97e3689 (patch) | |
tree | ee82f415fa196c9fa2765d22a4b34bd4213aae76 /drivers/net/ethernet/chelsio | |
parent | 91c04a9eb3a9b7e340a59446989263bfe31aee62 (diff) |
cxgb4: Add support for adaptive rx
Based on original work by Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/chelsio')
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 24 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/sge.c | 24 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 1 |
5 files changed, 49 insertions, 2 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 54b10d4c990a..9b2c669b6522 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -452,6 +452,7 @@ struct sge_rspq { /* state for an SGE response queue */ | |||
452 | u8 gen; /* current generation bit */ | 452 | u8 gen; /* current generation bit */ |
453 | u8 intr_params; /* interrupt holdoff parameters */ | 453 | u8 intr_params; /* interrupt holdoff parameters */ |
454 | u8 next_intr_params; /* holdoff params for next interrupt */ | 454 | u8 next_intr_params; /* holdoff params for next interrupt */ |
455 | u8 adaptive_rx; | ||
455 | u8 pktcnt_idx; /* interrupt packet threshold */ | 456 | u8 pktcnt_idx; /* interrupt packet threshold */ |
456 | u8 uld; /* ULD handling this queue */ | 457 | u8 uld; /* ULD handling this queue */ |
457 | u8 idx; /* queue index within its group */ | 458 | u8 idx; /* queue index within its group */ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index b9596a3668af..321f3d9385c9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -2753,8 +2753,31 @@ static int set_rx_intr_params(struct net_device *dev, | |||
2753 | return 0; | 2753 | return 0; |
2754 | } | 2754 | } |
2755 | 2755 | ||
2756 | static int set_adaptive_rx_setting(struct net_device *dev, int adaptive_rx) | ||
2757 | { | ||
2758 | int i; | ||
2759 | struct port_info *pi = netdev_priv(dev); | ||
2760 | struct adapter *adap = pi->adapter; | ||
2761 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
2762 | |||
2763 | for (i = 0; i < pi->nqsets; i++, q++) | ||
2764 | q->rspq.adaptive_rx = adaptive_rx; | ||
2765 | |||
2766 | return 0; | ||
2767 | } | ||
2768 | |||
2769 | static int get_adaptive_rx_setting(struct net_device *dev) | ||
2770 | { | ||
2771 | struct port_info *pi = netdev_priv(dev); | ||
2772 | struct adapter *adap = pi->adapter; | ||
2773 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
2774 | |||
2775 | return q->rspq.adaptive_rx; | ||
2776 | } | ||
2777 | |||
2756 | static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | 2778 | static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) |
2757 | { | 2779 | { |
2780 | set_adaptive_rx_setting(dev, c->use_adaptive_rx_coalesce); | ||
2758 | return set_rx_intr_params(dev, c->rx_coalesce_usecs, | 2781 | return set_rx_intr_params(dev, c->rx_coalesce_usecs, |
2759 | c->rx_max_coalesced_frames); | 2782 | c->rx_max_coalesced_frames); |
2760 | } | 2783 | } |
@@ -2768,6 +2791,7 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | |||
2768 | c->rx_coalesce_usecs = qtimer_val(adap, rq); | 2791 | c->rx_coalesce_usecs = qtimer_val(adap, rq); |
2769 | c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ? | 2792 | c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ? |
2770 | adap->sge.counter_val[rq->pktcnt_idx] : 0; | 2793 | adap->sge.counter_val[rq->pktcnt_idx] : 0; |
2794 | c->use_adaptive_rx_coalesce = get_adaptive_rx_setting(dev); | ||
2771 | return 0; | 2795 | return 0; |
2772 | } | 2796 | } |
2773 | 2797 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 87db53343543..bb7851e0b4c6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c | |||
@@ -203,6 +203,9 @@ enum { | |||
203 | RX_LARGE_MTU_BUF = 0x3, /* large MTU buffer */ | 203 | RX_LARGE_MTU_BUF = 0x3, /* large MTU buffer */ |
204 | }; | 204 | }; |
205 | 205 | ||
206 | static int timer_pkt_quota[] = {1, 1, 2, 3, 4, 5}; | ||
207 | #define MIN_NAPI_WORK 1 | ||
208 | |||
206 | static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *d) | 209 | static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *d) |
207 | { | 210 | { |
208 | return d->dma_addr & ~(dma_addr_t)RX_BUF_FLAGS; | 211 | return d->dma_addr & ~(dma_addr_t)RX_BUF_FLAGS; |
@@ -1969,9 +1972,26 @@ static int napi_rx_handler(struct napi_struct *napi, int budget) | |||
1969 | u32 val; | 1972 | u32 val; |
1970 | 1973 | ||
1971 | if (likely(work_done < budget)) { | 1974 | if (likely(work_done < budget)) { |
1975 | int timer_index; | ||
1976 | |||
1972 | napi_complete(napi); | 1977 | napi_complete(napi); |
1973 | params = q->next_intr_params; | 1978 | timer_index = QINTR_TIMER_IDX_GET(q->next_intr_params); |
1974 | q->next_intr_params = q->intr_params; | 1979 | |
1980 | if (q->adaptive_rx) { | ||
1981 | if (work_done > max(timer_pkt_quota[timer_index], | ||
1982 | MIN_NAPI_WORK)) | ||
1983 | timer_index = (timer_index + 1); | ||
1984 | else | ||
1985 | timer_index = timer_index - 1; | ||
1986 | |||
1987 | timer_index = clamp(timer_index, 0, SGE_TIMERREGS - 1); | ||
1988 | q->next_intr_params = QINTR_TIMER_IDX(timer_index) | | ||
1989 | V_QINTR_CNT_EN; | ||
1990 | params = q->next_intr_params; | ||
1991 | } else { | ||
1992 | params = q->next_intr_params; | ||
1993 | q->next_intr_params = q->intr_params; | ||
1994 | } | ||
1975 | } else | 1995 | } else |
1976 | params = QINTR_TIMER_IDX(7); | 1996 | params = QINTR_TIMER_IDX(7); |
1977 | 1997 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h index 6833a7b02137..c19a90e7f7d1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | |||
@@ -135,6 +135,7 @@ struct rsp_ctrl { | |||
135 | #define RSPD_GEN(x) ((x) >> 7) | 135 | #define RSPD_GEN(x) ((x) >> 7) |
136 | #define RSPD_TYPE(x) (((x) >> 4) & 3) | 136 | #define RSPD_TYPE(x) (((x) >> 4) & 3) |
137 | 137 | ||
138 | #define V_QINTR_CNT_EN 0x0 | ||
138 | #define QINTR_CNT_EN 0x1 | 139 | #define QINTR_CNT_EN 0x1 |
139 | #define QINTR_TIMER_IDX(x) ((x) << 1) | 140 | #define QINTR_TIMER_IDX(x) ((x) << 1) |
140 | #define QINTR_TIMER_IDX_GET(x) (((x) >> 1) & 0x7) | 141 | #define QINTR_TIMER_IDX_GET(x) (((x) >> 1) & 0x7) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 847a162af98c..eee272883027 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | |||
@@ -77,6 +77,7 @@ | |||
77 | #define PIDX_T5(x) (((x) >> S_PIDX_T5) & M_PIDX_T5) | 77 | #define PIDX_T5(x) (((x) >> S_PIDX_T5) & M_PIDX_T5) |
78 | 78 | ||
79 | 79 | ||
80 | #define SGE_TIMERREGS 6 | ||
80 | #define SGE_PF_GTS 0x4 | 81 | #define SGE_PF_GTS 0x4 |
81 | #define INGRESSQID_MASK 0xffff0000U | 82 | #define INGRESSQID_MASK 0xffff0000U |
82 | #define INGRESSQID_SHIFT 16 | 83 | #define INGRESSQID_SHIFT 16 |