1*4882a593Smuzhiyun /*****************************************************************************
2*4882a593Smuzhiyun * *
3*4882a593Smuzhiyun * File: sge.c *
4*4882a593Smuzhiyun * $Revision: 1.26 $ *
5*4882a593Smuzhiyun * $Date: 2005/06/21 18:29:48 $ *
6*4882a593Smuzhiyun * Description: *
7*4882a593Smuzhiyun * DMA engine. *
8*4882a593Smuzhiyun * part of the Chelsio 10Gb Ethernet Driver. *
9*4882a593Smuzhiyun * *
10*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify *
11*4882a593Smuzhiyun * it under the terms of the GNU General Public License, version 2, as *
12*4882a593Smuzhiyun * published by the Free Software Foundation. *
13*4882a593Smuzhiyun * *
14*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License along *
15*4882a593Smuzhiyun * with this program; if not, see <http://www.gnu.org/licenses/>. *
16*4882a593Smuzhiyun * *
17*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18*4882a593Smuzhiyun * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19*4882a593Smuzhiyun * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20*4882a593Smuzhiyun * *
21*4882a593Smuzhiyun * http://www.chelsio.com *
22*4882a593Smuzhiyun * *
23*4882a593Smuzhiyun * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24*4882a593Smuzhiyun * All rights reserved. *
25*4882a593Smuzhiyun * *
26*4882a593Smuzhiyun * Maintainers: maintainers@chelsio.com *
27*4882a593Smuzhiyun * *
28*4882a593Smuzhiyun * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29*4882a593Smuzhiyun * Tina Yang <tainay@chelsio.com> *
30*4882a593Smuzhiyun * Felix Marti <felix@chelsio.com> *
31*4882a593Smuzhiyun * Scott Bardone <sbardone@chelsio.com> *
32*4882a593Smuzhiyun * Kurt Ottaway <kottaway@chelsio.com> *
33*4882a593Smuzhiyun * Frank DiMambro <frank@chelsio.com> *
34*4882a593Smuzhiyun * *
35*4882a593Smuzhiyun * History: *
36*4882a593Smuzhiyun * *
37*4882a593Smuzhiyun ****************************************************************************/
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #include "common.h"
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #include <linux/types.h>
42*4882a593Smuzhiyun #include <linux/errno.h>
43*4882a593Smuzhiyun #include <linux/pci.h>
44*4882a593Smuzhiyun #include <linux/ktime.h>
45*4882a593Smuzhiyun #include <linux/netdevice.h>
46*4882a593Smuzhiyun #include <linux/etherdevice.h>
47*4882a593Smuzhiyun #include <linux/if_vlan.h>
48*4882a593Smuzhiyun #include <linux/skbuff.h>
49*4882a593Smuzhiyun #include <linux/mm.h>
50*4882a593Smuzhiyun #include <linux/tcp.h>
51*4882a593Smuzhiyun #include <linux/ip.h>
52*4882a593Smuzhiyun #include <linux/in.h>
53*4882a593Smuzhiyun #include <linux/if_arp.h>
54*4882a593Smuzhiyun #include <linux/slab.h>
55*4882a593Smuzhiyun #include <linux/prefetch.h>
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #include "cpl5_cmd.h"
58*4882a593Smuzhiyun #include "sge.h"
59*4882a593Smuzhiyun #include "regs.h"
60*4882a593Smuzhiyun #include "espi.h"
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* This belongs in if_ether.h */
63*4882a593Smuzhiyun #define ETH_P_CPL5 0xf
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun #define SGE_CMDQ_N 2
66*4882a593Smuzhiyun #define SGE_FREELQ_N 2
67*4882a593Smuzhiyun #define SGE_CMDQ0_E_N 1024
68*4882a593Smuzhiyun #define SGE_CMDQ1_E_N 128
69*4882a593Smuzhiyun #define SGE_FREEL_SIZE 4096
70*4882a593Smuzhiyun #define SGE_JUMBO_FREEL_SIZE 512
71*4882a593Smuzhiyun #define SGE_FREEL_REFILL_THRESH 16
72*4882a593Smuzhiyun #define SGE_RESPQ_E_N 1024
73*4882a593Smuzhiyun #define SGE_INTRTIMER_NRES 1000
74*4882a593Smuzhiyun #define SGE_RX_SM_BUF_SIZE 1536
75*4882a593Smuzhiyun #define SGE_TX_DESC_MAX_PLEN 16384
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun #define SGE_RESPQ_REPLENISH_THRES (SGE_RESPQ_E_N / 4)
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun /*
80*4882a593Smuzhiyun * Period of the TX buffer reclaim timer. This timer does not need to run
81*4882a593Smuzhiyun * frequently as TX buffers are usually reclaimed by new TX packets.
82*4882a593Smuzhiyun */
83*4882a593Smuzhiyun #define TX_RECLAIM_PERIOD (HZ / 4)
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun #define M_CMD_LEN 0x7fffffff
86*4882a593Smuzhiyun #define V_CMD_LEN(v) (v)
87*4882a593Smuzhiyun #define G_CMD_LEN(v) ((v) & M_CMD_LEN)
88*4882a593Smuzhiyun #define V_CMD_GEN1(v) ((v) << 31)
89*4882a593Smuzhiyun #define V_CMD_GEN2(v) (v)
90*4882a593Smuzhiyun #define F_CMD_DATAVALID (1 << 1)
91*4882a593Smuzhiyun #define F_CMD_SOP (1 << 2)
92*4882a593Smuzhiyun #define V_CMD_EOP(v) ((v) << 3)
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /*
95*4882a593Smuzhiyun * Command queue, receive buffer list, and response queue descriptors.
96*4882a593Smuzhiyun */
97*4882a593Smuzhiyun #if defined(__BIG_ENDIAN_BITFIELD)
98*4882a593Smuzhiyun struct cmdQ_e {
99*4882a593Smuzhiyun u32 addr_lo;
100*4882a593Smuzhiyun u32 len_gen;
101*4882a593Smuzhiyun u32 flags;
102*4882a593Smuzhiyun u32 addr_hi;
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun struct freelQ_e {
106*4882a593Smuzhiyun u32 addr_lo;
107*4882a593Smuzhiyun u32 len_gen;
108*4882a593Smuzhiyun u32 gen2;
109*4882a593Smuzhiyun u32 addr_hi;
110*4882a593Smuzhiyun };
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun struct respQ_e {
113*4882a593Smuzhiyun u32 Qsleeping : 4;
114*4882a593Smuzhiyun u32 Cmdq1CreditReturn : 5;
115*4882a593Smuzhiyun u32 Cmdq1DmaComplete : 5;
116*4882a593Smuzhiyun u32 Cmdq0CreditReturn : 5;
117*4882a593Smuzhiyun u32 Cmdq0DmaComplete : 5;
118*4882a593Smuzhiyun u32 FreelistQid : 2;
119*4882a593Smuzhiyun u32 CreditValid : 1;
120*4882a593Smuzhiyun u32 DataValid : 1;
121*4882a593Smuzhiyun u32 Offload : 1;
122*4882a593Smuzhiyun u32 Eop : 1;
123*4882a593Smuzhiyun u32 Sop : 1;
124*4882a593Smuzhiyun u32 GenerationBit : 1;
125*4882a593Smuzhiyun u32 BufferLength;
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun #elif defined(__LITTLE_ENDIAN_BITFIELD)
128*4882a593Smuzhiyun struct cmdQ_e {
129*4882a593Smuzhiyun u32 len_gen;
130*4882a593Smuzhiyun u32 addr_lo;
131*4882a593Smuzhiyun u32 addr_hi;
132*4882a593Smuzhiyun u32 flags;
133*4882a593Smuzhiyun };
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun struct freelQ_e {
136*4882a593Smuzhiyun u32 len_gen;
137*4882a593Smuzhiyun u32 addr_lo;
138*4882a593Smuzhiyun u32 addr_hi;
139*4882a593Smuzhiyun u32 gen2;
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun struct respQ_e {
143*4882a593Smuzhiyun u32 BufferLength;
144*4882a593Smuzhiyun u32 GenerationBit : 1;
145*4882a593Smuzhiyun u32 Sop : 1;
146*4882a593Smuzhiyun u32 Eop : 1;
147*4882a593Smuzhiyun u32 Offload : 1;
148*4882a593Smuzhiyun u32 DataValid : 1;
149*4882a593Smuzhiyun u32 CreditValid : 1;
150*4882a593Smuzhiyun u32 FreelistQid : 2;
151*4882a593Smuzhiyun u32 Cmdq0DmaComplete : 5;
152*4882a593Smuzhiyun u32 Cmdq0CreditReturn : 5;
153*4882a593Smuzhiyun u32 Cmdq1DmaComplete : 5;
154*4882a593Smuzhiyun u32 Cmdq1CreditReturn : 5;
155*4882a593Smuzhiyun u32 Qsleeping : 4;
156*4882a593Smuzhiyun } ;
157*4882a593Smuzhiyun #endif
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun /*
160*4882a593Smuzhiyun * SW Context Command and Freelist Queue Descriptors
161*4882a593Smuzhiyun */
162*4882a593Smuzhiyun struct cmdQ_ce {
163*4882a593Smuzhiyun struct sk_buff *skb;
164*4882a593Smuzhiyun DEFINE_DMA_UNMAP_ADDR(dma_addr);
165*4882a593Smuzhiyun DEFINE_DMA_UNMAP_LEN(dma_len);
166*4882a593Smuzhiyun };
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun struct freelQ_ce {
169*4882a593Smuzhiyun struct sk_buff *skb;
170*4882a593Smuzhiyun DEFINE_DMA_UNMAP_ADDR(dma_addr);
171*4882a593Smuzhiyun DEFINE_DMA_UNMAP_LEN(dma_len);
172*4882a593Smuzhiyun };
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /*
175*4882a593Smuzhiyun * SW command, freelist and response rings
176*4882a593Smuzhiyun */
177*4882a593Smuzhiyun struct cmdQ {
178*4882a593Smuzhiyun unsigned long status; /* HW DMA fetch status */
179*4882a593Smuzhiyun unsigned int in_use; /* # of in-use command descriptors */
180*4882a593Smuzhiyun unsigned int size; /* # of descriptors */
181*4882a593Smuzhiyun unsigned int processed; /* total # of descs HW has processed */
182*4882a593Smuzhiyun unsigned int cleaned; /* total # of descs SW has reclaimed */
183*4882a593Smuzhiyun unsigned int stop_thres; /* SW TX queue suspend threshold */
184*4882a593Smuzhiyun u16 pidx; /* producer index (SW) */
185*4882a593Smuzhiyun u16 cidx; /* consumer index (HW) */
186*4882a593Smuzhiyun u8 genbit; /* current generation (=valid) bit */
187*4882a593Smuzhiyun u8 sop; /* is next entry start of packet? */
188*4882a593Smuzhiyun struct cmdQ_e *entries; /* HW command descriptor Q */
189*4882a593Smuzhiyun struct cmdQ_ce *centries; /* SW command context descriptor Q */
190*4882a593Smuzhiyun dma_addr_t dma_addr; /* DMA addr HW command descriptor Q */
191*4882a593Smuzhiyun spinlock_t lock; /* Lock to protect cmdQ enqueuing */
192*4882a593Smuzhiyun };
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun struct freelQ {
195*4882a593Smuzhiyun unsigned int credits; /* # of available RX buffers */
196*4882a593Smuzhiyun unsigned int size; /* free list capacity */
197*4882a593Smuzhiyun u16 pidx; /* producer index (SW) */
198*4882a593Smuzhiyun u16 cidx; /* consumer index (HW) */
199*4882a593Smuzhiyun u16 rx_buffer_size; /* Buffer size on this free list */
200*4882a593Smuzhiyun u16 dma_offset; /* DMA offset to align IP headers */
201*4882a593Smuzhiyun u16 recycleq_idx; /* skb recycle q to use */
202*4882a593Smuzhiyun u8 genbit; /* current generation (=valid) bit */
203*4882a593Smuzhiyun struct freelQ_e *entries; /* HW freelist descriptor Q */
204*4882a593Smuzhiyun struct freelQ_ce *centries; /* SW freelist context descriptor Q */
205*4882a593Smuzhiyun dma_addr_t dma_addr; /* DMA addr HW freelist descriptor Q */
206*4882a593Smuzhiyun };
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun struct respQ {
209*4882a593Smuzhiyun unsigned int credits; /* credits to be returned to SGE */
210*4882a593Smuzhiyun unsigned int size; /* # of response Q descriptors */
211*4882a593Smuzhiyun u16 cidx; /* consumer index (SW) */
212*4882a593Smuzhiyun u8 genbit; /* current generation(=valid) bit */
213*4882a593Smuzhiyun struct respQ_e *entries; /* HW response descriptor Q */
214*4882a593Smuzhiyun dma_addr_t dma_addr; /* DMA addr HW response descriptor Q */
215*4882a593Smuzhiyun };
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun /* Bit flags for cmdQ.status */
218*4882a593Smuzhiyun enum {
219*4882a593Smuzhiyun CMDQ_STAT_RUNNING = 1, /* fetch engine is running */
220*4882a593Smuzhiyun CMDQ_STAT_LAST_PKT_DB = 2 /* last packet rung the doorbell */
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun /* T204 TX SW scheduler */
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /* Per T204 TX port */
226*4882a593Smuzhiyun struct sched_port {
227*4882a593Smuzhiyun unsigned int avail; /* available bits - quota */
228*4882a593Smuzhiyun unsigned int drain_bits_per_1024ns; /* drain rate */
229*4882a593Smuzhiyun unsigned int speed; /* drain rate, mbps */
230*4882a593Smuzhiyun unsigned int mtu; /* mtu size */
231*4882a593Smuzhiyun struct sk_buff_head skbq; /* pending skbs */
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /* Per T204 device */
235*4882a593Smuzhiyun struct sched {
236*4882a593Smuzhiyun ktime_t last_updated; /* last time quotas were computed */
237*4882a593Smuzhiyun unsigned int max_avail; /* max bits to be sent to any port */
238*4882a593Smuzhiyun unsigned int port; /* port index (round robin ports) */
239*4882a593Smuzhiyun unsigned int num; /* num skbs in per port queues */
240*4882a593Smuzhiyun struct sched_port p[MAX_NPORTS];
241*4882a593Smuzhiyun struct tasklet_struct sched_tsk;/* tasklet used to run scheduler */
242*4882a593Smuzhiyun struct sge *sge;
243*4882a593Smuzhiyun };
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun static void restart_sched(struct tasklet_struct *t);
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun /*
249*4882a593Smuzhiyun * Main SGE data structure
250*4882a593Smuzhiyun *
251*4882a593Smuzhiyun * Interrupts are handled by a single CPU and it is likely that on a MP system
252*4882a593Smuzhiyun * the application is migrated to another CPU. In that scenario, we try to
253*4882a593Smuzhiyun * separate the RX(in irq context) and TX state in order to decrease memory
254*4882a593Smuzhiyun * contention.
255*4882a593Smuzhiyun */
256*4882a593Smuzhiyun struct sge {
257*4882a593Smuzhiyun struct adapter *adapter; /* adapter backpointer */
258*4882a593Smuzhiyun struct net_device *netdev; /* netdevice backpointer */
259*4882a593Smuzhiyun struct freelQ freelQ[SGE_FREELQ_N]; /* buffer free lists */
260*4882a593Smuzhiyun struct respQ respQ; /* response Q */
261*4882a593Smuzhiyun unsigned long stopped_tx_queues; /* bitmap of suspended Tx queues */
262*4882a593Smuzhiyun unsigned int rx_pkt_pad; /* RX padding for L2 packets */
263*4882a593Smuzhiyun unsigned int jumbo_fl; /* jumbo freelist Q index */
264*4882a593Smuzhiyun unsigned int intrtimer_nres; /* no-resource interrupt timer */
265*4882a593Smuzhiyun unsigned int fixed_intrtimer;/* non-adaptive interrupt timer */
266*4882a593Smuzhiyun struct timer_list tx_reclaim_timer; /* reclaims TX buffers */
267*4882a593Smuzhiyun struct timer_list espibug_timer;
268*4882a593Smuzhiyun unsigned long espibug_timeout;
269*4882a593Smuzhiyun struct sk_buff *espibug_skb[MAX_NPORTS];
270*4882a593Smuzhiyun u32 sge_control; /* shadow value of sge control reg */
271*4882a593Smuzhiyun struct sge_intr_counts stats;
272*4882a593Smuzhiyun struct sge_port_stats __percpu *port_stats[MAX_NPORTS];
273*4882a593Smuzhiyun struct sched *tx_sched;
274*4882a593Smuzhiyun struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp;
275*4882a593Smuzhiyun };
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun static const u8 ch_mac_addr[ETH_ALEN] = {
278*4882a593Smuzhiyun 0x0, 0x7, 0x43, 0x0, 0x0, 0x0
279*4882a593Smuzhiyun };
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun /*
282*4882a593Smuzhiyun * stop tasklet and free all pending skb's
283*4882a593Smuzhiyun */
tx_sched_stop(struct sge * sge)284*4882a593Smuzhiyun static void tx_sched_stop(struct sge *sge)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun struct sched *s = sge->tx_sched;
287*4882a593Smuzhiyun int i;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun tasklet_kill(&s->sched_tsk);
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun for (i = 0; i < MAX_NPORTS; i++)
292*4882a593Smuzhiyun __skb_queue_purge(&s->p[s->port].skbq);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun /*
296*4882a593Smuzhiyun * t1_sched_update_parms() is called when the MTU or link speed changes. It
297*4882a593Smuzhiyun * re-computes scheduler parameters to scope with the change.
298*4882a593Smuzhiyun */
t1_sched_update_parms(struct sge * sge,unsigned int port,unsigned int mtu,unsigned int speed)299*4882a593Smuzhiyun unsigned int t1_sched_update_parms(struct sge *sge, unsigned int port,
300*4882a593Smuzhiyun unsigned int mtu, unsigned int speed)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun struct sched *s = sge->tx_sched;
303*4882a593Smuzhiyun struct sched_port *p = &s->p[port];
304*4882a593Smuzhiyun unsigned int max_avail_segs;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun pr_debug("%s mtu=%d speed=%d\n", __func__, mtu, speed);
307*4882a593Smuzhiyun if (speed)
308*4882a593Smuzhiyun p->speed = speed;
309*4882a593Smuzhiyun if (mtu)
310*4882a593Smuzhiyun p->mtu = mtu;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun if (speed || mtu) {
313*4882a593Smuzhiyun unsigned long long drain = 1024ULL * p->speed * (p->mtu - 40);
314*4882a593Smuzhiyun do_div(drain, (p->mtu + 50) * 1000);
315*4882a593Smuzhiyun p->drain_bits_per_1024ns = (unsigned int) drain;
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun if (p->speed < 1000)
318*4882a593Smuzhiyun p->drain_bits_per_1024ns =
319*4882a593Smuzhiyun 90 * p->drain_bits_per_1024ns / 100;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun if (board_info(sge->adapter)->board == CHBT_BOARD_CHT204) {
323*4882a593Smuzhiyun p->drain_bits_per_1024ns -= 16;
324*4882a593Smuzhiyun s->max_avail = max(4096U, p->mtu + 16 + 14 + 4);
325*4882a593Smuzhiyun max_avail_segs = max(1U, 4096 / (p->mtu - 40));
326*4882a593Smuzhiyun } else {
327*4882a593Smuzhiyun s->max_avail = 16384;
328*4882a593Smuzhiyun max_avail_segs = max(1U, 9000 / (p->mtu - 40));
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun pr_debug("t1_sched_update_parms: mtu %u speed %u max_avail %u "
332*4882a593Smuzhiyun "max_avail_segs %u drain_bits_per_1024ns %u\n", p->mtu,
333*4882a593Smuzhiyun p->speed, s->max_avail, max_avail_segs,
334*4882a593Smuzhiyun p->drain_bits_per_1024ns);
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun return max_avail_segs * (p->mtu - 40);
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun #if 0
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun /*
342*4882a593Smuzhiyun * t1_sched_max_avail_bytes() tells the scheduler the maximum amount of
343*4882a593Smuzhiyun * data that can be pushed per port.
344*4882a593Smuzhiyun */
345*4882a593Smuzhiyun void t1_sched_set_max_avail_bytes(struct sge *sge, unsigned int val)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun struct sched *s = sge->tx_sched;
348*4882a593Smuzhiyun unsigned int i;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun s->max_avail = val;
351*4882a593Smuzhiyun for (i = 0; i < MAX_NPORTS; i++)
352*4882a593Smuzhiyun t1_sched_update_parms(sge, i, 0, 0);
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun /*
356*4882a593Smuzhiyun * t1_sched_set_drain_bits_per_us() tells the scheduler at which rate a port
357*4882a593Smuzhiyun * is draining.
358*4882a593Smuzhiyun */
359*4882a593Smuzhiyun void t1_sched_set_drain_bits_per_us(struct sge *sge, unsigned int port,
360*4882a593Smuzhiyun unsigned int val)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun struct sched *s = sge->tx_sched;
363*4882a593Smuzhiyun struct sched_port *p = &s->p[port];
364*4882a593Smuzhiyun p->drain_bits_per_1024ns = val * 1024 / 1000;
365*4882a593Smuzhiyun t1_sched_update_parms(sge, port, 0, 0);
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun #endif /* 0 */
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun /*
371*4882a593Smuzhiyun * tx_sched_init() allocates resources and does basic initialization.
372*4882a593Smuzhiyun */
tx_sched_init(struct sge * sge)373*4882a593Smuzhiyun static int tx_sched_init(struct sge *sge)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun struct sched *s;
376*4882a593Smuzhiyun int i;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun s = kzalloc(sizeof (struct sched), GFP_KERNEL);
379*4882a593Smuzhiyun if (!s)
380*4882a593Smuzhiyun return -ENOMEM;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun pr_debug("tx_sched_init\n");
383*4882a593Smuzhiyun tasklet_setup(&s->sched_tsk, restart_sched);
384*4882a593Smuzhiyun s->sge = sge;
385*4882a593Smuzhiyun sge->tx_sched = s;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun for (i = 0; i < MAX_NPORTS; i++) {
388*4882a593Smuzhiyun skb_queue_head_init(&s->p[i].skbq);
389*4882a593Smuzhiyun t1_sched_update_parms(sge, i, 1500, 1000);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /*
396*4882a593Smuzhiyun * sched_update_avail() computes the delta since the last time it was called
397*4882a593Smuzhiyun * and updates the per port quota (number of bits that can be sent to the any
398*4882a593Smuzhiyun * port).
399*4882a593Smuzhiyun */
sched_update_avail(struct sge * sge)400*4882a593Smuzhiyun static inline int sched_update_avail(struct sge *sge)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun struct sched *s = sge->tx_sched;
403*4882a593Smuzhiyun ktime_t now = ktime_get();
404*4882a593Smuzhiyun unsigned int i;
405*4882a593Smuzhiyun long long delta_time_ns;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun delta_time_ns = ktime_to_ns(ktime_sub(now, s->last_updated));
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun pr_debug("sched_update_avail delta=%lld\n", delta_time_ns);
410*4882a593Smuzhiyun if (delta_time_ns < 15000)
411*4882a593Smuzhiyun return 0;
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun for (i = 0; i < MAX_NPORTS; i++) {
414*4882a593Smuzhiyun struct sched_port *p = &s->p[i];
415*4882a593Smuzhiyun unsigned int delta_avail;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun delta_avail = (p->drain_bits_per_1024ns * delta_time_ns) >> 13;
418*4882a593Smuzhiyun p->avail = min(p->avail + delta_avail, s->max_avail);
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun s->last_updated = now;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun return 1;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun /*
427*4882a593Smuzhiyun * sched_skb() is called from two different places. In the tx path, any
428*4882a593Smuzhiyun * packet generating load on an output port will call sched_skb()
429*4882a593Smuzhiyun * (skb != NULL). In addition, sched_skb() is called from the irq/soft irq
430*4882a593Smuzhiyun * context (skb == NULL).
431*4882a593Smuzhiyun * The scheduler only returns a skb (which will then be sent) if the
432*4882a593Smuzhiyun * length of the skb is <= the current quota of the output port.
433*4882a593Smuzhiyun */
sched_skb(struct sge * sge,struct sk_buff * skb,unsigned int credits)434*4882a593Smuzhiyun static struct sk_buff *sched_skb(struct sge *sge, struct sk_buff *skb,
435*4882a593Smuzhiyun unsigned int credits)
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun struct sched *s = sge->tx_sched;
438*4882a593Smuzhiyun struct sk_buff_head *skbq;
439*4882a593Smuzhiyun unsigned int i, len, update = 1;
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun pr_debug("sched_skb %p\n", skb);
442*4882a593Smuzhiyun if (!skb) {
443*4882a593Smuzhiyun if (!s->num)
444*4882a593Smuzhiyun return NULL;
445*4882a593Smuzhiyun } else {
446*4882a593Smuzhiyun skbq = &s->p[skb->dev->if_port].skbq;
447*4882a593Smuzhiyun __skb_queue_tail(skbq, skb);
448*4882a593Smuzhiyun s->num++;
449*4882a593Smuzhiyun skb = NULL;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun if (credits < MAX_SKB_FRAGS + 1)
453*4882a593Smuzhiyun goto out;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun again:
456*4882a593Smuzhiyun for (i = 0; i < MAX_NPORTS; i++) {
457*4882a593Smuzhiyun s->port = (s->port + 1) & (MAX_NPORTS - 1);
458*4882a593Smuzhiyun skbq = &s->p[s->port].skbq;
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun skb = skb_peek(skbq);
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun if (!skb)
463*4882a593Smuzhiyun continue;
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun len = skb->len;
466*4882a593Smuzhiyun if (len <= s->p[s->port].avail) {
467*4882a593Smuzhiyun s->p[s->port].avail -= len;
468*4882a593Smuzhiyun s->num--;
469*4882a593Smuzhiyun __skb_unlink(skb, skbq);
470*4882a593Smuzhiyun goto out;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun skb = NULL;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun if (update-- && sched_update_avail(sge))
476*4882a593Smuzhiyun goto again;
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun out:
479*4882a593Smuzhiyun /* If there are more pending skbs, we use the hardware to schedule us
480*4882a593Smuzhiyun * again.
481*4882a593Smuzhiyun */
482*4882a593Smuzhiyun if (s->num && !skb) {
483*4882a593Smuzhiyun struct cmdQ *q = &sge->cmdQ[0];
484*4882a593Smuzhiyun clear_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
485*4882a593Smuzhiyun if (test_and_set_bit(CMDQ_STAT_RUNNING, &q->status) == 0) {
486*4882a593Smuzhiyun set_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
487*4882a593Smuzhiyun writel(F_CMDQ0_ENABLE, sge->adapter->regs + A_SG_DOORBELL);
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun pr_debug("sched_skb ret %p\n", skb);
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun return skb;
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun /*
496*4882a593Smuzhiyun * PIO to indicate that memory mapped Q contains valid descriptor(s).
497*4882a593Smuzhiyun */
doorbell_pio(struct adapter * adapter,u32 val)498*4882a593Smuzhiyun static inline void doorbell_pio(struct adapter *adapter, u32 val)
499*4882a593Smuzhiyun {
500*4882a593Smuzhiyun wmb();
501*4882a593Smuzhiyun writel(val, adapter->regs + A_SG_DOORBELL);
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun /*
505*4882a593Smuzhiyun * Frees all RX buffers on the freelist Q. The caller must make sure that
506*4882a593Smuzhiyun * the SGE is turned off before calling this function.
507*4882a593Smuzhiyun */
free_freelQ_buffers(struct pci_dev * pdev,struct freelQ * q)508*4882a593Smuzhiyun static void free_freelQ_buffers(struct pci_dev *pdev, struct freelQ *q)
509*4882a593Smuzhiyun {
510*4882a593Smuzhiyun unsigned int cidx = q->cidx;
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun while (q->credits--) {
513*4882a593Smuzhiyun struct freelQ_ce *ce = &q->centries[cidx];
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun dma_unmap_single(&pdev->dev, dma_unmap_addr(ce, dma_addr),
516*4882a593Smuzhiyun dma_unmap_len(ce, dma_len), DMA_FROM_DEVICE);
517*4882a593Smuzhiyun dev_kfree_skb(ce->skb);
518*4882a593Smuzhiyun ce->skb = NULL;
519*4882a593Smuzhiyun if (++cidx == q->size)
520*4882a593Smuzhiyun cidx = 0;
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun /*
525*4882a593Smuzhiyun * Free RX free list and response queue resources.
526*4882a593Smuzhiyun */
free_rx_resources(struct sge * sge)527*4882a593Smuzhiyun static void free_rx_resources(struct sge *sge)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun struct pci_dev *pdev = sge->adapter->pdev;
530*4882a593Smuzhiyun unsigned int size, i;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun if (sge->respQ.entries) {
533*4882a593Smuzhiyun size = sizeof(struct respQ_e) * sge->respQ.size;
534*4882a593Smuzhiyun dma_free_coherent(&pdev->dev, size, sge->respQ.entries,
535*4882a593Smuzhiyun sge->respQ.dma_addr);
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun for (i = 0; i < SGE_FREELQ_N; i++) {
539*4882a593Smuzhiyun struct freelQ *q = &sge->freelQ[i];
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun if (q->centries) {
542*4882a593Smuzhiyun free_freelQ_buffers(pdev, q);
543*4882a593Smuzhiyun kfree(q->centries);
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun if (q->entries) {
546*4882a593Smuzhiyun size = sizeof(struct freelQ_e) * q->size;
547*4882a593Smuzhiyun dma_free_coherent(&pdev->dev, size, q->entries,
548*4882a593Smuzhiyun q->dma_addr);
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun /*
554*4882a593Smuzhiyun * Allocates basic RX resources, consisting of memory mapped freelist Qs and a
555*4882a593Smuzhiyun * response queue.
556*4882a593Smuzhiyun */
alloc_rx_resources(struct sge * sge,struct sge_params * p)557*4882a593Smuzhiyun static int alloc_rx_resources(struct sge *sge, struct sge_params *p)
558*4882a593Smuzhiyun {
559*4882a593Smuzhiyun struct pci_dev *pdev = sge->adapter->pdev;
560*4882a593Smuzhiyun unsigned int size, i;
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun for (i = 0; i < SGE_FREELQ_N; i++) {
563*4882a593Smuzhiyun struct freelQ *q = &sge->freelQ[i];
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun q->genbit = 1;
566*4882a593Smuzhiyun q->size = p->freelQ_size[i];
567*4882a593Smuzhiyun q->dma_offset = sge->rx_pkt_pad ? 0 : NET_IP_ALIGN;
568*4882a593Smuzhiyun size = sizeof(struct freelQ_e) * q->size;
569*4882a593Smuzhiyun q->entries = dma_alloc_coherent(&pdev->dev, size,
570*4882a593Smuzhiyun &q->dma_addr, GFP_KERNEL);
571*4882a593Smuzhiyun if (!q->entries)
572*4882a593Smuzhiyun goto err_no_mem;
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun size = sizeof(struct freelQ_ce) * q->size;
575*4882a593Smuzhiyun q->centries = kzalloc(size, GFP_KERNEL);
576*4882a593Smuzhiyun if (!q->centries)
577*4882a593Smuzhiyun goto err_no_mem;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun /*
581*4882a593Smuzhiyun * Calculate the buffer sizes for the two free lists. FL0 accommodates
582*4882a593Smuzhiyun * regular sized Ethernet frames, FL1 is sized not to exceed 16K,
583*4882a593Smuzhiyun * including all the sk_buff overhead.
584*4882a593Smuzhiyun *
585*4882a593Smuzhiyun * Note: For T2 FL0 and FL1 are reversed.
586*4882a593Smuzhiyun */
587*4882a593Smuzhiyun sge->freelQ[!sge->jumbo_fl].rx_buffer_size = SGE_RX_SM_BUF_SIZE +
588*4882a593Smuzhiyun sizeof(struct cpl_rx_data) +
589*4882a593Smuzhiyun sge->freelQ[!sge->jumbo_fl].dma_offset;
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun size = (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun sge->freelQ[sge->jumbo_fl].rx_buffer_size = size;
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun /*
596*4882a593Smuzhiyun * Setup which skb recycle Q should be used when recycling buffers from
597*4882a593Smuzhiyun * each free list.
598*4882a593Smuzhiyun */
599*4882a593Smuzhiyun sge->freelQ[!sge->jumbo_fl].recycleq_idx = 0;
600*4882a593Smuzhiyun sge->freelQ[sge->jumbo_fl].recycleq_idx = 1;
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun sge->respQ.genbit = 1;
603*4882a593Smuzhiyun sge->respQ.size = SGE_RESPQ_E_N;
604*4882a593Smuzhiyun sge->respQ.credits = 0;
605*4882a593Smuzhiyun size = sizeof(struct respQ_e) * sge->respQ.size;
606*4882a593Smuzhiyun sge->respQ.entries =
607*4882a593Smuzhiyun dma_alloc_coherent(&pdev->dev, size, &sge->respQ.dma_addr,
608*4882a593Smuzhiyun GFP_KERNEL);
609*4882a593Smuzhiyun if (!sge->respQ.entries)
610*4882a593Smuzhiyun goto err_no_mem;
611*4882a593Smuzhiyun return 0;
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun err_no_mem:
614*4882a593Smuzhiyun free_rx_resources(sge);
615*4882a593Smuzhiyun return -ENOMEM;
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun /*
619*4882a593Smuzhiyun * Reclaims n TX descriptors and frees the buffers associated with them.
620*4882a593Smuzhiyun */
free_cmdQ_buffers(struct sge * sge,struct cmdQ * q,unsigned int n)621*4882a593Smuzhiyun static void free_cmdQ_buffers(struct sge *sge, struct cmdQ *q, unsigned int n)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun struct cmdQ_ce *ce;
624*4882a593Smuzhiyun struct pci_dev *pdev = sge->adapter->pdev;
625*4882a593Smuzhiyun unsigned int cidx = q->cidx;
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun q->in_use -= n;
628*4882a593Smuzhiyun ce = &q->centries[cidx];
629*4882a593Smuzhiyun while (n--) {
630*4882a593Smuzhiyun if (likely(dma_unmap_len(ce, dma_len))) {
631*4882a593Smuzhiyun dma_unmap_single(&pdev->dev,
632*4882a593Smuzhiyun dma_unmap_addr(ce, dma_addr),
633*4882a593Smuzhiyun dma_unmap_len(ce, dma_len),
634*4882a593Smuzhiyun DMA_TO_DEVICE);
635*4882a593Smuzhiyun if (q->sop)
636*4882a593Smuzhiyun q->sop = 0;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun if (ce->skb) {
639*4882a593Smuzhiyun dev_kfree_skb_any(ce->skb);
640*4882a593Smuzhiyun q->sop = 1;
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun ce++;
643*4882a593Smuzhiyun if (++cidx == q->size) {
644*4882a593Smuzhiyun cidx = 0;
645*4882a593Smuzhiyun ce = q->centries;
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun q->cidx = cidx;
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun /*
652*4882a593Smuzhiyun * Free TX resources.
653*4882a593Smuzhiyun *
654*4882a593Smuzhiyun * Assumes that SGE is stopped and all interrupts are disabled.
655*4882a593Smuzhiyun */
free_tx_resources(struct sge * sge)656*4882a593Smuzhiyun static void free_tx_resources(struct sge *sge)
657*4882a593Smuzhiyun {
658*4882a593Smuzhiyun struct pci_dev *pdev = sge->adapter->pdev;
659*4882a593Smuzhiyun unsigned int size, i;
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun for (i = 0; i < SGE_CMDQ_N; i++) {
662*4882a593Smuzhiyun struct cmdQ *q = &sge->cmdQ[i];
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun if (q->centries) {
665*4882a593Smuzhiyun if (q->in_use)
666*4882a593Smuzhiyun free_cmdQ_buffers(sge, q, q->in_use);
667*4882a593Smuzhiyun kfree(q->centries);
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun if (q->entries) {
670*4882a593Smuzhiyun size = sizeof(struct cmdQ_e) * q->size;
671*4882a593Smuzhiyun dma_free_coherent(&pdev->dev, size, q->entries,
672*4882a593Smuzhiyun q->dma_addr);
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun }
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun /*
678*4882a593Smuzhiyun * Allocates basic TX resources, consisting of memory mapped command Qs.
679*4882a593Smuzhiyun */
alloc_tx_resources(struct sge * sge,struct sge_params * p)680*4882a593Smuzhiyun static int alloc_tx_resources(struct sge *sge, struct sge_params *p)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun struct pci_dev *pdev = sge->adapter->pdev;
683*4882a593Smuzhiyun unsigned int size, i;
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun for (i = 0; i < SGE_CMDQ_N; i++) {
686*4882a593Smuzhiyun struct cmdQ *q = &sge->cmdQ[i];
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun q->genbit = 1;
689*4882a593Smuzhiyun q->sop = 1;
690*4882a593Smuzhiyun q->size = p->cmdQ_size[i];
691*4882a593Smuzhiyun q->in_use = 0;
692*4882a593Smuzhiyun q->status = 0;
693*4882a593Smuzhiyun q->processed = q->cleaned = 0;
694*4882a593Smuzhiyun q->stop_thres = 0;
695*4882a593Smuzhiyun spin_lock_init(&q->lock);
696*4882a593Smuzhiyun size = sizeof(struct cmdQ_e) * q->size;
697*4882a593Smuzhiyun q->entries = dma_alloc_coherent(&pdev->dev, size,
698*4882a593Smuzhiyun &q->dma_addr, GFP_KERNEL);
699*4882a593Smuzhiyun if (!q->entries)
700*4882a593Smuzhiyun goto err_no_mem;
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun size = sizeof(struct cmdQ_ce) * q->size;
703*4882a593Smuzhiyun q->centries = kzalloc(size, GFP_KERNEL);
704*4882a593Smuzhiyun if (!q->centries)
705*4882a593Smuzhiyun goto err_no_mem;
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun /*
709*4882a593Smuzhiyun * CommandQ 0 handles Ethernet and TOE packets, while queue 1 is TOE
710*4882a593Smuzhiyun * only. For queue 0 set the stop threshold so we can handle one more
711*4882a593Smuzhiyun * packet from each port, plus reserve an additional 24 entries for
712*4882a593Smuzhiyun * Ethernet packets only. Queue 1 never suspends nor do we reserve
713*4882a593Smuzhiyun * space for Ethernet packets.
714*4882a593Smuzhiyun */
715*4882a593Smuzhiyun sge->cmdQ[0].stop_thres = sge->adapter->params.nports *
716*4882a593Smuzhiyun (MAX_SKB_FRAGS + 1);
717*4882a593Smuzhiyun return 0;
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun err_no_mem:
720*4882a593Smuzhiyun free_tx_resources(sge);
721*4882a593Smuzhiyun return -ENOMEM;
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun
setup_ring_params(struct adapter * adapter,u64 addr,u32 size,int base_reg_lo,int base_reg_hi,int size_reg)724*4882a593Smuzhiyun static inline void setup_ring_params(struct adapter *adapter, u64 addr,
725*4882a593Smuzhiyun u32 size, int base_reg_lo,
726*4882a593Smuzhiyun int base_reg_hi, int size_reg)
727*4882a593Smuzhiyun {
728*4882a593Smuzhiyun writel((u32)addr, adapter->regs + base_reg_lo);
729*4882a593Smuzhiyun writel(addr >> 32, adapter->regs + base_reg_hi);
730*4882a593Smuzhiyun writel(size, adapter->regs + size_reg);
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun /*
734*4882a593Smuzhiyun * Enable/disable VLAN acceleration.
735*4882a593Smuzhiyun */
t1_vlan_mode(struct adapter * adapter,netdev_features_t features)736*4882a593Smuzhiyun void t1_vlan_mode(struct adapter *adapter, netdev_features_t features)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun struct sge *sge = adapter->sge;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun if (features & NETIF_F_HW_VLAN_CTAG_RX)
741*4882a593Smuzhiyun sge->sge_control |= F_VLAN_XTRACT;
742*4882a593Smuzhiyun else
743*4882a593Smuzhiyun sge->sge_control &= ~F_VLAN_XTRACT;
744*4882a593Smuzhiyun if (adapter->open_device_map) {
745*4882a593Smuzhiyun writel(sge->sge_control, adapter->regs + A_SG_CONTROL);
746*4882a593Smuzhiyun readl(adapter->regs + A_SG_CONTROL); /* flush */
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun /*
751*4882a593Smuzhiyun * Programs the various SGE registers. However, the engine is not yet enabled,
752*4882a593Smuzhiyun * but sge->sge_control is setup and ready to go.
753*4882a593Smuzhiyun */
configure_sge(struct sge * sge,struct sge_params * p)754*4882a593Smuzhiyun static void configure_sge(struct sge *sge, struct sge_params *p)
755*4882a593Smuzhiyun {
756*4882a593Smuzhiyun struct adapter *ap = sge->adapter;
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun writel(0, ap->regs + A_SG_CONTROL);
759*4882a593Smuzhiyun setup_ring_params(ap, sge->cmdQ[0].dma_addr, sge->cmdQ[0].size,
760*4882a593Smuzhiyun A_SG_CMD0BASELWR, A_SG_CMD0BASEUPR, A_SG_CMD0SIZE);
761*4882a593Smuzhiyun setup_ring_params(ap, sge->cmdQ[1].dma_addr, sge->cmdQ[1].size,
762*4882a593Smuzhiyun A_SG_CMD1BASELWR, A_SG_CMD1BASEUPR, A_SG_CMD1SIZE);
763*4882a593Smuzhiyun setup_ring_params(ap, sge->freelQ[0].dma_addr,
764*4882a593Smuzhiyun sge->freelQ[0].size, A_SG_FL0BASELWR,
765*4882a593Smuzhiyun A_SG_FL0BASEUPR, A_SG_FL0SIZE);
766*4882a593Smuzhiyun setup_ring_params(ap, sge->freelQ[1].dma_addr,
767*4882a593Smuzhiyun sge->freelQ[1].size, A_SG_FL1BASELWR,
768*4882a593Smuzhiyun A_SG_FL1BASEUPR, A_SG_FL1SIZE);
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun /* The threshold comparison uses <. */
771*4882a593Smuzhiyun writel(SGE_RX_SM_BUF_SIZE + 1, ap->regs + A_SG_FLTHRESHOLD);
772*4882a593Smuzhiyun
773*4882a593Smuzhiyun setup_ring_params(ap, sge->respQ.dma_addr, sge->respQ.size,
774*4882a593Smuzhiyun A_SG_RSPBASELWR, A_SG_RSPBASEUPR, A_SG_RSPSIZE);
775*4882a593Smuzhiyun writel((u32)sge->respQ.size - 1, ap->regs + A_SG_RSPQUEUECREDIT);
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun sge->sge_control = F_CMDQ0_ENABLE | F_CMDQ1_ENABLE | F_FL0_ENABLE |
778*4882a593Smuzhiyun F_FL1_ENABLE | F_CPL_ENABLE | F_RESPONSE_QUEUE_ENABLE |
779*4882a593Smuzhiyun V_CMDQ_PRIORITY(2) | F_DISABLE_CMDQ1_GTS | F_ISCSI_COALESCE |
780*4882a593Smuzhiyun V_RX_PKT_OFFSET(sge->rx_pkt_pad);
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun #if defined(__BIG_ENDIAN_BITFIELD)
783*4882a593Smuzhiyun sge->sge_control |= F_ENABLE_BIG_ENDIAN;
784*4882a593Smuzhiyun #endif
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun /* Initialize no-resource timer */
787*4882a593Smuzhiyun sge->intrtimer_nres = SGE_INTRTIMER_NRES * core_ticks_per_usec(ap);
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun t1_sge_set_coalesce_params(sge, p);
790*4882a593Smuzhiyun }
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun /*
793*4882a593Smuzhiyun * Return the payload capacity of the jumbo free-list buffers.
794*4882a593Smuzhiyun */
jumbo_payload_capacity(const struct sge * sge)795*4882a593Smuzhiyun static inline unsigned int jumbo_payload_capacity(const struct sge *sge)
796*4882a593Smuzhiyun {
797*4882a593Smuzhiyun return sge->freelQ[sge->jumbo_fl].rx_buffer_size -
798*4882a593Smuzhiyun sge->freelQ[sge->jumbo_fl].dma_offset -
799*4882a593Smuzhiyun sizeof(struct cpl_rx_data);
800*4882a593Smuzhiyun }
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun /*
803*4882a593Smuzhiyun * Frees all SGE related resources and the sge structure itself
804*4882a593Smuzhiyun */
t1_sge_destroy(struct sge * sge)805*4882a593Smuzhiyun void t1_sge_destroy(struct sge *sge)
806*4882a593Smuzhiyun {
807*4882a593Smuzhiyun int i;
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun for_each_port(sge->adapter, i)
810*4882a593Smuzhiyun free_percpu(sge->port_stats[i]);
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun kfree(sge->tx_sched);
813*4882a593Smuzhiyun free_tx_resources(sge);
814*4882a593Smuzhiyun free_rx_resources(sge);
815*4882a593Smuzhiyun kfree(sge);
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun
818*4882a593Smuzhiyun /*
819*4882a593Smuzhiyun * Allocates new RX buffers on the freelist Q (and tracks them on the freelist
820*4882a593Smuzhiyun * context Q) until the Q is full or alloc_skb fails.
821*4882a593Smuzhiyun *
822*4882a593Smuzhiyun * It is possible that the generation bits already match, indicating that the
823*4882a593Smuzhiyun * buffer is already valid and nothing needs to be done. This happens when we
824*4882a593Smuzhiyun * copied a received buffer into a new sk_buff during the interrupt processing.
825*4882a593Smuzhiyun *
826*4882a593Smuzhiyun * If the SGE doesn't automatically align packets properly (!sge->rx_pkt_pad),
827*4882a593Smuzhiyun * we specify a RX_OFFSET in order to make sure that the IP header is 4B
828*4882a593Smuzhiyun * aligned.
829*4882a593Smuzhiyun */
refill_free_list(struct sge * sge,struct freelQ * q)830*4882a593Smuzhiyun static void refill_free_list(struct sge *sge, struct freelQ *q)
831*4882a593Smuzhiyun {
832*4882a593Smuzhiyun struct pci_dev *pdev = sge->adapter->pdev;
833*4882a593Smuzhiyun struct freelQ_ce *ce = &q->centries[q->pidx];
834*4882a593Smuzhiyun struct freelQ_e *e = &q->entries[q->pidx];
835*4882a593Smuzhiyun unsigned int dma_len = q->rx_buffer_size - q->dma_offset;
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun while (q->credits < q->size) {
838*4882a593Smuzhiyun struct sk_buff *skb;
839*4882a593Smuzhiyun dma_addr_t mapping;
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun skb = dev_alloc_skb(q->rx_buffer_size);
842*4882a593Smuzhiyun if (!skb)
843*4882a593Smuzhiyun break;
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun skb_reserve(skb, q->dma_offset);
846*4882a593Smuzhiyun mapping = dma_map_single(&pdev->dev, skb->data, dma_len,
847*4882a593Smuzhiyun DMA_FROM_DEVICE);
848*4882a593Smuzhiyun skb_reserve(skb, sge->rx_pkt_pad);
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun ce->skb = skb;
851*4882a593Smuzhiyun dma_unmap_addr_set(ce, dma_addr, mapping);
852*4882a593Smuzhiyun dma_unmap_len_set(ce, dma_len, dma_len);
853*4882a593Smuzhiyun e->addr_lo = (u32)mapping;
854*4882a593Smuzhiyun e->addr_hi = (u64)mapping >> 32;
855*4882a593Smuzhiyun e->len_gen = V_CMD_LEN(dma_len) | V_CMD_GEN1(q->genbit);
856*4882a593Smuzhiyun wmb();
857*4882a593Smuzhiyun e->gen2 = V_CMD_GEN2(q->genbit);
858*4882a593Smuzhiyun
859*4882a593Smuzhiyun e++;
860*4882a593Smuzhiyun ce++;
861*4882a593Smuzhiyun if (++q->pidx == q->size) {
862*4882a593Smuzhiyun q->pidx = 0;
863*4882a593Smuzhiyun q->genbit ^= 1;
864*4882a593Smuzhiyun ce = q->centries;
865*4882a593Smuzhiyun e = q->entries;
866*4882a593Smuzhiyun }
867*4882a593Smuzhiyun q->credits++;
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun /*
872*4882a593Smuzhiyun * Calls refill_free_list for both free lists. If we cannot fill at least 1/4
873*4882a593Smuzhiyun * of both rings, we go into 'few interrupt mode' in order to give the system
874*4882a593Smuzhiyun * time to free up resources.
875*4882a593Smuzhiyun */
freelQs_empty(struct sge * sge)876*4882a593Smuzhiyun static void freelQs_empty(struct sge *sge)
877*4882a593Smuzhiyun {
878*4882a593Smuzhiyun struct adapter *adapter = sge->adapter;
879*4882a593Smuzhiyun u32 irq_reg = readl(adapter->regs + A_SG_INT_ENABLE);
880*4882a593Smuzhiyun u32 irqholdoff_reg;
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun refill_free_list(sge, &sge->freelQ[0]);
883*4882a593Smuzhiyun refill_free_list(sge, &sge->freelQ[1]);
884*4882a593Smuzhiyun
885*4882a593Smuzhiyun if (sge->freelQ[0].credits > (sge->freelQ[0].size >> 2) &&
886*4882a593Smuzhiyun sge->freelQ[1].credits > (sge->freelQ[1].size >> 2)) {
887*4882a593Smuzhiyun irq_reg |= F_FL_EXHAUSTED;
888*4882a593Smuzhiyun irqholdoff_reg = sge->fixed_intrtimer;
889*4882a593Smuzhiyun } else {
890*4882a593Smuzhiyun /* Clear the F_FL_EXHAUSTED interrupts for now */
891*4882a593Smuzhiyun irq_reg &= ~F_FL_EXHAUSTED;
892*4882a593Smuzhiyun irqholdoff_reg = sge->intrtimer_nres;
893*4882a593Smuzhiyun }
894*4882a593Smuzhiyun writel(irqholdoff_reg, adapter->regs + A_SG_INTRTIMER);
895*4882a593Smuzhiyun writel(irq_reg, adapter->regs + A_SG_INT_ENABLE);
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun /* We reenable the Qs to force a freelist GTS interrupt later */
898*4882a593Smuzhiyun doorbell_pio(adapter, F_FL0_ENABLE | F_FL1_ENABLE);
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun #define SGE_PL_INTR_MASK (F_PL_INTR_SGE_ERR | F_PL_INTR_SGE_DATA)
902*4882a593Smuzhiyun #define SGE_INT_FATAL (F_RESPQ_OVERFLOW | F_PACKET_TOO_BIG | F_PACKET_MISMATCH)
903*4882a593Smuzhiyun #define SGE_INT_ENABLE (F_RESPQ_EXHAUSTED | F_RESPQ_OVERFLOW | \
904*4882a593Smuzhiyun F_FL_EXHAUSTED | F_PACKET_TOO_BIG | F_PACKET_MISMATCH)
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun /*
907*4882a593Smuzhiyun * Disable SGE Interrupts
908*4882a593Smuzhiyun */
t1_sge_intr_disable(struct sge * sge)909*4882a593Smuzhiyun void t1_sge_intr_disable(struct sge *sge)
910*4882a593Smuzhiyun {
911*4882a593Smuzhiyun u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
912*4882a593Smuzhiyun
913*4882a593Smuzhiyun writel(val & ~SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
914*4882a593Smuzhiyun writel(0, sge->adapter->regs + A_SG_INT_ENABLE);
915*4882a593Smuzhiyun }
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun /*
918*4882a593Smuzhiyun * Enable SGE interrupts.
919*4882a593Smuzhiyun */
t1_sge_intr_enable(struct sge * sge)920*4882a593Smuzhiyun void t1_sge_intr_enable(struct sge *sge)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun u32 en = SGE_INT_ENABLE;
923*4882a593Smuzhiyun u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun if (sge->adapter->port[0].dev->hw_features & NETIF_F_TSO)
926*4882a593Smuzhiyun en &= ~F_PACKET_TOO_BIG;
927*4882a593Smuzhiyun writel(en, sge->adapter->regs + A_SG_INT_ENABLE);
928*4882a593Smuzhiyun writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
929*4882a593Smuzhiyun }
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun /*
932*4882a593Smuzhiyun * Clear SGE interrupts.
933*4882a593Smuzhiyun */
t1_sge_intr_clear(struct sge * sge)934*4882a593Smuzhiyun void t1_sge_intr_clear(struct sge *sge)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun writel(SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_CAUSE);
937*4882a593Smuzhiyun writel(0xffffffff, sge->adapter->regs + A_SG_INT_CAUSE);
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun /*
941*4882a593Smuzhiyun * SGE 'Error' interrupt handler
942*4882a593Smuzhiyun */
t1_sge_intr_error_handler(struct sge * sge)943*4882a593Smuzhiyun int t1_sge_intr_error_handler(struct sge *sge)
944*4882a593Smuzhiyun {
945*4882a593Smuzhiyun struct adapter *adapter = sge->adapter;
946*4882a593Smuzhiyun u32 cause = readl(adapter->regs + A_SG_INT_CAUSE);
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
949*4882a593Smuzhiyun cause &= ~F_PACKET_TOO_BIG;
950*4882a593Smuzhiyun if (cause & F_RESPQ_EXHAUSTED)
951*4882a593Smuzhiyun sge->stats.respQ_empty++;
952*4882a593Smuzhiyun if (cause & F_RESPQ_OVERFLOW) {
953*4882a593Smuzhiyun sge->stats.respQ_overflow++;
954*4882a593Smuzhiyun pr_alert("%s: SGE response queue overflow\n",
955*4882a593Smuzhiyun adapter->name);
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun if (cause & F_FL_EXHAUSTED) {
958*4882a593Smuzhiyun sge->stats.freelistQ_empty++;
959*4882a593Smuzhiyun freelQs_empty(sge);
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun if (cause & F_PACKET_TOO_BIG) {
962*4882a593Smuzhiyun sge->stats.pkt_too_big++;
963*4882a593Smuzhiyun pr_alert("%s: SGE max packet size exceeded\n",
964*4882a593Smuzhiyun adapter->name);
965*4882a593Smuzhiyun }
966*4882a593Smuzhiyun if (cause & F_PACKET_MISMATCH) {
967*4882a593Smuzhiyun sge->stats.pkt_mismatch++;
968*4882a593Smuzhiyun pr_alert("%s: SGE packet mismatch\n", adapter->name);
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun if (cause & SGE_INT_FATAL)
971*4882a593Smuzhiyun t1_fatal_err(adapter);
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun writel(cause, adapter->regs + A_SG_INT_CAUSE);
974*4882a593Smuzhiyun return 0;
975*4882a593Smuzhiyun }
976*4882a593Smuzhiyun
t1_sge_get_intr_counts(const struct sge * sge)977*4882a593Smuzhiyun const struct sge_intr_counts *t1_sge_get_intr_counts(const struct sge *sge)
978*4882a593Smuzhiyun {
979*4882a593Smuzhiyun return &sge->stats;
980*4882a593Smuzhiyun }
981*4882a593Smuzhiyun
t1_sge_get_port_stats(const struct sge * sge,int port,struct sge_port_stats * ss)982*4882a593Smuzhiyun void t1_sge_get_port_stats(const struct sge *sge, int port,
983*4882a593Smuzhiyun struct sge_port_stats *ss)
984*4882a593Smuzhiyun {
985*4882a593Smuzhiyun int cpu;
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun memset(ss, 0, sizeof(*ss));
988*4882a593Smuzhiyun for_each_possible_cpu(cpu) {
989*4882a593Smuzhiyun struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[port], cpu);
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun ss->rx_cso_good += st->rx_cso_good;
992*4882a593Smuzhiyun ss->tx_cso += st->tx_cso;
993*4882a593Smuzhiyun ss->tx_tso += st->tx_tso;
994*4882a593Smuzhiyun ss->tx_need_hdrroom += st->tx_need_hdrroom;
995*4882a593Smuzhiyun ss->vlan_xtract += st->vlan_xtract;
996*4882a593Smuzhiyun ss->vlan_insert += st->vlan_insert;
997*4882a593Smuzhiyun }
998*4882a593Smuzhiyun }
999*4882a593Smuzhiyun
1000*4882a593Smuzhiyun /**
1001*4882a593Smuzhiyun * recycle_fl_buf - recycle a free list buffer
1002*4882a593Smuzhiyun * @fl: the free list
1003*4882a593Smuzhiyun * @idx: index of buffer to recycle
1004*4882a593Smuzhiyun *
1005*4882a593Smuzhiyun * Recycles the specified buffer on the given free list by adding it at
1006*4882a593Smuzhiyun * the next available slot on the list.
1007*4882a593Smuzhiyun */
recycle_fl_buf(struct freelQ * fl,int idx)1008*4882a593Smuzhiyun static void recycle_fl_buf(struct freelQ *fl, int idx)
1009*4882a593Smuzhiyun {
1010*4882a593Smuzhiyun struct freelQ_e *from = &fl->entries[idx];
1011*4882a593Smuzhiyun struct freelQ_e *to = &fl->entries[fl->pidx];
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun fl->centries[fl->pidx] = fl->centries[idx];
1014*4882a593Smuzhiyun to->addr_lo = from->addr_lo;
1015*4882a593Smuzhiyun to->addr_hi = from->addr_hi;
1016*4882a593Smuzhiyun to->len_gen = G_CMD_LEN(from->len_gen) | V_CMD_GEN1(fl->genbit);
1017*4882a593Smuzhiyun wmb();
1018*4882a593Smuzhiyun to->gen2 = V_CMD_GEN2(fl->genbit);
1019*4882a593Smuzhiyun fl->credits++;
1020*4882a593Smuzhiyun
1021*4882a593Smuzhiyun if (++fl->pidx == fl->size) {
1022*4882a593Smuzhiyun fl->pidx = 0;
1023*4882a593Smuzhiyun fl->genbit ^= 1;
1024*4882a593Smuzhiyun }
1025*4882a593Smuzhiyun }
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun static int copybreak __read_mostly = 256;
1028*4882a593Smuzhiyun module_param(copybreak, int, 0);
1029*4882a593Smuzhiyun MODULE_PARM_DESC(copybreak, "Receive copy threshold");
1030*4882a593Smuzhiyun
1031*4882a593Smuzhiyun /**
1032*4882a593Smuzhiyun * get_packet - return the next ingress packet buffer
1033*4882a593Smuzhiyun * @adapter: the adapter that received the packet
1034*4882a593Smuzhiyun * @fl: the SGE free list holding the packet
1035*4882a593Smuzhiyun * @len: the actual packet length, excluding any SGE padding
1036*4882a593Smuzhiyun *
1037*4882a593Smuzhiyun * Get the next packet from a free list and complete setup of the
1038*4882a593Smuzhiyun * sk_buff. If the packet is small we make a copy and recycle the
1039*4882a593Smuzhiyun * original buffer, otherwise we use the original buffer itself. If a
1040*4882a593Smuzhiyun * positive drop threshold is supplied packets are dropped and their
1041*4882a593Smuzhiyun * buffers recycled if (a) the number of remaining buffers is under the
1042*4882a593Smuzhiyun * threshold and the packet is too big to copy, or (b) the packet should
1043*4882a593Smuzhiyun * be copied but there is no memory for the copy.
1044*4882a593Smuzhiyun */
get_packet(struct adapter * adapter,struct freelQ * fl,unsigned int len)1045*4882a593Smuzhiyun static inline struct sk_buff *get_packet(struct adapter *adapter,
1046*4882a593Smuzhiyun struct freelQ *fl, unsigned int len)
1047*4882a593Smuzhiyun {
1048*4882a593Smuzhiyun const struct freelQ_ce *ce = &fl->centries[fl->cidx];
1049*4882a593Smuzhiyun struct pci_dev *pdev = adapter->pdev;
1050*4882a593Smuzhiyun struct sk_buff *skb;
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun if (len < copybreak) {
1053*4882a593Smuzhiyun skb = napi_alloc_skb(&adapter->napi, len);
1054*4882a593Smuzhiyun if (!skb)
1055*4882a593Smuzhiyun goto use_orig_buf;
1056*4882a593Smuzhiyun
1057*4882a593Smuzhiyun skb_put(skb, len);
1058*4882a593Smuzhiyun dma_sync_single_for_cpu(&pdev->dev,
1059*4882a593Smuzhiyun dma_unmap_addr(ce, dma_addr),
1060*4882a593Smuzhiyun dma_unmap_len(ce, dma_len),
1061*4882a593Smuzhiyun DMA_FROM_DEVICE);
1062*4882a593Smuzhiyun skb_copy_from_linear_data(ce->skb, skb->data, len);
1063*4882a593Smuzhiyun dma_sync_single_for_device(&pdev->dev,
1064*4882a593Smuzhiyun dma_unmap_addr(ce, dma_addr),
1065*4882a593Smuzhiyun dma_unmap_len(ce, dma_len),
1066*4882a593Smuzhiyun DMA_FROM_DEVICE);
1067*4882a593Smuzhiyun recycle_fl_buf(fl, fl->cidx);
1068*4882a593Smuzhiyun return skb;
1069*4882a593Smuzhiyun }
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun use_orig_buf:
1072*4882a593Smuzhiyun if (fl->credits < 2) {
1073*4882a593Smuzhiyun recycle_fl_buf(fl, fl->cidx);
1074*4882a593Smuzhiyun return NULL;
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun
1077*4882a593Smuzhiyun dma_unmap_single(&pdev->dev, dma_unmap_addr(ce, dma_addr),
1078*4882a593Smuzhiyun dma_unmap_len(ce, dma_len), DMA_FROM_DEVICE);
1079*4882a593Smuzhiyun skb = ce->skb;
1080*4882a593Smuzhiyun prefetch(skb->data);
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun skb_put(skb, len);
1083*4882a593Smuzhiyun return skb;
1084*4882a593Smuzhiyun }
1085*4882a593Smuzhiyun
1086*4882a593Smuzhiyun /**
1087*4882a593Smuzhiyun * unexpected_offload - handle an unexpected offload packet
1088*4882a593Smuzhiyun * @adapter: the adapter
1089*4882a593Smuzhiyun * @fl: the free list that received the packet
1090*4882a593Smuzhiyun *
1091*4882a593Smuzhiyun * Called when we receive an unexpected offload packet (e.g., the TOE
1092*4882a593Smuzhiyun * function is disabled or the card is a NIC). Prints a message and
1093*4882a593Smuzhiyun * recycles the buffer.
1094*4882a593Smuzhiyun */
unexpected_offload(struct adapter * adapter,struct freelQ * fl)1095*4882a593Smuzhiyun static void unexpected_offload(struct adapter *adapter, struct freelQ *fl)
1096*4882a593Smuzhiyun {
1097*4882a593Smuzhiyun struct freelQ_ce *ce = &fl->centries[fl->cidx];
1098*4882a593Smuzhiyun struct sk_buff *skb = ce->skb;
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun dma_sync_single_for_cpu(&adapter->pdev->dev,
1101*4882a593Smuzhiyun dma_unmap_addr(ce, dma_addr),
1102*4882a593Smuzhiyun dma_unmap_len(ce, dma_len), DMA_FROM_DEVICE);
1103*4882a593Smuzhiyun pr_err("%s: unexpected offload packet, cmd %u\n",
1104*4882a593Smuzhiyun adapter->name, *skb->data);
1105*4882a593Smuzhiyun recycle_fl_buf(fl, fl->cidx);
1106*4882a593Smuzhiyun }
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun /*
1109*4882a593Smuzhiyun * T1/T2 SGE limits the maximum DMA size per TX descriptor to
1110*4882a593Smuzhiyun * SGE_TX_DESC_MAX_PLEN (16KB). If the PAGE_SIZE is larger than 16KB, the
1111*4882a593Smuzhiyun * stack might send more than SGE_TX_DESC_MAX_PLEN in a contiguous manner.
1112*4882a593Smuzhiyun * Note that the *_large_page_tx_descs stuff will be optimized out when
1113*4882a593Smuzhiyun * PAGE_SIZE <= SGE_TX_DESC_MAX_PLEN.
1114*4882a593Smuzhiyun *
1115*4882a593Smuzhiyun * compute_large_page_descs() computes how many additional descriptors are
1116*4882a593Smuzhiyun * required to break down the stack's request.
1117*4882a593Smuzhiyun */
compute_large_page_tx_descs(struct sk_buff * skb)1118*4882a593Smuzhiyun static inline unsigned int compute_large_page_tx_descs(struct sk_buff *skb)
1119*4882a593Smuzhiyun {
1120*4882a593Smuzhiyun unsigned int count = 0;
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun if (PAGE_SIZE > SGE_TX_DESC_MAX_PLEN) {
1123*4882a593Smuzhiyun unsigned int nfrags = skb_shinfo(skb)->nr_frags;
1124*4882a593Smuzhiyun unsigned int i, len = skb_headlen(skb);
1125*4882a593Smuzhiyun while (len > SGE_TX_DESC_MAX_PLEN) {
1126*4882a593Smuzhiyun count++;
1127*4882a593Smuzhiyun len -= SGE_TX_DESC_MAX_PLEN;
1128*4882a593Smuzhiyun }
1129*4882a593Smuzhiyun for (i = 0; nfrags--; i++) {
1130*4882a593Smuzhiyun const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1131*4882a593Smuzhiyun len = skb_frag_size(frag);
1132*4882a593Smuzhiyun while (len > SGE_TX_DESC_MAX_PLEN) {
1133*4882a593Smuzhiyun count++;
1134*4882a593Smuzhiyun len -= SGE_TX_DESC_MAX_PLEN;
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun }
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun return count;
1139*4882a593Smuzhiyun }
1140*4882a593Smuzhiyun
1141*4882a593Smuzhiyun /*
1142*4882a593Smuzhiyun * Write a cmdQ entry.
1143*4882a593Smuzhiyun *
1144*4882a593Smuzhiyun * Since this function writes the 'flags' field, it must not be used to
1145*4882a593Smuzhiyun * write the first cmdQ entry.
1146*4882a593Smuzhiyun */
write_tx_desc(struct cmdQ_e * e,dma_addr_t mapping,unsigned int len,unsigned int gen,unsigned int eop)1147*4882a593Smuzhiyun static inline void write_tx_desc(struct cmdQ_e *e, dma_addr_t mapping,
1148*4882a593Smuzhiyun unsigned int len, unsigned int gen,
1149*4882a593Smuzhiyun unsigned int eop)
1150*4882a593Smuzhiyun {
1151*4882a593Smuzhiyun BUG_ON(len > SGE_TX_DESC_MAX_PLEN);
1152*4882a593Smuzhiyun
1153*4882a593Smuzhiyun e->addr_lo = (u32)mapping;
1154*4882a593Smuzhiyun e->addr_hi = (u64)mapping >> 32;
1155*4882a593Smuzhiyun e->len_gen = V_CMD_LEN(len) | V_CMD_GEN1(gen);
1156*4882a593Smuzhiyun e->flags = F_CMD_DATAVALID | V_CMD_EOP(eop) | V_CMD_GEN2(gen);
1157*4882a593Smuzhiyun }
1158*4882a593Smuzhiyun
1159*4882a593Smuzhiyun /*
1160*4882a593Smuzhiyun * See comment for previous function.
1161*4882a593Smuzhiyun *
1162*4882a593Smuzhiyun * write_tx_descs_large_page() writes additional SGE tx descriptors if
1163*4882a593Smuzhiyun * *desc_len exceeds HW's capability.
1164*4882a593Smuzhiyun */
write_large_page_tx_descs(unsigned int pidx,struct cmdQ_e ** e,struct cmdQ_ce ** ce,unsigned int * gen,dma_addr_t * desc_mapping,unsigned int * desc_len,unsigned int nfrags,struct cmdQ * q)1165*4882a593Smuzhiyun static inline unsigned int write_large_page_tx_descs(unsigned int pidx,
1166*4882a593Smuzhiyun struct cmdQ_e **e,
1167*4882a593Smuzhiyun struct cmdQ_ce **ce,
1168*4882a593Smuzhiyun unsigned int *gen,
1169*4882a593Smuzhiyun dma_addr_t *desc_mapping,
1170*4882a593Smuzhiyun unsigned int *desc_len,
1171*4882a593Smuzhiyun unsigned int nfrags,
1172*4882a593Smuzhiyun struct cmdQ *q)
1173*4882a593Smuzhiyun {
1174*4882a593Smuzhiyun if (PAGE_SIZE > SGE_TX_DESC_MAX_PLEN) {
1175*4882a593Smuzhiyun struct cmdQ_e *e1 = *e;
1176*4882a593Smuzhiyun struct cmdQ_ce *ce1 = *ce;
1177*4882a593Smuzhiyun
1178*4882a593Smuzhiyun while (*desc_len > SGE_TX_DESC_MAX_PLEN) {
1179*4882a593Smuzhiyun *desc_len -= SGE_TX_DESC_MAX_PLEN;
1180*4882a593Smuzhiyun write_tx_desc(e1, *desc_mapping, SGE_TX_DESC_MAX_PLEN,
1181*4882a593Smuzhiyun *gen, nfrags == 0 && *desc_len == 0);
1182*4882a593Smuzhiyun ce1->skb = NULL;
1183*4882a593Smuzhiyun dma_unmap_len_set(ce1, dma_len, 0);
1184*4882a593Smuzhiyun *desc_mapping += SGE_TX_DESC_MAX_PLEN;
1185*4882a593Smuzhiyun if (*desc_len) {
1186*4882a593Smuzhiyun ce1++;
1187*4882a593Smuzhiyun e1++;
1188*4882a593Smuzhiyun if (++pidx == q->size) {
1189*4882a593Smuzhiyun pidx = 0;
1190*4882a593Smuzhiyun *gen ^= 1;
1191*4882a593Smuzhiyun ce1 = q->centries;
1192*4882a593Smuzhiyun e1 = q->entries;
1193*4882a593Smuzhiyun }
1194*4882a593Smuzhiyun }
1195*4882a593Smuzhiyun }
1196*4882a593Smuzhiyun *e = e1;
1197*4882a593Smuzhiyun *ce = ce1;
1198*4882a593Smuzhiyun }
1199*4882a593Smuzhiyun return pidx;
1200*4882a593Smuzhiyun }
1201*4882a593Smuzhiyun
1202*4882a593Smuzhiyun /*
1203*4882a593Smuzhiyun * Write the command descriptors to transmit the given skb starting at
1204*4882a593Smuzhiyun * descriptor pidx with the given generation.
1205*4882a593Smuzhiyun */
write_tx_descs(struct adapter * adapter,struct sk_buff * skb,unsigned int pidx,unsigned int gen,struct cmdQ * q)1206*4882a593Smuzhiyun static inline void write_tx_descs(struct adapter *adapter, struct sk_buff *skb,
1207*4882a593Smuzhiyun unsigned int pidx, unsigned int gen,
1208*4882a593Smuzhiyun struct cmdQ *q)
1209*4882a593Smuzhiyun {
1210*4882a593Smuzhiyun dma_addr_t mapping, desc_mapping;
1211*4882a593Smuzhiyun struct cmdQ_e *e, *e1;
1212*4882a593Smuzhiyun struct cmdQ_ce *ce;
1213*4882a593Smuzhiyun unsigned int i, flags, first_desc_len, desc_len,
1214*4882a593Smuzhiyun nfrags = skb_shinfo(skb)->nr_frags;
1215*4882a593Smuzhiyun
1216*4882a593Smuzhiyun e = e1 = &q->entries[pidx];
1217*4882a593Smuzhiyun ce = &q->centries[pidx];
1218*4882a593Smuzhiyun
1219*4882a593Smuzhiyun mapping = dma_map_single(&adapter->pdev->dev, skb->data,
1220*4882a593Smuzhiyun skb_headlen(skb), DMA_TO_DEVICE);
1221*4882a593Smuzhiyun
1222*4882a593Smuzhiyun desc_mapping = mapping;
1223*4882a593Smuzhiyun desc_len = skb_headlen(skb);
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun flags = F_CMD_DATAVALID | F_CMD_SOP |
1226*4882a593Smuzhiyun V_CMD_EOP(nfrags == 0 && desc_len <= SGE_TX_DESC_MAX_PLEN) |
1227*4882a593Smuzhiyun V_CMD_GEN2(gen);
1228*4882a593Smuzhiyun first_desc_len = (desc_len <= SGE_TX_DESC_MAX_PLEN) ?
1229*4882a593Smuzhiyun desc_len : SGE_TX_DESC_MAX_PLEN;
1230*4882a593Smuzhiyun e->addr_lo = (u32)desc_mapping;
1231*4882a593Smuzhiyun e->addr_hi = (u64)desc_mapping >> 32;
1232*4882a593Smuzhiyun e->len_gen = V_CMD_LEN(first_desc_len) | V_CMD_GEN1(gen);
1233*4882a593Smuzhiyun ce->skb = NULL;
1234*4882a593Smuzhiyun dma_unmap_len_set(ce, dma_len, 0);
1235*4882a593Smuzhiyun
1236*4882a593Smuzhiyun if (PAGE_SIZE > SGE_TX_DESC_MAX_PLEN &&
1237*4882a593Smuzhiyun desc_len > SGE_TX_DESC_MAX_PLEN) {
1238*4882a593Smuzhiyun desc_mapping += first_desc_len;
1239*4882a593Smuzhiyun desc_len -= first_desc_len;
1240*4882a593Smuzhiyun e1++;
1241*4882a593Smuzhiyun ce++;
1242*4882a593Smuzhiyun if (++pidx == q->size) {
1243*4882a593Smuzhiyun pidx = 0;
1244*4882a593Smuzhiyun gen ^= 1;
1245*4882a593Smuzhiyun e1 = q->entries;
1246*4882a593Smuzhiyun ce = q->centries;
1247*4882a593Smuzhiyun }
1248*4882a593Smuzhiyun pidx = write_large_page_tx_descs(pidx, &e1, &ce, &gen,
1249*4882a593Smuzhiyun &desc_mapping, &desc_len,
1250*4882a593Smuzhiyun nfrags, q);
1251*4882a593Smuzhiyun
1252*4882a593Smuzhiyun if (likely(desc_len))
1253*4882a593Smuzhiyun write_tx_desc(e1, desc_mapping, desc_len, gen,
1254*4882a593Smuzhiyun nfrags == 0);
1255*4882a593Smuzhiyun }
1256*4882a593Smuzhiyun
1257*4882a593Smuzhiyun ce->skb = NULL;
1258*4882a593Smuzhiyun dma_unmap_addr_set(ce, dma_addr, mapping);
1259*4882a593Smuzhiyun dma_unmap_len_set(ce, dma_len, skb_headlen(skb));
1260*4882a593Smuzhiyun
1261*4882a593Smuzhiyun for (i = 0; nfrags--; i++) {
1262*4882a593Smuzhiyun skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1263*4882a593Smuzhiyun e1++;
1264*4882a593Smuzhiyun ce++;
1265*4882a593Smuzhiyun if (++pidx == q->size) {
1266*4882a593Smuzhiyun pidx = 0;
1267*4882a593Smuzhiyun gen ^= 1;
1268*4882a593Smuzhiyun e1 = q->entries;
1269*4882a593Smuzhiyun ce = q->centries;
1270*4882a593Smuzhiyun }
1271*4882a593Smuzhiyun
1272*4882a593Smuzhiyun mapping = skb_frag_dma_map(&adapter->pdev->dev, frag, 0,
1273*4882a593Smuzhiyun skb_frag_size(frag), DMA_TO_DEVICE);
1274*4882a593Smuzhiyun desc_mapping = mapping;
1275*4882a593Smuzhiyun desc_len = skb_frag_size(frag);
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun pidx = write_large_page_tx_descs(pidx, &e1, &ce, &gen,
1278*4882a593Smuzhiyun &desc_mapping, &desc_len,
1279*4882a593Smuzhiyun nfrags, q);
1280*4882a593Smuzhiyun if (likely(desc_len))
1281*4882a593Smuzhiyun write_tx_desc(e1, desc_mapping, desc_len, gen,
1282*4882a593Smuzhiyun nfrags == 0);
1283*4882a593Smuzhiyun ce->skb = NULL;
1284*4882a593Smuzhiyun dma_unmap_addr_set(ce, dma_addr, mapping);
1285*4882a593Smuzhiyun dma_unmap_len_set(ce, dma_len, skb_frag_size(frag));
1286*4882a593Smuzhiyun }
1287*4882a593Smuzhiyun ce->skb = skb;
1288*4882a593Smuzhiyun wmb();
1289*4882a593Smuzhiyun e->flags = flags;
1290*4882a593Smuzhiyun }
1291*4882a593Smuzhiyun
1292*4882a593Smuzhiyun /*
1293*4882a593Smuzhiyun * Clean up completed Tx buffers.
1294*4882a593Smuzhiyun */
reclaim_completed_tx(struct sge * sge,struct cmdQ * q)1295*4882a593Smuzhiyun static inline void reclaim_completed_tx(struct sge *sge, struct cmdQ *q)
1296*4882a593Smuzhiyun {
1297*4882a593Smuzhiyun unsigned int reclaim = q->processed - q->cleaned;
1298*4882a593Smuzhiyun
1299*4882a593Smuzhiyun if (reclaim) {
1300*4882a593Smuzhiyun pr_debug("reclaim_completed_tx processed:%d cleaned:%d\n",
1301*4882a593Smuzhiyun q->processed, q->cleaned);
1302*4882a593Smuzhiyun free_cmdQ_buffers(sge, q, reclaim);
1303*4882a593Smuzhiyun q->cleaned += reclaim;
1304*4882a593Smuzhiyun }
1305*4882a593Smuzhiyun }
1306*4882a593Smuzhiyun
1307*4882a593Smuzhiyun /*
1308*4882a593Smuzhiyun * Called from tasklet. Checks the scheduler for any
1309*4882a593Smuzhiyun * pending skbs that can be sent.
1310*4882a593Smuzhiyun */
restart_sched(struct tasklet_struct * t)1311*4882a593Smuzhiyun static void restart_sched(struct tasklet_struct *t)
1312*4882a593Smuzhiyun {
1313*4882a593Smuzhiyun struct sched *s = from_tasklet(s, t, sched_tsk);
1314*4882a593Smuzhiyun struct sge *sge = s->sge;
1315*4882a593Smuzhiyun struct adapter *adapter = sge->adapter;
1316*4882a593Smuzhiyun struct cmdQ *q = &sge->cmdQ[0];
1317*4882a593Smuzhiyun struct sk_buff *skb;
1318*4882a593Smuzhiyun unsigned int credits, queued_skb = 0;
1319*4882a593Smuzhiyun
1320*4882a593Smuzhiyun spin_lock(&q->lock);
1321*4882a593Smuzhiyun reclaim_completed_tx(sge, q);
1322*4882a593Smuzhiyun
1323*4882a593Smuzhiyun credits = q->size - q->in_use;
1324*4882a593Smuzhiyun pr_debug("restart_sched credits=%d\n", credits);
1325*4882a593Smuzhiyun while ((skb = sched_skb(sge, NULL, credits)) != NULL) {
1326*4882a593Smuzhiyun unsigned int genbit, pidx, count;
1327*4882a593Smuzhiyun count = 1 + skb_shinfo(skb)->nr_frags;
1328*4882a593Smuzhiyun count += compute_large_page_tx_descs(skb);
1329*4882a593Smuzhiyun q->in_use += count;
1330*4882a593Smuzhiyun genbit = q->genbit;
1331*4882a593Smuzhiyun pidx = q->pidx;
1332*4882a593Smuzhiyun q->pidx += count;
1333*4882a593Smuzhiyun if (q->pidx >= q->size) {
1334*4882a593Smuzhiyun q->pidx -= q->size;
1335*4882a593Smuzhiyun q->genbit ^= 1;
1336*4882a593Smuzhiyun }
1337*4882a593Smuzhiyun write_tx_descs(adapter, skb, pidx, genbit, q);
1338*4882a593Smuzhiyun credits = q->size - q->in_use;
1339*4882a593Smuzhiyun queued_skb = 1;
1340*4882a593Smuzhiyun }
1341*4882a593Smuzhiyun
1342*4882a593Smuzhiyun if (queued_skb) {
1343*4882a593Smuzhiyun clear_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
1344*4882a593Smuzhiyun if (test_and_set_bit(CMDQ_STAT_RUNNING, &q->status) == 0) {
1345*4882a593Smuzhiyun set_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
1346*4882a593Smuzhiyun writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
1347*4882a593Smuzhiyun }
1348*4882a593Smuzhiyun }
1349*4882a593Smuzhiyun spin_unlock(&q->lock);
1350*4882a593Smuzhiyun }
1351*4882a593Smuzhiyun
1352*4882a593Smuzhiyun /**
1353*4882a593Smuzhiyun * sge_rx - process an ingress ethernet packet
1354*4882a593Smuzhiyun * @sge: the sge structure
1355*4882a593Smuzhiyun * @fl: the free list that contains the packet buffer
1356*4882a593Smuzhiyun * @len: the packet length
1357*4882a593Smuzhiyun *
1358*4882a593Smuzhiyun * Process an ingress ethernet pakcet and deliver it to the stack.
1359*4882a593Smuzhiyun */
sge_rx(struct sge * sge,struct freelQ * fl,unsigned int len)1360*4882a593Smuzhiyun static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
1361*4882a593Smuzhiyun {
1362*4882a593Smuzhiyun struct sk_buff *skb;
1363*4882a593Smuzhiyun const struct cpl_rx_pkt *p;
1364*4882a593Smuzhiyun struct adapter *adapter = sge->adapter;
1365*4882a593Smuzhiyun struct sge_port_stats *st;
1366*4882a593Smuzhiyun struct net_device *dev;
1367*4882a593Smuzhiyun
1368*4882a593Smuzhiyun skb = get_packet(adapter, fl, len - sge->rx_pkt_pad);
1369*4882a593Smuzhiyun if (unlikely(!skb)) {
1370*4882a593Smuzhiyun sge->stats.rx_drops++;
1371*4882a593Smuzhiyun return;
1372*4882a593Smuzhiyun }
1373*4882a593Smuzhiyun
1374*4882a593Smuzhiyun p = (const struct cpl_rx_pkt *) skb->data;
1375*4882a593Smuzhiyun if (p->iff >= adapter->params.nports) {
1376*4882a593Smuzhiyun kfree_skb(skb);
1377*4882a593Smuzhiyun return;
1378*4882a593Smuzhiyun }
1379*4882a593Smuzhiyun __skb_pull(skb, sizeof(*p));
1380*4882a593Smuzhiyun
1381*4882a593Smuzhiyun st = this_cpu_ptr(sge->port_stats[p->iff]);
1382*4882a593Smuzhiyun dev = adapter->port[p->iff].dev;
1383*4882a593Smuzhiyun
1384*4882a593Smuzhiyun skb->protocol = eth_type_trans(skb, dev);
1385*4882a593Smuzhiyun if ((dev->features & NETIF_F_RXCSUM) && p->csum == 0xffff &&
1386*4882a593Smuzhiyun skb->protocol == htons(ETH_P_IP) &&
1387*4882a593Smuzhiyun (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
1388*4882a593Smuzhiyun ++st->rx_cso_good;
1389*4882a593Smuzhiyun skb->ip_summed = CHECKSUM_UNNECESSARY;
1390*4882a593Smuzhiyun } else
1391*4882a593Smuzhiyun skb_checksum_none_assert(skb);
1392*4882a593Smuzhiyun
1393*4882a593Smuzhiyun if (p->vlan_valid) {
1394*4882a593Smuzhiyun st->vlan_xtract++;
1395*4882a593Smuzhiyun __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(p->vlan));
1396*4882a593Smuzhiyun }
1397*4882a593Smuzhiyun netif_receive_skb(skb);
1398*4882a593Smuzhiyun }
1399*4882a593Smuzhiyun
1400*4882a593Smuzhiyun /*
1401*4882a593Smuzhiyun * Returns true if a command queue has enough available descriptors that
1402*4882a593Smuzhiyun * we can resume Tx operation after temporarily disabling its packet queue.
1403*4882a593Smuzhiyun */
enough_free_Tx_descs(const struct cmdQ * q)1404*4882a593Smuzhiyun static inline int enough_free_Tx_descs(const struct cmdQ *q)
1405*4882a593Smuzhiyun {
1406*4882a593Smuzhiyun unsigned int r = q->processed - q->cleaned;
1407*4882a593Smuzhiyun
1408*4882a593Smuzhiyun return q->in_use - r < (q->size >> 1);
1409*4882a593Smuzhiyun }
1410*4882a593Smuzhiyun
1411*4882a593Smuzhiyun /*
1412*4882a593Smuzhiyun * Called when sufficient space has become available in the SGE command queues
1413*4882a593Smuzhiyun * after the Tx packet schedulers have been suspended to restart the Tx path.
1414*4882a593Smuzhiyun */
restart_tx_queues(struct sge * sge)1415*4882a593Smuzhiyun static void restart_tx_queues(struct sge *sge)
1416*4882a593Smuzhiyun {
1417*4882a593Smuzhiyun struct adapter *adap = sge->adapter;
1418*4882a593Smuzhiyun int i;
1419*4882a593Smuzhiyun
1420*4882a593Smuzhiyun if (!enough_free_Tx_descs(&sge->cmdQ[0]))
1421*4882a593Smuzhiyun return;
1422*4882a593Smuzhiyun
1423*4882a593Smuzhiyun for_each_port(adap, i) {
1424*4882a593Smuzhiyun struct net_device *nd = adap->port[i].dev;
1425*4882a593Smuzhiyun
1426*4882a593Smuzhiyun if (test_and_clear_bit(nd->if_port, &sge->stopped_tx_queues) &&
1427*4882a593Smuzhiyun netif_running(nd)) {
1428*4882a593Smuzhiyun sge->stats.cmdQ_restarted[2]++;
1429*4882a593Smuzhiyun netif_wake_queue(nd);
1430*4882a593Smuzhiyun }
1431*4882a593Smuzhiyun }
1432*4882a593Smuzhiyun }
1433*4882a593Smuzhiyun
1434*4882a593Smuzhiyun /*
1435*4882a593Smuzhiyun * update_tx_info is called from the interrupt handler/NAPI to return cmdQ0
1436*4882a593Smuzhiyun * information.
1437*4882a593Smuzhiyun */
update_tx_info(struct adapter * adapter,unsigned int flags,unsigned int pr0)1438*4882a593Smuzhiyun static unsigned int update_tx_info(struct adapter *adapter,
1439*4882a593Smuzhiyun unsigned int flags,
1440*4882a593Smuzhiyun unsigned int pr0)
1441*4882a593Smuzhiyun {
1442*4882a593Smuzhiyun struct sge *sge = adapter->sge;
1443*4882a593Smuzhiyun struct cmdQ *cmdq = &sge->cmdQ[0];
1444*4882a593Smuzhiyun
1445*4882a593Smuzhiyun cmdq->processed += pr0;
1446*4882a593Smuzhiyun if (flags & (F_FL0_ENABLE | F_FL1_ENABLE)) {
1447*4882a593Smuzhiyun freelQs_empty(sge);
1448*4882a593Smuzhiyun flags &= ~(F_FL0_ENABLE | F_FL1_ENABLE);
1449*4882a593Smuzhiyun }
1450*4882a593Smuzhiyun if (flags & F_CMDQ0_ENABLE) {
1451*4882a593Smuzhiyun clear_bit(CMDQ_STAT_RUNNING, &cmdq->status);
1452*4882a593Smuzhiyun
1453*4882a593Smuzhiyun if (cmdq->cleaned + cmdq->in_use != cmdq->processed &&
1454*4882a593Smuzhiyun !test_and_set_bit(CMDQ_STAT_LAST_PKT_DB, &cmdq->status)) {
1455*4882a593Smuzhiyun set_bit(CMDQ_STAT_RUNNING, &cmdq->status);
1456*4882a593Smuzhiyun writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
1457*4882a593Smuzhiyun }
1458*4882a593Smuzhiyun if (sge->tx_sched)
1459*4882a593Smuzhiyun tasklet_hi_schedule(&sge->tx_sched->sched_tsk);
1460*4882a593Smuzhiyun
1461*4882a593Smuzhiyun flags &= ~F_CMDQ0_ENABLE;
1462*4882a593Smuzhiyun }
1463*4882a593Smuzhiyun
1464*4882a593Smuzhiyun if (unlikely(sge->stopped_tx_queues != 0))
1465*4882a593Smuzhiyun restart_tx_queues(sge);
1466*4882a593Smuzhiyun
1467*4882a593Smuzhiyun return flags;
1468*4882a593Smuzhiyun }
1469*4882a593Smuzhiyun
1470*4882a593Smuzhiyun /*
1471*4882a593Smuzhiyun * Process SGE responses, up to the supplied budget. Returns the number of
1472*4882a593Smuzhiyun * responses processed. A negative budget is effectively unlimited.
1473*4882a593Smuzhiyun */
process_responses(struct adapter * adapter,int budget)1474*4882a593Smuzhiyun static int process_responses(struct adapter *adapter, int budget)
1475*4882a593Smuzhiyun {
1476*4882a593Smuzhiyun struct sge *sge = adapter->sge;
1477*4882a593Smuzhiyun struct respQ *q = &sge->respQ;
1478*4882a593Smuzhiyun struct respQ_e *e = &q->entries[q->cidx];
1479*4882a593Smuzhiyun int done = 0;
1480*4882a593Smuzhiyun unsigned int flags = 0;
1481*4882a593Smuzhiyun unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0};
1482*4882a593Smuzhiyun
1483*4882a593Smuzhiyun while (done < budget && e->GenerationBit == q->genbit) {
1484*4882a593Smuzhiyun flags |= e->Qsleeping;
1485*4882a593Smuzhiyun
1486*4882a593Smuzhiyun cmdq_processed[0] += e->Cmdq0CreditReturn;
1487*4882a593Smuzhiyun cmdq_processed[1] += e->Cmdq1CreditReturn;
1488*4882a593Smuzhiyun
1489*4882a593Smuzhiyun /* We batch updates to the TX side to avoid cacheline
1490*4882a593Smuzhiyun * ping-pong of TX state information on MP where the sender
1491*4882a593Smuzhiyun * might run on a different CPU than this function...
1492*4882a593Smuzhiyun */
1493*4882a593Smuzhiyun if (unlikely((flags & F_CMDQ0_ENABLE) || cmdq_processed[0] > 64)) {
1494*4882a593Smuzhiyun flags = update_tx_info(adapter, flags, cmdq_processed[0]);
1495*4882a593Smuzhiyun cmdq_processed[0] = 0;
1496*4882a593Smuzhiyun }
1497*4882a593Smuzhiyun
1498*4882a593Smuzhiyun if (unlikely(cmdq_processed[1] > 16)) {
1499*4882a593Smuzhiyun sge->cmdQ[1].processed += cmdq_processed[1];
1500*4882a593Smuzhiyun cmdq_processed[1] = 0;
1501*4882a593Smuzhiyun }
1502*4882a593Smuzhiyun
1503*4882a593Smuzhiyun if (likely(e->DataValid)) {
1504*4882a593Smuzhiyun struct freelQ *fl = &sge->freelQ[e->FreelistQid];
1505*4882a593Smuzhiyun
1506*4882a593Smuzhiyun BUG_ON(!e->Sop || !e->Eop);
1507*4882a593Smuzhiyun if (unlikely(e->Offload))
1508*4882a593Smuzhiyun unexpected_offload(adapter, fl);
1509*4882a593Smuzhiyun else
1510*4882a593Smuzhiyun sge_rx(sge, fl, e->BufferLength);
1511*4882a593Smuzhiyun
1512*4882a593Smuzhiyun ++done;
1513*4882a593Smuzhiyun
1514*4882a593Smuzhiyun /*
1515*4882a593Smuzhiyun * Note: this depends on each packet consuming a
1516*4882a593Smuzhiyun * single free-list buffer; cf. the BUG above.
1517*4882a593Smuzhiyun */
1518*4882a593Smuzhiyun if (++fl->cidx == fl->size)
1519*4882a593Smuzhiyun fl->cidx = 0;
1520*4882a593Smuzhiyun prefetch(fl->centries[fl->cidx].skb);
1521*4882a593Smuzhiyun
1522*4882a593Smuzhiyun if (unlikely(--fl->credits <
1523*4882a593Smuzhiyun fl->size - SGE_FREEL_REFILL_THRESH))
1524*4882a593Smuzhiyun refill_free_list(sge, fl);
1525*4882a593Smuzhiyun } else
1526*4882a593Smuzhiyun sge->stats.pure_rsps++;
1527*4882a593Smuzhiyun
1528*4882a593Smuzhiyun e++;
1529*4882a593Smuzhiyun if (unlikely(++q->cidx == q->size)) {
1530*4882a593Smuzhiyun q->cidx = 0;
1531*4882a593Smuzhiyun q->genbit ^= 1;
1532*4882a593Smuzhiyun e = q->entries;
1533*4882a593Smuzhiyun }
1534*4882a593Smuzhiyun prefetch(e);
1535*4882a593Smuzhiyun
1536*4882a593Smuzhiyun if (++q->credits > SGE_RESPQ_REPLENISH_THRES) {
1537*4882a593Smuzhiyun writel(q->credits, adapter->regs + A_SG_RSPQUEUECREDIT);
1538*4882a593Smuzhiyun q->credits = 0;
1539*4882a593Smuzhiyun }
1540*4882a593Smuzhiyun }
1541*4882a593Smuzhiyun
1542*4882a593Smuzhiyun flags = update_tx_info(adapter, flags, cmdq_processed[0]);
1543*4882a593Smuzhiyun sge->cmdQ[1].processed += cmdq_processed[1];
1544*4882a593Smuzhiyun
1545*4882a593Smuzhiyun return done;
1546*4882a593Smuzhiyun }
1547*4882a593Smuzhiyun
responses_pending(const struct adapter * adapter)1548*4882a593Smuzhiyun static inline int responses_pending(const struct adapter *adapter)
1549*4882a593Smuzhiyun {
1550*4882a593Smuzhiyun const struct respQ *Q = &adapter->sge->respQ;
1551*4882a593Smuzhiyun const struct respQ_e *e = &Q->entries[Q->cidx];
1552*4882a593Smuzhiyun
1553*4882a593Smuzhiyun return e->GenerationBit == Q->genbit;
1554*4882a593Smuzhiyun }
1555*4882a593Smuzhiyun
1556*4882a593Smuzhiyun /*
1557*4882a593Smuzhiyun * A simpler version of process_responses() that handles only pure (i.e.,
1558*4882a593Smuzhiyun * non data-carrying) responses. Such respones are too light-weight to justify
1559*4882a593Smuzhiyun * calling a softirq when using NAPI, so we handle them specially in hard
1560*4882a593Smuzhiyun * interrupt context. The function is called with a pointer to a response,
1561*4882a593Smuzhiyun * which the caller must ensure is a valid pure response. Returns 1 if it
1562*4882a593Smuzhiyun * encounters a valid data-carrying response, 0 otherwise.
1563*4882a593Smuzhiyun */
process_pure_responses(struct adapter * adapter)1564*4882a593Smuzhiyun static int process_pure_responses(struct adapter *adapter)
1565*4882a593Smuzhiyun {
1566*4882a593Smuzhiyun struct sge *sge = adapter->sge;
1567*4882a593Smuzhiyun struct respQ *q = &sge->respQ;
1568*4882a593Smuzhiyun struct respQ_e *e = &q->entries[q->cidx];
1569*4882a593Smuzhiyun const struct freelQ *fl = &sge->freelQ[e->FreelistQid];
1570*4882a593Smuzhiyun unsigned int flags = 0;
1571*4882a593Smuzhiyun unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0};
1572*4882a593Smuzhiyun
1573*4882a593Smuzhiyun prefetch(fl->centries[fl->cidx].skb);
1574*4882a593Smuzhiyun if (e->DataValid)
1575*4882a593Smuzhiyun return 1;
1576*4882a593Smuzhiyun
1577*4882a593Smuzhiyun do {
1578*4882a593Smuzhiyun flags |= e->Qsleeping;
1579*4882a593Smuzhiyun
1580*4882a593Smuzhiyun cmdq_processed[0] += e->Cmdq0CreditReturn;
1581*4882a593Smuzhiyun cmdq_processed[1] += e->Cmdq1CreditReturn;
1582*4882a593Smuzhiyun
1583*4882a593Smuzhiyun e++;
1584*4882a593Smuzhiyun if (unlikely(++q->cidx == q->size)) {
1585*4882a593Smuzhiyun q->cidx = 0;
1586*4882a593Smuzhiyun q->genbit ^= 1;
1587*4882a593Smuzhiyun e = q->entries;
1588*4882a593Smuzhiyun }
1589*4882a593Smuzhiyun prefetch(e);
1590*4882a593Smuzhiyun
1591*4882a593Smuzhiyun if (++q->credits > SGE_RESPQ_REPLENISH_THRES) {
1592*4882a593Smuzhiyun writel(q->credits, adapter->regs + A_SG_RSPQUEUECREDIT);
1593*4882a593Smuzhiyun q->credits = 0;
1594*4882a593Smuzhiyun }
1595*4882a593Smuzhiyun sge->stats.pure_rsps++;
1596*4882a593Smuzhiyun } while (e->GenerationBit == q->genbit && !e->DataValid);
1597*4882a593Smuzhiyun
1598*4882a593Smuzhiyun flags = update_tx_info(adapter, flags, cmdq_processed[0]);
1599*4882a593Smuzhiyun sge->cmdQ[1].processed += cmdq_processed[1];
1600*4882a593Smuzhiyun
1601*4882a593Smuzhiyun return e->GenerationBit == q->genbit;
1602*4882a593Smuzhiyun }
1603*4882a593Smuzhiyun
1604*4882a593Smuzhiyun /*
1605*4882a593Smuzhiyun * Handler for new data events when using NAPI. This does not need any locking
1606*4882a593Smuzhiyun * or protection from interrupts as data interrupts are off at this point and
1607*4882a593Smuzhiyun * other adapter interrupts do not interfere.
1608*4882a593Smuzhiyun */
t1_poll(struct napi_struct * napi,int budget)1609*4882a593Smuzhiyun int t1_poll(struct napi_struct *napi, int budget)
1610*4882a593Smuzhiyun {
1611*4882a593Smuzhiyun struct adapter *adapter = container_of(napi, struct adapter, napi);
1612*4882a593Smuzhiyun int work_done = process_responses(adapter, budget);
1613*4882a593Smuzhiyun
1614*4882a593Smuzhiyun if (likely(work_done < budget)) {
1615*4882a593Smuzhiyun napi_complete_done(napi, work_done);
1616*4882a593Smuzhiyun writel(adapter->sge->respQ.cidx,
1617*4882a593Smuzhiyun adapter->regs + A_SG_SLEEPING);
1618*4882a593Smuzhiyun }
1619*4882a593Smuzhiyun return work_done;
1620*4882a593Smuzhiyun }
1621*4882a593Smuzhiyun
t1_interrupt(int irq,void * data)1622*4882a593Smuzhiyun irqreturn_t t1_interrupt(int irq, void *data)
1623*4882a593Smuzhiyun {
1624*4882a593Smuzhiyun struct adapter *adapter = data;
1625*4882a593Smuzhiyun struct sge *sge = adapter->sge;
1626*4882a593Smuzhiyun int handled;
1627*4882a593Smuzhiyun
1628*4882a593Smuzhiyun if (likely(responses_pending(adapter))) {
1629*4882a593Smuzhiyun writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE);
1630*4882a593Smuzhiyun
1631*4882a593Smuzhiyun if (napi_schedule_prep(&adapter->napi)) {
1632*4882a593Smuzhiyun if (process_pure_responses(adapter))
1633*4882a593Smuzhiyun __napi_schedule(&adapter->napi);
1634*4882a593Smuzhiyun else {
1635*4882a593Smuzhiyun /* no data, no NAPI needed */
1636*4882a593Smuzhiyun writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
1637*4882a593Smuzhiyun /* undo schedule_prep */
1638*4882a593Smuzhiyun napi_enable(&adapter->napi);
1639*4882a593Smuzhiyun }
1640*4882a593Smuzhiyun }
1641*4882a593Smuzhiyun return IRQ_HANDLED;
1642*4882a593Smuzhiyun }
1643*4882a593Smuzhiyun
1644*4882a593Smuzhiyun spin_lock(&adapter->async_lock);
1645*4882a593Smuzhiyun handled = t1_slow_intr_handler(adapter);
1646*4882a593Smuzhiyun spin_unlock(&adapter->async_lock);
1647*4882a593Smuzhiyun
1648*4882a593Smuzhiyun if (!handled)
1649*4882a593Smuzhiyun sge->stats.unhandled_irqs++;
1650*4882a593Smuzhiyun
1651*4882a593Smuzhiyun return IRQ_RETVAL(handled != 0);
1652*4882a593Smuzhiyun }
1653*4882a593Smuzhiyun
1654*4882a593Smuzhiyun /*
1655*4882a593Smuzhiyun * Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it.
1656*4882a593Smuzhiyun *
1657*4882a593Smuzhiyun * The code figures out how many entries the sk_buff will require in the
1658*4882a593Smuzhiyun * cmdQ and updates the cmdQ data structure with the state once the enqueue
1659*4882a593Smuzhiyun * has complete. Then, it doesn't access the global structure anymore, but
1660*4882a593Smuzhiyun * uses the corresponding fields on the stack. In conjunction with a spinlock
1661*4882a593Smuzhiyun * around that code, we can make the function reentrant without holding the
1662*4882a593Smuzhiyun * lock when we actually enqueue (which might be expensive, especially on
1663*4882a593Smuzhiyun * architectures with IO MMUs).
1664*4882a593Smuzhiyun *
1665*4882a593Smuzhiyun * This runs with softirqs disabled.
1666*4882a593Smuzhiyun */
t1_sge_tx(struct sk_buff * skb,struct adapter * adapter,unsigned int qid,struct net_device * dev)1667*4882a593Smuzhiyun static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
1668*4882a593Smuzhiyun unsigned int qid, struct net_device *dev)
1669*4882a593Smuzhiyun {
1670*4882a593Smuzhiyun struct sge *sge = adapter->sge;
1671*4882a593Smuzhiyun struct cmdQ *q = &sge->cmdQ[qid];
1672*4882a593Smuzhiyun unsigned int credits, pidx, genbit, count, use_sched_skb = 0;
1673*4882a593Smuzhiyun
1674*4882a593Smuzhiyun spin_lock(&q->lock);
1675*4882a593Smuzhiyun
1676*4882a593Smuzhiyun reclaim_completed_tx(sge, q);
1677*4882a593Smuzhiyun
1678*4882a593Smuzhiyun pidx = q->pidx;
1679*4882a593Smuzhiyun credits = q->size - q->in_use;
1680*4882a593Smuzhiyun count = 1 + skb_shinfo(skb)->nr_frags;
1681*4882a593Smuzhiyun count += compute_large_page_tx_descs(skb);
1682*4882a593Smuzhiyun
1683*4882a593Smuzhiyun /* Ethernet packet */
1684*4882a593Smuzhiyun if (unlikely(credits < count)) {
1685*4882a593Smuzhiyun if (!netif_queue_stopped(dev)) {
1686*4882a593Smuzhiyun netif_stop_queue(dev);
1687*4882a593Smuzhiyun set_bit(dev->if_port, &sge->stopped_tx_queues);
1688*4882a593Smuzhiyun sge->stats.cmdQ_full[2]++;
1689*4882a593Smuzhiyun pr_err("%s: Tx ring full while queue awake!\n",
1690*4882a593Smuzhiyun adapter->name);
1691*4882a593Smuzhiyun }
1692*4882a593Smuzhiyun spin_unlock(&q->lock);
1693*4882a593Smuzhiyun return NETDEV_TX_BUSY;
1694*4882a593Smuzhiyun }
1695*4882a593Smuzhiyun
1696*4882a593Smuzhiyun if (unlikely(credits - count < q->stop_thres)) {
1697*4882a593Smuzhiyun netif_stop_queue(dev);
1698*4882a593Smuzhiyun set_bit(dev->if_port, &sge->stopped_tx_queues);
1699*4882a593Smuzhiyun sge->stats.cmdQ_full[2]++;
1700*4882a593Smuzhiyun }
1701*4882a593Smuzhiyun
1702*4882a593Smuzhiyun /* T204 cmdQ0 skbs that are destined for a certain port have to go
1703*4882a593Smuzhiyun * through the scheduler.
1704*4882a593Smuzhiyun */
1705*4882a593Smuzhiyun if (sge->tx_sched && !qid && skb->dev) {
1706*4882a593Smuzhiyun use_sched:
1707*4882a593Smuzhiyun use_sched_skb = 1;
1708*4882a593Smuzhiyun /* Note that the scheduler might return a different skb than
1709*4882a593Smuzhiyun * the one passed in.
1710*4882a593Smuzhiyun */
1711*4882a593Smuzhiyun skb = sched_skb(sge, skb, credits);
1712*4882a593Smuzhiyun if (!skb) {
1713*4882a593Smuzhiyun spin_unlock(&q->lock);
1714*4882a593Smuzhiyun return NETDEV_TX_OK;
1715*4882a593Smuzhiyun }
1716*4882a593Smuzhiyun pidx = q->pidx;
1717*4882a593Smuzhiyun count = 1 + skb_shinfo(skb)->nr_frags;
1718*4882a593Smuzhiyun count += compute_large_page_tx_descs(skb);
1719*4882a593Smuzhiyun }
1720*4882a593Smuzhiyun
1721*4882a593Smuzhiyun q->in_use += count;
1722*4882a593Smuzhiyun genbit = q->genbit;
1723*4882a593Smuzhiyun pidx = q->pidx;
1724*4882a593Smuzhiyun q->pidx += count;
1725*4882a593Smuzhiyun if (q->pidx >= q->size) {
1726*4882a593Smuzhiyun q->pidx -= q->size;
1727*4882a593Smuzhiyun q->genbit ^= 1;
1728*4882a593Smuzhiyun }
1729*4882a593Smuzhiyun spin_unlock(&q->lock);
1730*4882a593Smuzhiyun
1731*4882a593Smuzhiyun write_tx_descs(adapter, skb, pidx, genbit, q);
1732*4882a593Smuzhiyun
1733*4882a593Smuzhiyun /*
1734*4882a593Smuzhiyun * We always ring the doorbell for cmdQ1. For cmdQ0, we only ring
1735*4882a593Smuzhiyun * the doorbell if the Q is asleep. There is a natural race, where
1736*4882a593Smuzhiyun * the hardware is going to sleep just after we checked, however,
1737*4882a593Smuzhiyun * then the interrupt handler will detect the outstanding TX packet
1738*4882a593Smuzhiyun * and ring the doorbell for us.
1739*4882a593Smuzhiyun */
1740*4882a593Smuzhiyun if (qid)
1741*4882a593Smuzhiyun doorbell_pio(adapter, F_CMDQ1_ENABLE);
1742*4882a593Smuzhiyun else {
1743*4882a593Smuzhiyun clear_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
1744*4882a593Smuzhiyun if (test_and_set_bit(CMDQ_STAT_RUNNING, &q->status) == 0) {
1745*4882a593Smuzhiyun set_bit(CMDQ_STAT_LAST_PKT_DB, &q->status);
1746*4882a593Smuzhiyun writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
1747*4882a593Smuzhiyun }
1748*4882a593Smuzhiyun }
1749*4882a593Smuzhiyun
1750*4882a593Smuzhiyun if (use_sched_skb) {
1751*4882a593Smuzhiyun if (spin_trylock(&q->lock)) {
1752*4882a593Smuzhiyun credits = q->size - q->in_use;
1753*4882a593Smuzhiyun skb = NULL;
1754*4882a593Smuzhiyun goto use_sched;
1755*4882a593Smuzhiyun }
1756*4882a593Smuzhiyun }
1757*4882a593Smuzhiyun return NETDEV_TX_OK;
1758*4882a593Smuzhiyun }
1759*4882a593Smuzhiyun
1760*4882a593Smuzhiyun #define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14))
1761*4882a593Smuzhiyun
1762*4882a593Smuzhiyun /*
1763*4882a593Smuzhiyun * eth_hdr_len - return the length of an Ethernet header
1764*4882a593Smuzhiyun * @data: pointer to the start of the Ethernet header
1765*4882a593Smuzhiyun *
1766*4882a593Smuzhiyun * Returns the length of an Ethernet header, including optional VLAN tag.
1767*4882a593Smuzhiyun */
eth_hdr_len(const void * data)1768*4882a593Smuzhiyun static inline int eth_hdr_len(const void *data)
1769*4882a593Smuzhiyun {
1770*4882a593Smuzhiyun const struct ethhdr *e = data;
1771*4882a593Smuzhiyun
1772*4882a593Smuzhiyun return e->h_proto == htons(ETH_P_8021Q) ? VLAN_ETH_HLEN : ETH_HLEN;
1773*4882a593Smuzhiyun }
1774*4882a593Smuzhiyun
1775*4882a593Smuzhiyun /*
1776*4882a593Smuzhiyun * Adds the CPL header to the sk_buff and passes it to t1_sge_tx.
1777*4882a593Smuzhiyun */
t1_start_xmit(struct sk_buff * skb,struct net_device * dev)1778*4882a593Smuzhiyun netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1779*4882a593Smuzhiyun {
1780*4882a593Smuzhiyun struct adapter *adapter = dev->ml_priv;
1781*4882a593Smuzhiyun struct sge *sge = adapter->sge;
1782*4882a593Smuzhiyun struct sge_port_stats *st = this_cpu_ptr(sge->port_stats[dev->if_port]);
1783*4882a593Smuzhiyun struct cpl_tx_pkt *cpl;
1784*4882a593Smuzhiyun struct sk_buff *orig_skb = skb;
1785*4882a593Smuzhiyun int ret;
1786*4882a593Smuzhiyun
1787*4882a593Smuzhiyun if (skb->protocol == htons(ETH_P_CPL5))
1788*4882a593Smuzhiyun goto send;
1789*4882a593Smuzhiyun
1790*4882a593Smuzhiyun /*
1791*4882a593Smuzhiyun * We are using a non-standard hard_header_len.
1792*4882a593Smuzhiyun * Allocate more header room in the rare cases it is not big enough.
1793*4882a593Smuzhiyun */
1794*4882a593Smuzhiyun if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) {
1795*4882a593Smuzhiyun skb = skb_realloc_headroom(skb, sizeof(struct cpl_tx_pkt_lso));
1796*4882a593Smuzhiyun ++st->tx_need_hdrroom;
1797*4882a593Smuzhiyun dev_kfree_skb_any(orig_skb);
1798*4882a593Smuzhiyun if (!skb)
1799*4882a593Smuzhiyun return NETDEV_TX_OK;
1800*4882a593Smuzhiyun }
1801*4882a593Smuzhiyun
1802*4882a593Smuzhiyun if (skb_shinfo(skb)->gso_size) {
1803*4882a593Smuzhiyun int eth_type;
1804*4882a593Smuzhiyun struct cpl_tx_pkt_lso *hdr;
1805*4882a593Smuzhiyun
1806*4882a593Smuzhiyun ++st->tx_tso;
1807*4882a593Smuzhiyun
1808*4882a593Smuzhiyun eth_type = skb_network_offset(skb) == ETH_HLEN ?
1809*4882a593Smuzhiyun CPL_ETH_II : CPL_ETH_II_VLAN;
1810*4882a593Smuzhiyun
1811*4882a593Smuzhiyun hdr = skb_push(skb, sizeof(*hdr));
1812*4882a593Smuzhiyun hdr->opcode = CPL_TX_PKT_LSO;
1813*4882a593Smuzhiyun hdr->ip_csum_dis = hdr->l4_csum_dis = 0;
1814*4882a593Smuzhiyun hdr->ip_hdr_words = ip_hdr(skb)->ihl;
1815*4882a593Smuzhiyun hdr->tcp_hdr_words = tcp_hdr(skb)->doff;
1816*4882a593Smuzhiyun hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
1817*4882a593Smuzhiyun skb_shinfo(skb)->gso_size));
1818*4882a593Smuzhiyun hdr->len = htonl(skb->len - sizeof(*hdr));
1819*4882a593Smuzhiyun cpl = (struct cpl_tx_pkt *)hdr;
1820*4882a593Smuzhiyun } else {
1821*4882a593Smuzhiyun /*
1822*4882a593Smuzhiyun * Packets shorter than ETH_HLEN can break the MAC, drop them
1823*4882a593Smuzhiyun * early. Also, we may get oversized packets because some
1824*4882a593Smuzhiyun * parts of the kernel don't handle our unusual hard_header_len
1825*4882a593Smuzhiyun * right, drop those too.
1826*4882a593Smuzhiyun */
1827*4882a593Smuzhiyun if (unlikely(skb->len < ETH_HLEN ||
1828*4882a593Smuzhiyun skb->len > dev->mtu + eth_hdr_len(skb->data))) {
1829*4882a593Smuzhiyun netdev_dbg(dev, "packet size %d hdr %d mtu%d\n",
1830*4882a593Smuzhiyun skb->len, eth_hdr_len(skb->data), dev->mtu);
1831*4882a593Smuzhiyun dev_kfree_skb_any(skb);
1832*4882a593Smuzhiyun return NETDEV_TX_OK;
1833*4882a593Smuzhiyun }
1834*4882a593Smuzhiyun
1835*4882a593Smuzhiyun if (skb->ip_summed == CHECKSUM_PARTIAL &&
1836*4882a593Smuzhiyun ip_hdr(skb)->protocol == IPPROTO_UDP) {
1837*4882a593Smuzhiyun if (unlikely(skb_checksum_help(skb))) {
1838*4882a593Smuzhiyun netdev_dbg(dev, "unable to do udp checksum\n");
1839*4882a593Smuzhiyun dev_kfree_skb_any(skb);
1840*4882a593Smuzhiyun return NETDEV_TX_OK;
1841*4882a593Smuzhiyun }
1842*4882a593Smuzhiyun }
1843*4882a593Smuzhiyun
1844*4882a593Smuzhiyun /* Hmmm, assuming to catch the gratious arp... and we'll use
1845*4882a593Smuzhiyun * it to flush out stuck espi packets...
1846*4882a593Smuzhiyun */
1847*4882a593Smuzhiyun if ((unlikely(!adapter->sge->espibug_skb[dev->if_port]))) {
1848*4882a593Smuzhiyun if (skb->protocol == htons(ETH_P_ARP) &&
1849*4882a593Smuzhiyun arp_hdr(skb)->ar_op == htons(ARPOP_REQUEST)) {
1850*4882a593Smuzhiyun adapter->sge->espibug_skb[dev->if_port] = skb;
1851*4882a593Smuzhiyun /* We want to re-use this skb later. We
1852*4882a593Smuzhiyun * simply bump the reference count and it
1853*4882a593Smuzhiyun * will not be freed...
1854*4882a593Smuzhiyun */
1855*4882a593Smuzhiyun skb = skb_get(skb);
1856*4882a593Smuzhiyun }
1857*4882a593Smuzhiyun }
1858*4882a593Smuzhiyun
1859*4882a593Smuzhiyun cpl = __skb_push(skb, sizeof(*cpl));
1860*4882a593Smuzhiyun cpl->opcode = CPL_TX_PKT;
1861*4882a593Smuzhiyun cpl->ip_csum_dis = 1; /* SW calculates IP csum */
1862*4882a593Smuzhiyun cpl->l4_csum_dis = skb->ip_summed == CHECKSUM_PARTIAL ? 0 : 1;
1863*4882a593Smuzhiyun /* the length field isn't used so don't bother setting it */
1864*4882a593Smuzhiyun
1865*4882a593Smuzhiyun st->tx_cso += (skb->ip_summed == CHECKSUM_PARTIAL);
1866*4882a593Smuzhiyun }
1867*4882a593Smuzhiyun cpl->iff = dev->if_port;
1868*4882a593Smuzhiyun
1869*4882a593Smuzhiyun if (skb_vlan_tag_present(skb)) {
1870*4882a593Smuzhiyun cpl->vlan_valid = 1;
1871*4882a593Smuzhiyun cpl->vlan = htons(skb_vlan_tag_get(skb));
1872*4882a593Smuzhiyun st->vlan_insert++;
1873*4882a593Smuzhiyun } else
1874*4882a593Smuzhiyun cpl->vlan_valid = 0;
1875*4882a593Smuzhiyun
1876*4882a593Smuzhiyun send:
1877*4882a593Smuzhiyun ret = t1_sge_tx(skb, adapter, 0, dev);
1878*4882a593Smuzhiyun
1879*4882a593Smuzhiyun /* If transmit busy, and we reallocated skb's due to headroom limit,
1880*4882a593Smuzhiyun * then silently discard to avoid leak.
1881*4882a593Smuzhiyun */
1882*4882a593Smuzhiyun if (unlikely(ret != NETDEV_TX_OK && skb != orig_skb)) {
1883*4882a593Smuzhiyun dev_kfree_skb_any(skb);
1884*4882a593Smuzhiyun ret = NETDEV_TX_OK;
1885*4882a593Smuzhiyun }
1886*4882a593Smuzhiyun return ret;
1887*4882a593Smuzhiyun }
1888*4882a593Smuzhiyun
1889*4882a593Smuzhiyun /*
1890*4882a593Smuzhiyun * Callback for the Tx buffer reclaim timer. Runs with softirqs disabled.
1891*4882a593Smuzhiyun */
sge_tx_reclaim_cb(struct timer_list * t)1892*4882a593Smuzhiyun static void sge_tx_reclaim_cb(struct timer_list *t)
1893*4882a593Smuzhiyun {
1894*4882a593Smuzhiyun int i;
1895*4882a593Smuzhiyun struct sge *sge = from_timer(sge, t, tx_reclaim_timer);
1896*4882a593Smuzhiyun
1897*4882a593Smuzhiyun for (i = 0; i < SGE_CMDQ_N; ++i) {
1898*4882a593Smuzhiyun struct cmdQ *q = &sge->cmdQ[i];
1899*4882a593Smuzhiyun
1900*4882a593Smuzhiyun if (!spin_trylock(&q->lock))
1901*4882a593Smuzhiyun continue;
1902*4882a593Smuzhiyun
1903*4882a593Smuzhiyun reclaim_completed_tx(sge, q);
1904*4882a593Smuzhiyun if (i == 0 && q->in_use) { /* flush pending credits */
1905*4882a593Smuzhiyun writel(F_CMDQ0_ENABLE, sge->adapter->regs + A_SG_DOORBELL);
1906*4882a593Smuzhiyun }
1907*4882a593Smuzhiyun spin_unlock(&q->lock);
1908*4882a593Smuzhiyun }
1909*4882a593Smuzhiyun mod_timer(&sge->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
1910*4882a593Smuzhiyun }
1911*4882a593Smuzhiyun
1912*4882a593Smuzhiyun /*
1913*4882a593Smuzhiyun * Propagate changes of the SGE coalescing parameters to the HW.
1914*4882a593Smuzhiyun */
t1_sge_set_coalesce_params(struct sge * sge,struct sge_params * p)1915*4882a593Smuzhiyun int t1_sge_set_coalesce_params(struct sge *sge, struct sge_params *p)
1916*4882a593Smuzhiyun {
1917*4882a593Smuzhiyun sge->fixed_intrtimer = p->rx_coalesce_usecs *
1918*4882a593Smuzhiyun core_ticks_per_usec(sge->adapter);
1919*4882a593Smuzhiyun writel(sge->fixed_intrtimer, sge->adapter->regs + A_SG_INTRTIMER);
1920*4882a593Smuzhiyun return 0;
1921*4882a593Smuzhiyun }
1922*4882a593Smuzhiyun
1923*4882a593Smuzhiyun /*
1924*4882a593Smuzhiyun * Allocates both RX and TX resources and configures the SGE. However,
1925*4882a593Smuzhiyun * the hardware is not enabled yet.
1926*4882a593Smuzhiyun */
t1_sge_configure(struct sge * sge,struct sge_params * p)1927*4882a593Smuzhiyun int t1_sge_configure(struct sge *sge, struct sge_params *p)
1928*4882a593Smuzhiyun {
1929*4882a593Smuzhiyun if (alloc_rx_resources(sge, p))
1930*4882a593Smuzhiyun return -ENOMEM;
1931*4882a593Smuzhiyun if (alloc_tx_resources(sge, p)) {
1932*4882a593Smuzhiyun free_rx_resources(sge);
1933*4882a593Smuzhiyun return -ENOMEM;
1934*4882a593Smuzhiyun }
1935*4882a593Smuzhiyun configure_sge(sge, p);
1936*4882a593Smuzhiyun
1937*4882a593Smuzhiyun /*
1938*4882a593Smuzhiyun * Now that we have sized the free lists calculate the payload
1939*4882a593Smuzhiyun * capacity of the large buffers. Other parts of the driver use
1940*4882a593Smuzhiyun * this to set the max offload coalescing size so that RX packets
1941*4882a593Smuzhiyun * do not overflow our large buffers.
1942*4882a593Smuzhiyun */
1943*4882a593Smuzhiyun p->large_buf_capacity = jumbo_payload_capacity(sge);
1944*4882a593Smuzhiyun return 0;
1945*4882a593Smuzhiyun }
1946*4882a593Smuzhiyun
1947*4882a593Smuzhiyun /*
1948*4882a593Smuzhiyun * Disables the DMA engine.
1949*4882a593Smuzhiyun */
t1_sge_stop(struct sge * sge)1950*4882a593Smuzhiyun void t1_sge_stop(struct sge *sge)
1951*4882a593Smuzhiyun {
1952*4882a593Smuzhiyun int i;
1953*4882a593Smuzhiyun writel(0, sge->adapter->regs + A_SG_CONTROL);
1954*4882a593Smuzhiyun readl(sge->adapter->regs + A_SG_CONTROL); /* flush */
1955*4882a593Smuzhiyun
1956*4882a593Smuzhiyun if (is_T2(sge->adapter))
1957*4882a593Smuzhiyun del_timer_sync(&sge->espibug_timer);
1958*4882a593Smuzhiyun
1959*4882a593Smuzhiyun del_timer_sync(&sge->tx_reclaim_timer);
1960*4882a593Smuzhiyun if (sge->tx_sched)
1961*4882a593Smuzhiyun tx_sched_stop(sge);
1962*4882a593Smuzhiyun
1963*4882a593Smuzhiyun for (i = 0; i < MAX_NPORTS; i++)
1964*4882a593Smuzhiyun kfree_skb(sge->espibug_skb[i]);
1965*4882a593Smuzhiyun }
1966*4882a593Smuzhiyun
1967*4882a593Smuzhiyun /*
1968*4882a593Smuzhiyun * Enables the DMA engine.
1969*4882a593Smuzhiyun */
t1_sge_start(struct sge * sge)1970*4882a593Smuzhiyun void t1_sge_start(struct sge *sge)
1971*4882a593Smuzhiyun {
1972*4882a593Smuzhiyun refill_free_list(sge, &sge->freelQ[0]);
1973*4882a593Smuzhiyun refill_free_list(sge, &sge->freelQ[1]);
1974*4882a593Smuzhiyun
1975*4882a593Smuzhiyun writel(sge->sge_control, sge->adapter->regs + A_SG_CONTROL);
1976*4882a593Smuzhiyun doorbell_pio(sge->adapter, F_FL0_ENABLE | F_FL1_ENABLE);
1977*4882a593Smuzhiyun readl(sge->adapter->regs + A_SG_CONTROL); /* flush */
1978*4882a593Smuzhiyun
1979*4882a593Smuzhiyun mod_timer(&sge->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
1980*4882a593Smuzhiyun
1981*4882a593Smuzhiyun if (is_T2(sge->adapter))
1982*4882a593Smuzhiyun mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout);
1983*4882a593Smuzhiyun }
1984*4882a593Smuzhiyun
1985*4882a593Smuzhiyun /*
1986*4882a593Smuzhiyun * Callback for the T2 ESPI 'stuck packet feature' workaorund
1987*4882a593Smuzhiyun */
espibug_workaround_t204(struct timer_list * t)1988*4882a593Smuzhiyun static void espibug_workaround_t204(struct timer_list *t)
1989*4882a593Smuzhiyun {
1990*4882a593Smuzhiyun struct sge *sge = from_timer(sge, t, espibug_timer);
1991*4882a593Smuzhiyun struct adapter *adapter = sge->adapter;
1992*4882a593Smuzhiyun unsigned int nports = adapter->params.nports;
1993*4882a593Smuzhiyun u32 seop[MAX_NPORTS];
1994*4882a593Smuzhiyun
1995*4882a593Smuzhiyun if (adapter->open_device_map & PORT_MASK) {
1996*4882a593Smuzhiyun int i;
1997*4882a593Smuzhiyun
1998*4882a593Smuzhiyun if (t1_espi_get_mon_t204(adapter, &(seop[0]), 0) < 0)
1999*4882a593Smuzhiyun return;
2000*4882a593Smuzhiyun
2001*4882a593Smuzhiyun for (i = 0; i < nports; i++) {
2002*4882a593Smuzhiyun struct sk_buff *skb = sge->espibug_skb[i];
2003*4882a593Smuzhiyun
2004*4882a593Smuzhiyun if (!netif_running(adapter->port[i].dev) ||
2005*4882a593Smuzhiyun netif_queue_stopped(adapter->port[i].dev) ||
2006*4882a593Smuzhiyun !seop[i] || ((seop[i] & 0xfff) != 0) || !skb)
2007*4882a593Smuzhiyun continue;
2008*4882a593Smuzhiyun
2009*4882a593Smuzhiyun if (!skb->cb[0]) {
2010*4882a593Smuzhiyun skb_copy_to_linear_data_offset(skb,
2011*4882a593Smuzhiyun sizeof(struct cpl_tx_pkt),
2012*4882a593Smuzhiyun ch_mac_addr,
2013*4882a593Smuzhiyun ETH_ALEN);
2014*4882a593Smuzhiyun skb_copy_to_linear_data_offset(skb,
2015*4882a593Smuzhiyun skb->len - 10,
2016*4882a593Smuzhiyun ch_mac_addr,
2017*4882a593Smuzhiyun ETH_ALEN);
2018*4882a593Smuzhiyun skb->cb[0] = 0xff;
2019*4882a593Smuzhiyun }
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun /* bump the reference count to avoid freeing of
2022*4882a593Smuzhiyun * the skb once the DMA has completed.
2023*4882a593Smuzhiyun */
2024*4882a593Smuzhiyun skb = skb_get(skb);
2025*4882a593Smuzhiyun t1_sge_tx(skb, adapter, 0, adapter->port[i].dev);
2026*4882a593Smuzhiyun }
2027*4882a593Smuzhiyun }
2028*4882a593Smuzhiyun mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout);
2029*4882a593Smuzhiyun }
2030*4882a593Smuzhiyun
espibug_workaround(struct timer_list * t)2031*4882a593Smuzhiyun static void espibug_workaround(struct timer_list *t)
2032*4882a593Smuzhiyun {
2033*4882a593Smuzhiyun struct sge *sge = from_timer(sge, t, espibug_timer);
2034*4882a593Smuzhiyun struct adapter *adapter = sge->adapter;
2035*4882a593Smuzhiyun
2036*4882a593Smuzhiyun if (netif_running(adapter->port[0].dev)) {
2037*4882a593Smuzhiyun struct sk_buff *skb = sge->espibug_skb[0];
2038*4882a593Smuzhiyun u32 seop = t1_espi_get_mon(adapter, 0x930, 0);
2039*4882a593Smuzhiyun
2040*4882a593Smuzhiyun if ((seop & 0xfff0fff) == 0xfff && skb) {
2041*4882a593Smuzhiyun if (!skb->cb[0]) {
2042*4882a593Smuzhiyun skb_copy_to_linear_data_offset(skb,
2043*4882a593Smuzhiyun sizeof(struct cpl_tx_pkt),
2044*4882a593Smuzhiyun ch_mac_addr,
2045*4882a593Smuzhiyun ETH_ALEN);
2046*4882a593Smuzhiyun skb_copy_to_linear_data_offset(skb,
2047*4882a593Smuzhiyun skb->len - 10,
2048*4882a593Smuzhiyun ch_mac_addr,
2049*4882a593Smuzhiyun ETH_ALEN);
2050*4882a593Smuzhiyun skb->cb[0] = 0xff;
2051*4882a593Smuzhiyun }
2052*4882a593Smuzhiyun
2053*4882a593Smuzhiyun /* bump the reference count to avoid freeing of the
2054*4882a593Smuzhiyun * skb once the DMA has completed.
2055*4882a593Smuzhiyun */
2056*4882a593Smuzhiyun skb = skb_get(skb);
2057*4882a593Smuzhiyun t1_sge_tx(skb, adapter, 0, adapter->port[0].dev);
2058*4882a593Smuzhiyun }
2059*4882a593Smuzhiyun }
2060*4882a593Smuzhiyun mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout);
2061*4882a593Smuzhiyun }
2062*4882a593Smuzhiyun
2063*4882a593Smuzhiyun /*
2064*4882a593Smuzhiyun * Creates a t1_sge structure and returns suggested resource parameters.
2065*4882a593Smuzhiyun */
t1_sge_create(struct adapter * adapter,struct sge_params * p)2066*4882a593Smuzhiyun struct sge *t1_sge_create(struct adapter *adapter, struct sge_params *p)
2067*4882a593Smuzhiyun {
2068*4882a593Smuzhiyun struct sge *sge = kzalloc(sizeof(*sge), GFP_KERNEL);
2069*4882a593Smuzhiyun int i;
2070*4882a593Smuzhiyun
2071*4882a593Smuzhiyun if (!sge)
2072*4882a593Smuzhiyun return NULL;
2073*4882a593Smuzhiyun
2074*4882a593Smuzhiyun sge->adapter = adapter;
2075*4882a593Smuzhiyun sge->netdev = adapter->port[0].dev;
2076*4882a593Smuzhiyun sge->rx_pkt_pad = t1_is_T1B(adapter) ? 0 : 2;
2077*4882a593Smuzhiyun sge->jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
2078*4882a593Smuzhiyun
2079*4882a593Smuzhiyun for_each_port(adapter, i) {
2080*4882a593Smuzhiyun sge->port_stats[i] = alloc_percpu(struct sge_port_stats);
2081*4882a593Smuzhiyun if (!sge->port_stats[i])
2082*4882a593Smuzhiyun goto nomem_port;
2083*4882a593Smuzhiyun }
2084*4882a593Smuzhiyun
2085*4882a593Smuzhiyun timer_setup(&sge->tx_reclaim_timer, sge_tx_reclaim_cb, 0);
2086*4882a593Smuzhiyun
2087*4882a593Smuzhiyun if (is_T2(sge->adapter)) {
2088*4882a593Smuzhiyun timer_setup(&sge->espibug_timer,
2089*4882a593Smuzhiyun adapter->params.nports > 1 ? espibug_workaround_t204 : espibug_workaround,
2090*4882a593Smuzhiyun 0);
2091*4882a593Smuzhiyun
2092*4882a593Smuzhiyun if (adapter->params.nports > 1)
2093*4882a593Smuzhiyun tx_sched_init(sge);
2094*4882a593Smuzhiyun
2095*4882a593Smuzhiyun sge->espibug_timeout = 1;
2096*4882a593Smuzhiyun /* for T204, every 10ms */
2097*4882a593Smuzhiyun if (adapter->params.nports > 1)
2098*4882a593Smuzhiyun sge->espibug_timeout = HZ/100;
2099*4882a593Smuzhiyun }
2100*4882a593Smuzhiyun
2101*4882a593Smuzhiyun
2102*4882a593Smuzhiyun p->cmdQ_size[0] = SGE_CMDQ0_E_N;
2103*4882a593Smuzhiyun p->cmdQ_size[1] = SGE_CMDQ1_E_N;
2104*4882a593Smuzhiyun p->freelQ_size[!sge->jumbo_fl] = SGE_FREEL_SIZE;
2105*4882a593Smuzhiyun p->freelQ_size[sge->jumbo_fl] = SGE_JUMBO_FREEL_SIZE;
2106*4882a593Smuzhiyun if (sge->tx_sched) {
2107*4882a593Smuzhiyun if (board_info(sge->adapter)->board == CHBT_BOARD_CHT204)
2108*4882a593Smuzhiyun p->rx_coalesce_usecs = 15;
2109*4882a593Smuzhiyun else
2110*4882a593Smuzhiyun p->rx_coalesce_usecs = 50;
2111*4882a593Smuzhiyun } else
2112*4882a593Smuzhiyun p->rx_coalesce_usecs = 50;
2113*4882a593Smuzhiyun
2114*4882a593Smuzhiyun p->coalesce_enable = 0;
2115*4882a593Smuzhiyun p->sample_interval_usecs = 0;
2116*4882a593Smuzhiyun
2117*4882a593Smuzhiyun return sge;
2118*4882a593Smuzhiyun nomem_port:
2119*4882a593Smuzhiyun while (i >= 0) {
2120*4882a593Smuzhiyun free_percpu(sge->port_stats[i]);
2121*4882a593Smuzhiyun --i;
2122*4882a593Smuzhiyun }
2123*4882a593Smuzhiyun kfree(sge);
2124*4882a593Smuzhiyun return NULL;
2125*4882a593Smuzhiyun
2126*4882a593Smuzhiyun }
2127