cxgb_sge.c revision 1.3 1 1.1 jklos /**************************************************************************
2 1.1 jklos
3 1.1 jklos Copyright (c) 2007, Chelsio Inc.
4 1.1 jklos All rights reserved.
5 1.1 jklos
6 1.1 jklos Redistribution and use in source and binary forms, with or without
7 1.1 jklos modification, are permitted provided that the following conditions are met:
8 1.1 jklos
9 1.1 jklos 1. Redistributions of source code must retain the above copyright notice,
10 1.1 jklos this list of conditions and the following disclaimer.
11 1.1 jklos
12 1.1 jklos 2. Neither the name of the Chelsio Corporation nor the names of its
13 1.1 jklos contributors may be used to endorse or promote products derived from
14 1.1 jklos this software without specific prior written permission.
15 1.1 jklos
16 1.1 jklos THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 1.1 jklos AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 1.1 jklos IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 1.1 jklos ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 1.1 jklos LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 jklos CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 jklos SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 jklos INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 jklos CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 jklos ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 jklos POSSIBILITY OF SUCH DAMAGE.
27 1.1 jklos
28 1.1 jklos ***************************************************************************/
29 1.1 jklos
30 1.1 jklos #include <sys/cdefs.h>
31 1.3 ozaki __KERNEL_RCSID(0, "$NetBSD: cxgb_sge.c,v 1.3 2016/02/09 08:32:11 ozaki-r Exp $");
32 1.1 jklos
33 1.1 jklos #include <sys/param.h>
34 1.1 jklos #include <sys/systm.h>
35 1.1 jklos #include <sys/kernel.h>
36 1.1 jklos #include <sys/conf.h>
37 1.2 dyoung #include <sys/bus.h>
38 1.1 jklos #include <sys/queue.h>
39 1.1 jklos #include <sys/sysctl.h>
40 1.1 jklos
41 1.1 jklos #include <sys/proc.h>
42 1.1 jklos #include <sys/sched.h>
43 1.1 jklos #include <sys/systm.h>
44 1.1 jklos
45 1.1 jklos #include <netinet/in_systm.h>
46 1.1 jklos #include <netinet/in.h>
47 1.1 jklos #include <netinet/ip.h>
48 1.1 jklos #include <netinet/tcp.h>
49 1.1 jklos
50 1.1 jklos #include <dev/pci/pcireg.h>
51 1.1 jklos #include <dev/pci/pcivar.h>
52 1.1 jklos
53 1.1 jklos #ifdef CONFIG_DEFINED
54 1.1 jklos #include <cxgb_include.h>
55 1.1 jklos #else
56 1.1 jklos #include <dev/pci/cxgb/cxgb_include.h>
57 1.1 jklos #endif
58 1.1 jklos
59 1.1 jklos uint32_t collapse_free = 0;
60 1.1 jklos uint32_t mb_free_vec_free = 0;
61 1.1 jklos int txq_fills = 0;
62 1.1 jklos int collapse_mbufs = 0;
63 1.1 jklos static int bogus_imm = 0;
64 1.1 jklos #ifndef DISABLE_MBUF_IOVEC
65 1.1 jklos static int recycle_enable = 1;
66 1.1 jklos #endif
67 1.1 jklos
68 1.1 jklos #define USE_GTS 0
69 1.1 jklos
70 1.1 jklos #define SGE_RX_SM_BUF_SIZE 1536
71 1.1 jklos #define SGE_RX_DROP_THRES 16
72 1.1 jklos #define SGE_RX_COPY_THRES 128
73 1.1 jklos
74 1.1 jklos /*
75 1.1 jklos * Period of the Tx buffer reclaim timer. This timer does not need to run
76 1.1 jklos * frequently as Tx buffers are usually reclaimed by new Tx packets.
77 1.1 jklos */
78 1.1 jklos #define TX_RECLAIM_PERIOD (hz >> 1)
79 1.1 jklos
80 1.1 jklos /*
81 1.1 jklos * work request size in bytes
82 1.1 jklos */
83 1.1 jklos #define WR_LEN (WR_FLITS * 8)
84 1.1 jklos
85 1.1 jklos /*
86 1.1 jklos * Values for sge_txq.flags
87 1.1 jklos */
88 1.1 jklos enum {
89 1.1 jklos TXQ_RUNNING = 1 << 0, /* fetch engine is running */
90 1.1 jklos TXQ_LAST_PKT_DB = 1 << 1, /* last packet rang the doorbell */
91 1.1 jklos };
92 1.1 jklos
93 1.1 jklos struct tx_desc {
94 1.1 jklos uint64_t flit[TX_DESC_FLITS];
95 1.1 jklos } __packed;
96 1.1 jklos
97 1.1 jklos struct rx_desc {
98 1.1 jklos uint32_t addr_lo;
99 1.1 jklos uint32_t len_gen;
100 1.1 jklos uint32_t gen2;
101 1.1 jklos uint32_t addr_hi;
102 1.1 jklos } __packed;
103 1.1 jklos
104 1.1 jklos struct rsp_desc { /* response queue descriptor */
105 1.1 jklos struct rss_header rss_hdr;
106 1.1 jklos uint32_t flags;
107 1.1 jklos uint32_t len_cq;
108 1.1 jklos uint8_t imm_data[47];
109 1.1 jklos uint8_t intr_gen;
110 1.1 jklos } __packed;
111 1.1 jklos
112 1.1 jklos #define RX_SW_DESC_MAP_CREATED (1 << 0)
113 1.1 jklos #define TX_SW_DESC_MAP_CREATED (1 << 1)
114 1.1 jklos #define RX_SW_DESC_INUSE (1 << 3)
115 1.1 jklos #define TX_SW_DESC_MAPPED (1 << 4)
116 1.1 jklos
117 1.1 jklos #define RSPQ_NSOP_NEOP G_RSPD_SOP_EOP(0)
118 1.1 jklos #define RSPQ_EOP G_RSPD_SOP_EOP(F_RSPD_EOP)
119 1.1 jklos #define RSPQ_SOP G_RSPD_SOP_EOP(F_RSPD_SOP)
120 1.1 jklos #define RSPQ_SOP_EOP G_RSPD_SOP_EOP(F_RSPD_SOP|F_RSPD_EOP)
121 1.1 jklos
122 1.1 jklos struct tx_sw_desc { /* SW state per Tx descriptor */
123 1.1 jklos struct mbuf *m;
124 1.1 jklos bus_dma_segment_t segs[1];
125 1.1 jklos bus_dmamap_t map;
126 1.1 jklos int flags;
127 1.1 jklos };
128 1.1 jklos
129 1.1 jklos struct rx_sw_desc { /* SW state per Rx descriptor */
130 1.1 jklos void *cl;
131 1.1 jklos bus_dmamap_t map;
132 1.1 jklos int flags;
133 1.1 jklos };
134 1.1 jklos
135 1.1 jklos struct txq_state {
136 1.1 jklos unsigned int compl;
137 1.1 jklos unsigned int gen;
138 1.1 jklos unsigned int pidx;
139 1.1 jklos };
140 1.1 jklos
141 1.1 jklos /*
142 1.1 jklos * Maps a number of flits to the number of Tx descriptors that can hold them.
143 1.1 jklos * The formula is
144 1.1 jklos *
145 1.1 jklos * desc = 1 + (flits - 2) / (WR_FLITS - 1).
146 1.1 jklos *
147 1.1 jklos * HW allows up to 4 descriptors to be combined into a WR.
148 1.1 jklos */
149 1.1 jklos static uint8_t flit_desc_map[] = {
150 1.1 jklos 0,
151 1.1 jklos #if SGE_NUM_GENBITS == 1
152 1.1 jklos 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
153 1.1 jklos 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
154 1.1 jklos 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
155 1.1 jklos 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
156 1.1 jklos #elif SGE_NUM_GENBITS == 2
157 1.1 jklos 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
158 1.1 jklos 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
159 1.1 jklos 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
160 1.1 jklos 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
161 1.1 jklos #else
162 1.1 jklos # error "SGE_NUM_GENBITS must be 1 or 2"
163 1.1 jklos #endif
164 1.1 jklos };
165 1.1 jklos
166 1.1 jklos
167 1.1 jklos static int lro_default = 0;
168 1.1 jklos int cxgb_debug = 0;
169 1.1 jklos
170 1.1 jklos static void t3_free_qset(adapter_t *sc, struct sge_qset *q);
171 1.1 jklos static void sge_timer_cb(void *arg);
172 1.1 jklos static void sge_timer_reclaim(struct work *wk, void *arg);
173 1.1 jklos static void sge_txq_reclaim_handler(struct work *wk, void *arg);
174 1.1 jklos static int free_tx_desc(struct sge_txq *q, int n, struct mbuf **m_vec);
175 1.1 jklos
176 1.1 jklos /**
177 1.1 jklos * reclaim_completed_tx - reclaims completed Tx descriptors
178 1.1 jklos * @adapter: the adapter
179 1.1 jklos * @q: the Tx queue to reclaim completed descriptors from
180 1.1 jklos *
181 1.1 jklos * Reclaims Tx descriptors that the SGE has indicated it has processed,
182 1.1 jklos * and frees the associated buffers if possible. Called with the Tx
183 1.1 jklos * queue's lock held.
184 1.1 jklos */
185 1.1 jklos static __inline int
186 1.1 jklos reclaim_completed_tx(struct sge_txq *q, int nbufs, struct mbuf **mvec)
187 1.1 jklos {
188 1.1 jklos int reclaimed, reclaim = desc_reclaimable(q);
189 1.1 jklos int n = 0;
190 1.1 jklos
191 1.1 jklos mtx_assert(&q->lock, MA_OWNED);
192 1.1 jklos if (reclaim > 0) {
193 1.1 jklos n = free_tx_desc(q, min(reclaim, nbufs), mvec);
194 1.1 jklos reclaimed = min(reclaim, nbufs);
195 1.1 jklos q->cleaned += reclaimed;
196 1.1 jklos q->in_use -= reclaimed;
197 1.1 jklos }
198 1.1 jklos return (n);
199 1.1 jklos }
200 1.1 jklos
201 1.1 jklos /**
202 1.1 jklos * should_restart_tx - are there enough resources to restart a Tx queue?
203 1.1 jklos * @q: the Tx queue
204 1.1 jklos *
205 1.1 jklos * Checks if there are enough descriptors to restart a suspended Tx queue.
206 1.1 jklos */
207 1.1 jklos static __inline int
208 1.1 jklos should_restart_tx(const struct sge_txq *q)
209 1.1 jklos {
210 1.1 jklos unsigned int r = q->processed - q->cleaned;
211 1.1 jklos
212 1.1 jklos return q->in_use - r < (q->size >> 1);
213 1.1 jklos }
214 1.1 jklos
215 1.1 jklos /**
216 1.1 jklos * t3_sge_init - initialize SGE
217 1.1 jklos * @adap: the adapter
218 1.1 jklos * @p: the SGE parameters
219 1.1 jklos *
220 1.1 jklos * Performs SGE initialization needed every time after a chip reset.
221 1.1 jklos * We do not initialize any of the queue sets here, instead the driver
222 1.1 jklos * top-level must request those individually. We also do not enable DMA
223 1.1 jklos * here, that should be done after the queues have been set up.
224 1.1 jklos */
225 1.1 jklos void
226 1.1 jklos t3_sge_init(adapter_t *adap, struct sge_params *p)
227 1.1 jklos {
228 1.1 jklos u_int ctrl, ups;
229 1.1 jklos
230 1.1 jklos ups = 0; /* = ffs(pci_resource_len(adap->pdev, 2) >> 12); */
231 1.1 jklos
232 1.1 jklos ctrl = F_DROPPKT | V_PKTSHIFT(2) | F_FLMODE | F_AVOIDCQOVFL |
233 1.1 jklos F_CQCRDTCTRL |
234 1.1 jklos V_HOSTPAGESIZE(PAGE_SHIFT - 11) | F_BIGENDIANINGRESS |
235 1.1 jklos V_USERSPACESIZE(ups ? ups - 1 : 0) | F_ISCSICOALESCING;
236 1.1 jklos #if SGE_NUM_GENBITS == 1
237 1.1 jklos ctrl |= F_EGRGENCTRL;
238 1.1 jklos #endif
239 1.1 jklos if (adap->params.rev > 0) {
240 1.1 jklos if (!(adap->flags & (USING_MSIX | USING_MSI)))
241 1.1 jklos ctrl |= F_ONEINTMULTQ | F_OPTONEINTMULTQ;
242 1.1 jklos ctrl |= F_CQCRDTCTRL | F_AVOIDCQOVFL;
243 1.1 jklos }
244 1.1 jklos t3_write_reg(adap, A_SG_CONTROL, ctrl);
245 1.1 jklos t3_write_reg(adap, A_SG_EGR_RCQ_DRB_THRSH, V_HIRCQDRBTHRSH(512) |
246 1.1 jklos V_LORCQDRBTHRSH(512));
247 1.1 jklos t3_write_reg(adap, A_SG_TIMER_TICK, core_ticks_per_usec(adap) / 10);
248 1.1 jklos t3_write_reg(adap, A_SG_CMDQ_CREDIT_TH, V_THRESHOLD(32) |
249 1.1 jklos V_TIMEOUT(200 * core_ticks_per_usec(adap)));
250 1.1 jklos t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH, 1000);
251 1.1 jklos t3_write_reg(adap, A_SG_HI_DRB_LO_THRSH, 256);
252 1.1 jklos t3_write_reg(adap, A_SG_LO_DRB_HI_THRSH, 1000);
253 1.1 jklos t3_write_reg(adap, A_SG_LO_DRB_LO_THRSH, 256);
254 1.1 jklos t3_write_reg(adap, A_SG_OCO_BASE, V_BASE1(0xfff));
255 1.1 jklos t3_write_reg(adap, A_SG_DRB_PRI_THRESH, 63 * 1024);
256 1.1 jklos }
257 1.1 jklos
258 1.1 jklos
259 1.1 jklos /**
260 1.1 jklos * sgl_len - calculates the size of an SGL of the given capacity
261 1.1 jklos * @n: the number of SGL entries
262 1.1 jklos *
263 1.1 jklos * Calculates the number of flits needed for a scatter/gather list that
264 1.1 jklos * can hold the given number of entries.
265 1.1 jklos */
266 1.1 jklos static __inline unsigned int
267 1.1 jklos sgl_len(unsigned int n)
268 1.1 jklos {
269 1.1 jklos return ((3 * n) / 2 + (n & 1));
270 1.1 jklos }
271 1.1 jklos
272 1.1 jklos /**
273 1.1 jklos * get_imm_packet - return the next ingress packet buffer from a response
274 1.1 jklos * @resp: the response descriptor containing the packet data
275 1.1 jklos *
276 1.1 jklos * Return a packet containing the immediate data of the given response.
277 1.1 jklos */
278 1.1 jklos #ifdef DISABLE_MBUF_IOVEC
279 1.1 jklos static __inline int
280 1.1 jklos get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct t3_mbuf_hdr *mh)
281 1.1 jklos {
282 1.1 jklos struct mbuf *m;
283 1.1 jklos int len;
284 1.1 jklos uint32_t flags = ntohl(resp->flags);
285 1.1 jklos uint8_t sopeop = G_RSPD_SOP_EOP(flags);
286 1.1 jklos
287 1.1 jklos /*
288 1.1 jklos * would be a firmware bug
289 1.1 jklos */
290 1.1 jklos if (sopeop == RSPQ_NSOP_NEOP || sopeop == RSPQ_SOP)
291 1.1 jklos return (0);
292 1.1 jklos
293 1.1 jklos m = m_gethdr(M_NOWAIT, MT_DATA);
294 1.1 jklos len = G_RSPD_LEN(ntohl(resp->len_cq));
295 1.1 jklos
296 1.1 jklos if (m) {
297 1.1 jklos MH_ALIGN(m, IMMED_PKT_SIZE);
298 1.1 jklos memcpy(m->m_data, resp->imm_data, IMMED_PKT_SIZE);
299 1.1 jklos m->m_len = len;
300 1.1 jklos
301 1.1 jklos switch (sopeop) {
302 1.1 jklos case RSPQ_SOP_EOP:
303 1.1 jklos mh->mh_head = mh->mh_tail = m;
304 1.1 jklos m->m_pkthdr.len = len;
305 1.1 jklos m->m_flags |= M_PKTHDR;
306 1.1 jklos break;
307 1.1 jklos case RSPQ_EOP:
308 1.1 jklos m->m_flags &= ~M_PKTHDR;
309 1.1 jklos mh->mh_head->m_pkthdr.len += len;
310 1.1 jklos mh->mh_tail->m_next = m;
311 1.1 jklos mh->mh_tail = m;
312 1.1 jklos break;
313 1.1 jklos }
314 1.1 jklos }
315 1.1 jklos return (m != NULL);
316 1.1 jklos }
317 1.1 jklos
318 1.1 jklos #else
319 1.1 jklos static int
320 1.1 jklos get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void *cl, uint32_t flags)
321 1.1 jklos {
322 1.1 jklos int len, error;
323 1.1 jklos uint8_t sopeop = G_RSPD_SOP_EOP(flags);
324 1.1 jklos
325 1.1 jklos /*
326 1.1 jklos * would be a firmware bug
327 1.1 jklos */
328 1.1 jklos len = G_RSPD_LEN(ntohl(resp->len_cq));
329 1.1 jklos if (sopeop == RSPQ_NSOP_NEOP || sopeop == RSPQ_SOP) {
330 1.1 jklos if (cxgb_debug)
331 1.1 jklos device_printf(sc->dev, "unexpected value sopeop=%d flags=0x%x len=%din get_imm_packet\n", sopeop, flags, len);
332 1.1 jklos bogus_imm++;
333 1.1 jklos return (EINVAL);
334 1.1 jklos }
335 1.1 jklos error = 0;
336 1.1 jklos switch (sopeop) {
337 1.1 jklos case RSPQ_SOP_EOP:
338 1.1 jklos m->m_len = m->m_pkthdr.len = len;
339 1.1 jklos memcpy(mtod(m, uint8_t *), resp->imm_data, len);
340 1.1 jklos break;
341 1.1 jklos case RSPQ_EOP:
342 1.1 jklos memcpy(cl, resp->imm_data, len);
343 1.1 jklos m_iovappend(m, cl, MSIZE, len, 0);
344 1.1 jklos break;
345 1.1 jklos default:
346 1.1 jklos bogus_imm++;
347 1.1 jklos error = EINVAL;
348 1.1 jklos }
349 1.1 jklos
350 1.1 jklos return (error);
351 1.1 jklos }
352 1.1 jklos #endif
353 1.1 jklos
354 1.1 jklos static __inline u_int
355 1.1 jklos flits_to_desc(u_int n)
356 1.1 jklos {
357 1.1 jklos return (flit_desc_map[n]);
358 1.1 jklos }
359 1.1 jklos
360 1.1 jklos void
361 1.1 jklos t3_sge_err_intr_handler(adapter_t *adapter)
362 1.1 jklos {
363 1.1 jklos unsigned int v, status;
364 1.1 jklos
365 1.1 jklos
366 1.1 jklos status = t3_read_reg(adapter, A_SG_INT_CAUSE);
367 1.1 jklos
368 1.1 jklos if (status & F_RSPQCREDITOVERFOW)
369 1.1 jklos CH_ALERT(adapter, "SGE response queue credit overflow\n");
370 1.1 jklos
371 1.1 jklos if (status & F_RSPQDISABLED) {
372 1.1 jklos v = t3_read_reg(adapter, A_SG_RSPQ_FL_STATUS);
373 1.1 jklos
374 1.1 jklos CH_ALERT(adapter,
375 1.1 jklos "packet delivered to disabled response queue (0x%x)\n",
376 1.1 jklos (v >> S_RSPQ0DISABLED) & 0xff);
377 1.1 jklos }
378 1.1 jklos
379 1.1 jklos t3_write_reg(adapter, A_SG_INT_CAUSE, status);
380 1.1 jklos if (status & (F_RSPQCREDITOVERFOW | F_RSPQDISABLED))
381 1.1 jklos t3_fatal_err(adapter);
382 1.1 jklos }
383 1.1 jklos
384 1.1 jklos void
385 1.1 jklos t3_sge_prep(adapter_t *adap, struct sge_params *p)
386 1.1 jklos {
387 1.1 jklos int i;
388 1.1 jklos
389 1.1 jklos /* XXX Does ETHER_ALIGN need to be accounted for here? */
390 1.1 jklos p->max_pkt_size = MJUM16BYTES - sizeof(struct cpl_rx_data);
391 1.1 jklos
392 1.1 jklos for (i = 0; i < SGE_QSETS; ++i) {
393 1.1 jklos struct qset_params *q = p->qset + i;
394 1.1 jklos
395 1.1 jklos q->polling = adap->params.rev > 0;
396 1.1 jklos
397 1.1 jklos if (adap->params.nports > 2)
398 1.1 jklos q->coalesce_nsecs = 50000;
399 1.1 jklos else
400 1.1 jklos q->coalesce_nsecs = 5000;
401 1.1 jklos
402 1.1 jklos q->rspq_size = RSPQ_Q_SIZE;
403 1.1 jklos q->fl_size = FL_Q_SIZE;
404 1.1 jklos q->jumbo_size = JUMBO_Q_SIZE;
405 1.1 jklos q->txq_size[TXQ_ETH] = TX_ETH_Q_SIZE;
406 1.1 jklos q->txq_size[TXQ_OFLD] = 1024;
407 1.1 jklos q->txq_size[TXQ_CTRL] = 256;
408 1.1 jklos q->cong_thres = 0;
409 1.1 jklos }
410 1.1 jklos }
411 1.1 jklos
412 1.1 jklos int
413 1.1 jklos t3_sge_alloc(adapter_t *sc)
414 1.1 jklos {
415 1.1 jklos /* The parent tag. */
416 1.1 jklos sc->parent_dmat = sc->pa.pa_dmat;
417 1.1 jklos
418 1.1 jklos /*
419 1.1 jklos * DMA tag for normal sized RX frames
420 1.1 jklos */
421 1.1 jklos sc->rx_dmat = sc->pa.pa_dmat;
422 1.1 jklos
423 1.1 jklos /*
424 1.1 jklos * DMA tag for jumbo sized RX frames.
425 1.1 jklos */
426 1.1 jklos sc->rx_jumbo_dmat = sc->pa.pa_dmat;
427 1.1 jklos
428 1.1 jklos /*
429 1.1 jklos * DMA tag for TX frames.
430 1.1 jklos */
431 1.1 jklos sc->tx_dmat = sc->pa.pa_dmat;
432 1.1 jklos
433 1.1 jklos return (0);
434 1.1 jklos }
435 1.1 jklos
436 1.1 jklos int
437 1.1 jklos t3_sge_free(struct adapter * sc)
438 1.1 jklos {
439 1.1 jklos return (0);
440 1.1 jklos }
441 1.1 jklos
442 1.1 jklos void
443 1.1 jklos t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p)
444 1.1 jklos {
445 1.1 jklos
446 1.1 jklos qs->rspq.holdoff_tmr = max(p->coalesce_nsecs/100, 1U);
447 1.1 jklos qs->rspq.polling = 0 /* p->polling */;
448 1.1 jklos }
449 1.1 jklos
450 1.1 jklos /**
451 1.1 jklos * refill_fl - refill an SGE free-buffer list
452 1.1 jklos * @sc: the controller softc
453 1.1 jklos * @q: the free-list to refill
454 1.1 jklos * @n: the number of new buffers to allocate
455 1.1 jklos *
456 1.1 jklos * (Re)populate an SGE free-buffer list with up to @n new packet buffers.
457 1.1 jklos * The caller must assure that @n does not exceed the queue's capacity.
458 1.1 jklos */
459 1.1 jklos static void
460 1.1 jklos refill_fl(adapter_t *sc, struct sge_fl *q, int n)
461 1.1 jklos {
462 1.1 jklos struct rx_sw_desc *sd = &q->sdesc[q->pidx];
463 1.1 jklos struct rx_desc *d = &q->desc[q->pidx];
464 1.1 jklos void *cl;
465 1.1 jklos int err;
466 1.1 jklos
467 1.1 jklos while (n--) {
468 1.1 jklos /*
469 1.1 jklos * We only allocate a cluster, mbuf allocation happens after rx
470 1.1 jklos */
471 1.1 jklos if ((sd->flags & RX_SW_DESC_MAP_CREATED) == 0)
472 1.1 jklos {
473 1.1 jklos err = bus_dmamap_create(sc->pa.pa_dmat,
474 1.1 jklos q->buf_size, 1, q->buf_size, 0,
475 1.1 jklos BUS_DMA_ALLOCNOW, &sd->map);
476 1.1 jklos if (err != 0)
477 1.1 jklos {
478 1.1 jklos log(LOG_WARNING, "failure in refill_fl\n");
479 1.1 jklos return;
480 1.1 jklos }
481 1.1 jklos sd->flags |= RX_SW_DESC_MAP_CREATED;
482 1.1 jklos }
483 1.1 jklos cl = malloc(q->buf_size, M_DEVBUF, M_NOWAIT);
484 1.1 jklos if (cl == NULL)
485 1.1 jklos {
486 1.1 jklos log(LOG_WARNING, "Failed to allocate cluster\n");
487 1.1 jklos break;
488 1.1 jklos }
489 1.1 jklos err = bus_dmamap_load(sc->pa.pa_dmat, sd->map, cl, q->buf_size, NULL, BUS_DMA_NOWAIT);
490 1.1 jklos if (err)
491 1.1 jklos {
492 1.1 jklos log(LOG_WARNING, "failure in refill_fl\n");
493 1.1 jklos free(cl, M_DEVBUF);
494 1.1 jklos return;
495 1.1 jklos }
496 1.1 jklos
497 1.1 jklos sd->flags |= RX_SW_DESC_INUSE;
498 1.1 jklos sd->cl = cl;
499 1.1 jklos d->addr_lo = htobe32(sd->map->dm_segs[0].ds_addr & 0xffffffff);
500 1.1 jklos d->addr_hi = htobe32(((uint64_t)sd->map->dm_segs[0].ds_addr>>32) & 0xffffffff);
501 1.1 jklos d->len_gen = htobe32(V_FLD_GEN1(q->gen));
502 1.1 jklos d->gen2 = htobe32(V_FLD_GEN2(q->gen));
503 1.1 jklos
504 1.1 jklos d++;
505 1.1 jklos sd++;
506 1.1 jklos
507 1.1 jklos if (++q->pidx == q->size) {
508 1.1 jklos q->pidx = 0;
509 1.1 jklos q->gen ^= 1;
510 1.1 jklos sd = q->sdesc;
511 1.1 jklos d = q->desc;
512 1.1 jklos }
513 1.1 jklos q->credits++;
514 1.1 jklos }
515 1.1 jklos
516 1.1 jklos t3_write_reg(sc, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
517 1.1 jklos }
518 1.1 jklos
519 1.1 jklos
520 1.1 jklos /**
521 1.1 jklos * free_rx_bufs - free the Rx buffers on an SGE free list
522 1.1 jklos * @sc: the controle softc
523 1.1 jklos * @q: the SGE free list to clean up
524 1.1 jklos *
525 1.1 jklos * Release the buffers on an SGE free-buffer Rx queue. HW fetching from
526 1.1 jklos * this queue should be stopped before calling this function.
527 1.1 jklos */
528 1.1 jklos static void
529 1.1 jklos free_rx_bufs(adapter_t *sc, struct sge_fl *q)
530 1.1 jklos {
531 1.1 jklos u_int cidx = q->cidx;
532 1.1 jklos
533 1.1 jklos while (q->credits--) {
534 1.1 jklos struct rx_sw_desc *d = &q->sdesc[cidx];
535 1.1 jklos
536 1.1 jklos if (d->flags & RX_SW_DESC_INUSE) {
537 1.1 jklos bus_dmamap_unload(q->entry_tag, d->map);
538 1.1 jklos bus_dmamap_destroy(q->entry_tag, d->map);
539 1.1 jklos d->map = NULL;
540 1.1 jklos free(d->cl, M_DEVBUF);
541 1.1 jklos d->cl = NULL;
542 1.1 jklos }
543 1.1 jklos d->cl = NULL;
544 1.1 jklos if (++cidx == q->size)
545 1.1 jklos cidx = 0;
546 1.1 jklos }
547 1.1 jklos }
548 1.1 jklos
549 1.1 jklos static __inline void
550 1.1 jklos __refill_fl(adapter_t *adap, struct sge_fl *fl)
551 1.1 jklos {
552 1.1 jklos refill_fl(adap, fl, min(16U, fl->size - fl->credits));
553 1.1 jklos }
554 1.1 jklos
555 1.1 jklos #ifndef DISABLE_MBUF_IOVEC
556 1.1 jklos /**
557 1.1 jklos * recycle_rx_buf - recycle a receive buffer
558 1.1 jklos * @adapter: the adapter
559 1.1 jklos * @q: the SGE free list
560 1.1 jklos * @idx: index of buffer to recycle
561 1.1 jklos *
562 1.1 jklos * Recycles the specified buffer on the given free list by adding it at
563 1.1 jklos * the next available slot on the list.
564 1.1 jklos */
565 1.1 jklos static void
566 1.1 jklos recycle_rx_buf(adapter_t *adap, struct sge_fl *q, unsigned int idx)
567 1.1 jklos {
568 1.1 jklos struct rx_desc *from = &q->desc[idx];
569 1.1 jklos struct rx_desc *to = &q->desc[q->pidx];
570 1.1 jklos
571 1.1 jklos q->sdesc[q->pidx] = q->sdesc[idx];
572 1.1 jklos to->addr_lo = from->addr_lo; // already big endian
573 1.1 jklos to->addr_hi = from->addr_hi; // likewise
574 1.1 jklos wmb();
575 1.1 jklos to->len_gen = htobe32(V_FLD_GEN1(q->gen));
576 1.1 jklos to->gen2 = htobe32(V_FLD_GEN2(q->gen));
577 1.1 jklos q->credits++;
578 1.1 jklos
579 1.1 jklos if (++q->pidx == q->size) {
580 1.1 jklos q->pidx = 0;
581 1.1 jklos q->gen ^= 1;
582 1.1 jklos }
583 1.1 jklos t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
584 1.1 jklos }
585 1.1 jklos #endif
586 1.1 jklos
587 1.1 jklos static int
588 1.1 jklos alloc_ring(adapter_t *sc, size_t nelem, size_t elem_size, size_t sw_size,
589 1.1 jklos bus_addr_t *phys,
590 1.1 jklos void *desc, void *sdesc, bus_dma_tag_t *tag,
591 1.1 jklos bus_dmamap_t *map, bus_dma_tag_t parent_entry_tag, bus_dma_tag_t *entry_tag)
592 1.1 jklos {
593 1.1 jklos size_t len = nelem * elem_size;
594 1.1 jklos void *s = NULL;
595 1.1 jklos void *p = NULL;
596 1.1 jklos int err;
597 1.1 jklos bus_dma_segment_t phys_seg;
598 1.1 jklos
599 1.1 jklos int nsegs;
600 1.1 jklos
601 1.1 jklos *tag = sc->pa.pa_dmat;
602 1.1 jklos
603 1.1 jklos /* allocate wired physical memory for DMA descriptor array */
604 1.1 jklos err = bus_dmamem_alloc(*tag, len, PAGE_SIZE, 0, &phys_seg, 1,
605 1.1 jklos &nsegs, BUS_DMA_NOWAIT);
606 1.1 jklos if (err != 0)
607 1.1 jklos {
608 1.1 jklos device_printf(sc->dev, "Cannot allocate descriptor memory\n");
609 1.1 jklos return (ENOMEM);
610 1.1 jklos }
611 1.1 jklos *phys = phys_seg.ds_addr;
612 1.1 jklos
613 1.1 jklos /* map physical address to kernel virtual address */
614 1.1 jklos err = bus_dmamem_map(*tag, &phys_seg, 1, len, &p,
615 1.1 jklos BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
616 1.1 jklos if (err != 0)
617 1.1 jklos {
618 1.1 jklos device_printf(sc->dev, "Cannot map descriptor memory\n");
619 1.1 jklos return (ENOMEM);
620 1.1 jklos }
621 1.1 jklos
622 1.1 jklos memset(p, 0, len);
623 1.1 jklos *(void **)desc = p;
624 1.1 jklos
625 1.1 jklos if (sw_size)
626 1.1 jklos {
627 1.1 jklos len = nelem * sw_size;
628 1.1 jklos s = malloc(len, M_DEVBUF, M_WAITOK|M_ZERO);
629 1.1 jklos *(void **)sdesc = s;
630 1.1 jklos }
631 1.1 jklos
632 1.1 jklos if (parent_entry_tag == NULL)
633 1.1 jklos return (0);
634 1.1 jklos *entry_tag = sc->pa.pa_dmat;
635 1.1 jklos
636 1.1 jklos return (0);
637 1.1 jklos }
638 1.1 jklos
639 1.1 jklos static void
640 1.1 jklos sge_slow_intr_handler(struct work *wk, void *arg)
641 1.1 jklos {
642 1.1 jklos adapter_t *sc = arg;
643 1.1 jklos
644 1.1 jklos t3_slow_intr_handler(sc);
645 1.1 jklos }
646 1.1 jklos
647 1.1 jklos /**
648 1.1 jklos * sge_timer_cb - perform periodic maintenance of an SGE qset
649 1.1 jklos * @data: the SGE queue set to maintain
650 1.1 jklos *
651 1.1 jklos * Runs periodically from a timer to perform maintenance of an SGE queue
652 1.1 jklos * set. It performs two tasks:
653 1.1 jklos *
654 1.1 jklos * a) Cleans up any completed Tx descriptors that may still be pending.
655 1.1 jklos * Normal descriptor cleanup happens when new packets are added to a Tx
656 1.1 jklos * queue so this timer is relatively infrequent and does any cleanup only
657 1.1 jklos * if the Tx queue has not seen any new packets in a while. We make a
658 1.1 jklos * best effort attempt to reclaim descriptors, in that we don't wait
659 1.1 jklos * around if we cannot get a queue's lock (which most likely is because
660 1.1 jklos * someone else is queueing new packets and so will also handle the clean
661 1.1 jklos * up). Since control queues use immediate data exclusively we don't
662 1.1 jklos * bother cleaning them up here.
663 1.1 jklos *
664 1.1 jklos * b) Replenishes Rx queues that have run out due to memory shortage.
665 1.1 jklos * Normally new Rx buffers are added when existing ones are consumed but
666 1.1 jklos * when out of memory a queue can become empty. We try to add only a few
667 1.1 jklos * buffers here, the queue will be replenished fully as these new buffers
668 1.1 jklos * are used up if memory shortage has subsided.
669 1.1 jklos *
670 1.1 jklos * c) Return coalesced response queue credits in case a response queue is
671 1.1 jklos * starved.
672 1.1 jklos *
673 1.1 jklos * d) Ring doorbells for T304 tunnel queues since we have seen doorbell
674 1.1 jklos * fifo overflows and the FW doesn't implement any recovery scheme yet.
675 1.1 jklos */
676 1.1 jklos
677 1.1 jklos static void
678 1.1 jklos sge_timer_cb(void *arg)
679 1.1 jklos {
680 1.1 jklos adapter_t *sc = arg;
681 1.1 jklos struct port_info *p;
682 1.1 jklos struct sge_qset *qs;
683 1.1 jklos struct sge_txq *txq;
684 1.1 jklos int i, j;
685 1.1 jklos int reclaim_eth, reclaim_ofl, refill_rx;
686 1.1 jklos
687 1.1 jklos for (i = 0; i < sc->params.nports; i++)
688 1.1 jklos for (j = 0; j < sc->port[i].nqsets; j++) {
689 1.1 jklos qs = &sc->sge.qs[i + j];
690 1.1 jklos txq = &qs->txq[0];
691 1.1 jklos reclaim_eth = txq[TXQ_ETH].processed - txq[TXQ_ETH].cleaned;
692 1.1 jklos reclaim_ofl = txq[TXQ_OFLD].processed - txq[TXQ_OFLD].cleaned;
693 1.1 jklos refill_rx = ((qs->fl[0].credits < qs->fl[0].size) ||
694 1.1 jklos (qs->fl[1].credits < qs->fl[1].size));
695 1.1 jklos if (reclaim_eth || reclaim_ofl || refill_rx) {
696 1.1 jklos p = &sc->port[i];
697 1.1 jklos workqueue_enqueue(p->timer_reclaim_task.wq, &p->timer_reclaim_task.w, NULL);
698 1.1 jklos break;
699 1.1 jklos }
700 1.1 jklos }
701 1.1 jklos if (sc->params.nports > 2) {
702 1.1 jklos int k;
703 1.1 jklos
704 1.1 jklos for_each_port(sc, k) {
705 1.1 jklos struct port_info *pi = &sc->port[k];
706 1.1 jklos
707 1.1 jklos t3_write_reg(sc, A_SG_KDOORBELL,
708 1.1 jklos F_SELEGRCNTX |
709 1.1 jklos (FW_TUNNEL_SGEEC_START + pi->first_qset));
710 1.1 jklos }
711 1.1 jklos }
712 1.1 jklos if (sc->open_device_map != 0)
713 1.1 jklos callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc);
714 1.1 jklos }
715 1.1 jklos
716 1.1 jklos /*
717 1.1 jklos * This is meant to be a catch-all function to keep sge state private
718 1.1 jklos * to sge.c
719 1.1 jklos *
720 1.1 jklos */
721 1.1 jklos int
722 1.1 jklos t3_sge_init_adapter(adapter_t *sc)
723 1.1 jklos {
724 1.1 jklos callout_init(&sc->sge_timer_ch, 0);
725 1.1 jklos callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc);
726 1.1 jklos sc->slow_intr_task.name = "sge_slow_intr";
727 1.1 jklos sc->slow_intr_task.func = sge_slow_intr_handler;
728 1.1 jklos sc->slow_intr_task.context = sc;
729 1.1 jklos kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &sc->slow_intr_task, NULL, "cxgb_make_task");
730 1.1 jklos return (0);
731 1.1 jklos }
732 1.1 jklos
733 1.1 jklos int
734 1.1 jklos t3_sge_init_port(struct port_info *p)
735 1.1 jklos {
736 1.1 jklos p->timer_reclaim_task.name = "sge_timer_reclaim";
737 1.1 jklos p->timer_reclaim_task.func = sge_timer_reclaim;
738 1.1 jklos p->timer_reclaim_task.context = p;
739 1.1 jklos kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &p->timer_reclaim_task, NULL, "cxgb_make_task");
740 1.1 jklos
741 1.1 jklos return (0);
742 1.1 jklos }
743 1.1 jklos
744 1.1 jklos void
745 1.1 jklos t3_sge_deinit_sw(adapter_t *sc)
746 1.1 jklos {
747 1.1 jklos callout_drain(&sc->sge_timer_ch);
748 1.1 jklos }
749 1.1 jklos
750 1.1 jklos /**
751 1.1 jklos * refill_rspq - replenish an SGE response queue
752 1.1 jklos * @adapter: the adapter
753 1.1 jklos * @q: the response queue to replenish
754 1.1 jklos * @credits: how many new responses to make available
755 1.1 jklos *
756 1.1 jklos * Replenishes a response queue by making the supplied number of responses
757 1.1 jklos * available to HW.
758 1.1 jklos */
759 1.1 jklos static __inline void
760 1.1 jklos refill_rspq(adapter_t *sc, const struct sge_rspq *q, u_int credits)
761 1.1 jklos {
762 1.1 jklos
763 1.1 jklos /* mbufs are allocated on demand when a rspq entry is processed. */
764 1.1 jklos t3_write_reg(sc, A_SG_RSPQ_CREDIT_RETURN,
765 1.1 jklos V_RSPQ(q->cntxt_id) | V_CREDITS(credits));
766 1.1 jklos }
767 1.1 jklos
768 1.1 jklos static __inline void
769 1.1 jklos sge_txq_reclaim_(struct sge_txq *txq)
770 1.1 jklos {
771 1.1 jklos int reclaimable, i, n;
772 1.1 jklos struct mbuf *m_vec[TX_CLEAN_MAX_DESC];
773 1.1 jklos struct port_info *p;
774 1.1 jklos
775 1.1 jklos p = txq->port;
776 1.1 jklos reclaim_more:
777 1.1 jklos n = 0;
778 1.1 jklos reclaimable = desc_reclaimable(txq);
779 1.1 jklos if (reclaimable > 0 && mtx_trylock(&txq->lock)) {
780 1.1 jklos n = reclaim_completed_tx(txq, TX_CLEAN_MAX_DESC, m_vec);
781 1.1 jklos mtx_unlock(&txq->lock);
782 1.1 jklos }
783 1.1 jklos if (n == 0)
784 1.1 jklos return;
785 1.1 jklos
786 1.1 jklos for (i = 0; i < n; i++) {
787 1.1 jklos m_freem_vec(m_vec[i]);
788 1.1 jklos }
789 1.1 jklos if (p && p->ifp->if_drv_flags & IFF_DRV_OACTIVE &&
790 1.1 jklos txq->size - txq->in_use >= TX_START_MAX_DESC) {
791 1.1 jklos txq_fills++;
792 1.1 jklos p->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
793 1.1 jklos workqueue_enqueue(p->start_task.wq, &p->start_task.w, NULL);
794 1.1 jklos }
795 1.1 jklos
796 1.1 jklos if (n)
797 1.1 jklos goto reclaim_more;
798 1.1 jklos }
799 1.1 jklos
800 1.1 jklos static void
801 1.1 jklos sge_txq_reclaim_handler(struct work *wk, void *arg)
802 1.1 jklos {
803 1.1 jklos struct sge_txq *q = arg;
804 1.1 jklos
805 1.1 jklos sge_txq_reclaim_(q);
806 1.1 jklos }
807 1.1 jklos
808 1.1 jklos static void
809 1.1 jklos sge_timer_reclaim(struct work *wk, void *arg)
810 1.1 jklos {
811 1.1 jklos struct port_info *p = arg;
812 1.1 jklos int i, nqsets = p->nqsets;
813 1.1 jklos adapter_t *sc = p->adapter;
814 1.1 jklos struct sge_qset *qs;
815 1.1 jklos struct sge_txq *txq;
816 1.1 jklos struct mtx *lock;
817 1.1 jklos
818 1.1 jklos for (i = 0; i < nqsets; i++) {
819 1.1 jklos qs = &sc->sge.qs[i];
820 1.1 jklos txq = &qs->txq[TXQ_ETH];
821 1.1 jklos sge_txq_reclaim_(txq);
822 1.1 jklos
823 1.1 jklos txq = &qs->txq[TXQ_OFLD];
824 1.1 jklos sge_txq_reclaim_(txq);
825 1.1 jklos
826 1.1 jklos lock = (sc->flags & USING_MSIX) ? &qs->rspq.lock :
827 1.1 jklos &sc->sge.qs[0].rspq.lock;
828 1.1 jklos
829 1.1 jklos if (mtx_trylock(lock)) {
830 1.1 jklos /* XXX currently assume that we are *NOT* polling */
831 1.1 jklos uint32_t status = t3_read_reg(sc, A_SG_RSPQ_FL_STATUS);
832 1.1 jklos
833 1.1 jklos if (qs->fl[0].credits < qs->fl[0].size - 16)
834 1.1 jklos __refill_fl(sc, &qs->fl[0]);
835 1.1 jklos if (qs->fl[1].credits < qs->fl[1].size - 16)
836 1.1 jklos __refill_fl(sc, &qs->fl[1]);
837 1.1 jklos
838 1.1 jklos if (status & (1 << qs->rspq.cntxt_id)) {
839 1.1 jklos if (qs->rspq.credits) {
840 1.1 jklos refill_rspq(sc, &qs->rspq, 1);
841 1.1 jklos qs->rspq.credits--;
842 1.1 jklos t3_write_reg(sc, A_SG_RSPQ_FL_STATUS,
843 1.1 jklos 1 << qs->rspq.cntxt_id);
844 1.1 jklos }
845 1.1 jklos }
846 1.1 jklos mtx_unlock(lock);
847 1.1 jklos }
848 1.1 jklos }
849 1.1 jklos }
850 1.1 jklos
851 1.1 jklos /**
852 1.1 jklos * init_qset_cntxt - initialize an SGE queue set context info
853 1.1 jklos * @qs: the queue set
854 1.1 jklos * @id: the queue set id
855 1.1 jklos *
856 1.1 jklos * Initializes the TIDs and context ids for the queues of a queue set.
857 1.1 jklos */
858 1.1 jklos static void
859 1.1 jklos init_qset_cntxt(struct sge_qset *qs, u_int id)
860 1.1 jklos {
861 1.1 jklos
862 1.1 jklos qs->rspq.cntxt_id = id;
863 1.1 jklos qs->fl[0].cntxt_id = 2 * id;
864 1.1 jklos qs->fl[1].cntxt_id = 2 * id + 1;
865 1.1 jklos qs->txq[TXQ_ETH].cntxt_id = FW_TUNNEL_SGEEC_START + id;
866 1.1 jklos qs->txq[TXQ_ETH].token = FW_TUNNEL_TID_START + id;
867 1.1 jklos qs->txq[TXQ_OFLD].cntxt_id = FW_OFLD_SGEEC_START + id;
868 1.1 jklos qs->txq[TXQ_CTRL].cntxt_id = FW_CTRL_SGEEC_START + id;
869 1.1 jklos qs->txq[TXQ_CTRL].token = FW_CTRL_TID_START + id;
870 1.1 jklos }
871 1.1 jklos
872 1.1 jklos
873 1.1 jklos static void
874 1.1 jklos txq_prod(struct sge_txq *txq, unsigned int ndesc, struct txq_state *txqs)
875 1.1 jklos {
876 1.1 jklos txq->in_use += ndesc;
877 1.1 jklos /*
878 1.1 jklos * XXX we don't handle stopping of queue
879 1.1 jklos * presumably start handles this when we bump against the end
880 1.1 jklos */
881 1.1 jklos txqs->gen = txq->gen;
882 1.1 jklos txq->unacked += ndesc;
883 1.1 jklos txqs->compl = (txq->unacked & 8) << (S_WR_COMPL - 3);
884 1.1 jklos txq->unacked &= 7;
885 1.1 jklos txqs->pidx = txq->pidx;
886 1.1 jklos txq->pidx += ndesc;
887 1.1 jklos
888 1.1 jklos if (txq->pidx >= txq->size) {
889 1.1 jklos txq->pidx -= txq->size;
890 1.1 jklos txq->gen ^= 1;
891 1.1 jklos }
892 1.1 jklos
893 1.1 jklos }
894 1.1 jklos
895 1.1 jklos /**
896 1.1 jklos * calc_tx_descs - calculate the number of Tx descriptors for a packet
897 1.1 jklos * @m: the packet mbufs
898 1.1 jklos * @nsegs: the number of segments
899 1.1 jklos *
900 1.1 jklos * Returns the number of Tx descriptors needed for the given Ethernet
901 1.1 jklos * packet. Ethernet packets require addition of WR and CPL headers.
902 1.1 jklos */
903 1.1 jklos static __inline unsigned int
904 1.1 jklos calc_tx_descs(const struct mbuf *m, int nsegs)
905 1.1 jklos {
906 1.1 jklos unsigned int flits;
907 1.1 jklos
908 1.1 jklos if (m->m_pkthdr.len <= WR_LEN - sizeof(struct cpl_tx_pkt))
909 1.1 jklos return 1;
910 1.1 jklos
911 1.1 jklos flits = sgl_len(nsegs) + 2;
912 1.1 jklos #ifdef TSO_SUPPORTED
913 1.1 jklos if (m->m_pkthdr.csum_flags & (CSUM_TSO))
914 1.1 jklos flits++;
915 1.1 jklos #endif
916 1.1 jklos return flits_to_desc(flits);
917 1.1 jklos }
918 1.1 jklos
919 1.1 jklos static unsigned int
920 1.1 jklos busdma_map_mbufs(struct mbuf **m, struct sge_txq *txq,
921 1.1 jklos struct tx_sw_desc *stx, bus_dma_segment_t *segs, int *nsegs)
922 1.1 jklos {
923 1.1 jklos struct mbuf *m0;
924 1.1 jklos int err, pktlen;
925 1.1 jklos int i, total_len;
926 1.1 jklos
927 1.1 jklos m0 = *m;
928 1.1 jklos pktlen = m0->m_pkthdr.len;
929 1.1 jklos
930 1.1 jklos m0 = *m;
931 1.1 jklos i = 0;
932 1.1 jklos total_len = 0;
933 1.1 jklos while (m0)
934 1.1 jklos {
935 1.1 jklos i++;
936 1.1 jklos total_len += m0->m_len;
937 1.1 jklos m0 = m0->m_next;
938 1.1 jklos }
939 1.1 jklos err = bus_dmamap_create(txq->entry_tag, total_len, TX_MAX_SEGS, total_len, 0, BUS_DMA_NOWAIT, &stx->map);
940 1.1 jklos if (err)
941 1.1 jklos return (err);
942 1.1 jklos err = bus_dmamap_load_mbuf(txq->entry_tag, stx->map, *m, 0);
943 1.1 jklos if (err)
944 1.1 jklos return (err);
945 1.1 jklos // feed out the physical mappings
946 1.1 jklos *nsegs = stx->map->dm_nsegs;
947 1.1 jklos for (i=0; i<*nsegs; i++)
948 1.1 jklos {
949 1.1 jklos segs[i] = stx->map->dm_segs[i];
950 1.1 jklos }
951 1.1 jklos #ifdef DEBUG
952 1.1 jklos if (err) {
953 1.1 jklos int n = 0;
954 1.1 jklos struct mbuf *mtmp = m0;
955 1.1 jklos while(mtmp) {
956 1.1 jklos n++;
957 1.1 jklos mtmp = mtmp->m_next;
958 1.1 jklos }
959 1.1 jklos printf("map_mbufs: bus_dmamap_load_mbuf_sg failed with %d - pkthdr.len==%d nmbufs=%d\n",
960 1.1 jklos err, m0->m_pkthdr.len, n);
961 1.1 jklos }
962 1.1 jklos #endif
963 1.1 jklos if (err == EFBIG) {
964 1.1 jklos /* Too many segments, try to defrag */
965 1.1 jklos m0 = m_defrag(m0, M_DONTWAIT);
966 1.1 jklos if (m0 == NULL) {
967 1.1 jklos m_freem(*m);
968 1.1 jklos *m = NULL;
969 1.1 jklos return (ENOBUFS);
970 1.1 jklos }
971 1.1 jklos *m = m0;
972 1.1 jklos INT3; // XXXXXXXXXXXXXXXXXX like above!
973 1.1 jklos }
974 1.1 jklos
975 1.1 jklos if (err == ENOMEM) {
976 1.1 jklos return (err);
977 1.1 jklos }
978 1.1 jklos
979 1.1 jklos if (err) {
980 1.1 jklos if (cxgb_debug)
981 1.1 jklos printf("map failure err=%d pktlen=%d\n", err, pktlen);
982 1.1 jklos m_freem_vec(m0);
983 1.1 jklos *m = NULL;
984 1.1 jklos return (err);
985 1.1 jklos }
986 1.1 jklos
987 1.1 jklos bus_dmamap_sync(txq->entry_tag, stx->map, 0, pktlen, BUS_DMASYNC_PREWRITE);
988 1.1 jklos stx->flags |= TX_SW_DESC_MAPPED;
989 1.1 jklos
990 1.1 jklos return (0);
991 1.1 jklos }
992 1.1 jklos
993 1.1 jklos /**
994 1.1 jklos * make_sgl - populate a scatter/gather list for a packet
995 1.1 jklos * @sgp: the SGL to populate
996 1.1 jklos * @segs: the packet dma segments
997 1.1 jklos * @nsegs: the number of segments
998 1.1 jklos *
999 1.1 jklos * Generates a scatter/gather list for the buffers that make up a packet
1000 1.1 jklos * and returns the SGL size in 8-byte words. The caller must size the SGL
1001 1.1 jklos * appropriately.
1002 1.1 jklos */
1003 1.1 jklos static __inline void
1004 1.1 jklos make_sgl(struct sg_ent *sgp, bus_dma_segment_t *segs, int nsegs)
1005 1.1 jklos {
1006 1.1 jklos int i, idx;
1007 1.1 jklos
1008 1.1 jklos for (idx = 0, i = 0; i < nsegs; i++, idx ^= 1) {
1009 1.1 jklos if (i && idx == 0)
1010 1.1 jklos ++sgp;
1011 1.1 jklos
1012 1.1 jklos sgp->len[idx] = htobe32(segs[i].ds_len);
1013 1.1 jklos sgp->addr[idx] = htobe64(segs[i].ds_addr);
1014 1.1 jklos }
1015 1.1 jklos
1016 1.1 jklos if (idx)
1017 1.1 jklos sgp->len[idx] = 0;
1018 1.1 jklos }
1019 1.1 jklos
1020 1.1 jklos /**
1021 1.1 jklos * check_ring_tx_db - check and potentially ring a Tx queue's doorbell
1022 1.1 jklos * @adap: the adapter
1023 1.1 jklos * @q: the Tx queue
1024 1.1 jklos *
1025 1.1 jklos * Ring the doorbel if a Tx queue is asleep. There is a natural race,
1026 1.1 jklos * where the HW is going to sleep just after we checked, however,
1027 1.1 jklos * then the interrupt handler will detect the outstanding TX packet
1028 1.1 jklos * and ring the doorbell for us.
1029 1.1 jklos *
1030 1.1 jklos * When GTS is disabled we unconditionally ring the doorbell.
1031 1.1 jklos */
1032 1.1 jklos static __inline void
1033 1.1 jklos check_ring_tx_db(adapter_t *adap, struct sge_txq *q)
1034 1.1 jklos {
1035 1.1 jklos #if USE_GTS
1036 1.1 jklos clear_bit(TXQ_LAST_PKT_DB, &q->flags);
1037 1.1 jklos if (test_and_set_bit(TXQ_RUNNING, &q->flags) == 0) {
1038 1.1 jklos set_bit(TXQ_LAST_PKT_DB, &q->flags);
1039 1.1 jklos #ifdef T3_TRACE
1040 1.1 jklos T3_TRACE1(adap->tb[q->cntxt_id & 7], "doorbell Tx, cntxt %d",
1041 1.1 jklos q->cntxt_id);
1042 1.1 jklos #endif
1043 1.1 jklos t3_write_reg(adap, A_SG_KDOORBELL,
1044 1.1 jklos F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
1045 1.1 jklos }
1046 1.1 jklos #else
1047 1.1 jklos wmb(); /* write descriptors before telling HW */
1048 1.1 jklos t3_write_reg(adap, A_SG_KDOORBELL,
1049 1.1 jklos F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
1050 1.1 jklos #endif
1051 1.1 jklos }
1052 1.1 jklos
1053 1.1 jklos static __inline void
1054 1.1 jklos wr_gen2(struct tx_desc *d, unsigned int gen)
1055 1.1 jklos {
1056 1.1 jklos #if SGE_NUM_GENBITS == 2
1057 1.1 jklos d->flit[TX_DESC_FLITS - 1] = htobe64(gen);
1058 1.1 jklos #endif
1059 1.1 jklos }
1060 1.1 jklos
1061 1.1 jklos
1062 1.1 jklos
1063 1.1 jklos /**
1064 1.1 jklos * write_wr_hdr_sgl - write a WR header and, optionally, SGL
1065 1.1 jklos * @ndesc: number of Tx descriptors spanned by the SGL
1066 1.1 jklos * @txd: first Tx descriptor to be written
1067 1.1 jklos * @txqs: txq state (generation and producer index)
1068 1.1 jklos * @txq: the SGE Tx queue
1069 1.1 jklos * @sgl: the SGL
1070 1.1 jklos * @flits: number of flits to the start of the SGL in the first descriptor
1071 1.1 jklos * @sgl_flits: the SGL size in flits
1072 1.1 jklos * @wr_hi: top 32 bits of WR header based on WR type (big endian)
1073 1.1 jklos * @wr_lo: low 32 bits of WR header based on WR type (big endian)
1074 1.1 jklos *
1075 1.1 jklos * Write a work request header and an associated SGL. If the SGL is
1076 1.1 jklos * small enough to fit into one Tx descriptor it has already been written
1077 1.1 jklos * and we just need to write the WR header. Otherwise we distribute the
1078 1.1 jklos * SGL across the number of descriptors it spans.
1079 1.1 jklos */
1080 1.1 jklos
1081 1.1 jklos static void
1082 1.1 jklos write_wr_hdr_sgl(unsigned int ndesc, struct tx_desc *txd, struct txq_state *txqs,
1083 1.1 jklos const struct sge_txq *txq, const struct sg_ent *sgl, unsigned int flits,
1084 1.1 jklos unsigned int sgl_flits, unsigned int wr_hi, unsigned int wr_lo)
1085 1.1 jklos {
1086 1.1 jklos
1087 1.1 jklos struct work_request_hdr *wrp = (struct work_request_hdr *)txd;
1088 1.1 jklos struct tx_sw_desc *txsd = &txq->sdesc[txqs->pidx];
1089 1.1 jklos
1090 1.1 jklos if (__predict_true(ndesc == 1)) {
1091 1.1 jklos wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) |
1092 1.1 jklos V_WR_SGLSFLT(flits)) | wr_hi;
1093 1.1 jklos wmb();
1094 1.1 jklos wrp->wr_lo = htonl(V_WR_LEN(flits + sgl_flits) |
1095 1.1 jklos V_WR_GEN(txqs->gen)) | wr_lo;
1096 1.1 jklos /* XXX gen? */
1097 1.1 jklos wr_gen2(txd, txqs->gen);
1098 1.1 jklos } else {
1099 1.1 jklos unsigned int ogen = txqs->gen;
1100 1.1 jklos const uint64_t *fp = (const uint64_t *)sgl;
1101 1.1 jklos struct work_request_hdr *wp = wrp;
1102 1.1 jklos
1103 1.1 jklos wrp->wr_hi = htonl(F_WR_SOP | V_WR_DATATYPE(1) |
1104 1.1 jklos V_WR_SGLSFLT(flits)) | wr_hi;
1105 1.1 jklos
1106 1.1 jklos while (sgl_flits) {
1107 1.1 jklos unsigned int avail = WR_FLITS - flits;
1108 1.1 jklos
1109 1.1 jklos if (avail > sgl_flits)
1110 1.1 jklos avail = sgl_flits;
1111 1.1 jklos memcpy(&txd->flit[flits], fp, avail * sizeof(*fp));
1112 1.1 jklos sgl_flits -= avail;
1113 1.1 jklos ndesc--;
1114 1.1 jklos if (!sgl_flits)
1115 1.1 jklos break;
1116 1.1 jklos
1117 1.1 jklos fp += avail;
1118 1.1 jklos txd++;
1119 1.1 jklos txsd++;
1120 1.1 jklos if (++txqs->pidx == txq->size) {
1121 1.1 jklos txqs->pidx = 0;
1122 1.1 jklos txqs->gen ^= 1;
1123 1.1 jklos txd = txq->desc;
1124 1.1 jklos txsd = txq->sdesc;
1125 1.1 jklos }
1126 1.1 jklos
1127 1.1 jklos /*
1128 1.1 jklos * when the head of the mbuf chain
1129 1.1 jklos * is freed all clusters will be freed
1130 1.1 jklos * with it
1131 1.1 jklos */
1132 1.1 jklos txsd->m = NULL;
1133 1.1 jklos wrp = (struct work_request_hdr *)txd;
1134 1.1 jklos wrp->wr_hi = htonl(V_WR_DATATYPE(1) |
1135 1.1 jklos V_WR_SGLSFLT(1)) | wr_hi;
1136 1.1 jklos wrp->wr_lo = htonl(V_WR_LEN(min(WR_FLITS,
1137 1.1 jklos sgl_flits + 1)) |
1138 1.1 jklos V_WR_GEN(txqs->gen)) | wr_lo;
1139 1.1 jklos wr_gen2(txd, txqs->gen);
1140 1.1 jklos flits = 1;
1141 1.1 jklos }
1142 1.1 jklos wrp->wr_hi |= htonl(F_WR_EOP);
1143 1.1 jklos wmb();
1144 1.1 jklos wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo;
1145 1.1 jklos wr_gen2((struct tx_desc *)wp, ogen);
1146 1.1 jklos }
1147 1.1 jklos }
1148 1.1 jklos
1149 1.1 jklos
1150 1.1 jklos /* sizeof(*eh) + sizeof(*vhdr) + sizeof(*ip) + sizeof(*tcp) */
1151 1.1 jklos #define TCPPKTHDRSIZE (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + 20 + 20)
1152 1.1 jklos
1153 1.1 jklos int
1154 1.1 jklos t3_encap(struct port_info *p, struct mbuf **m, int *free_it)
1155 1.1 jklos {
1156 1.1 jklos adapter_t *sc;
1157 1.1 jklos struct mbuf *m0;
1158 1.1 jklos struct sge_qset *qs;
1159 1.1 jklos struct sge_txq *txq;
1160 1.1 jklos struct tx_sw_desc *stx;
1161 1.1 jklos struct txq_state txqs;
1162 1.1 jklos unsigned int ndesc, flits, cntrl, mlen;
1163 1.1 jklos int err, nsegs, tso_info = 0;
1164 1.1 jklos
1165 1.1 jklos struct work_request_hdr *wrp;
1166 1.1 jklos struct tx_sw_desc *txsd;
1167 1.1 jklos struct sg_ent *sgp, sgl[TX_MAX_SEGS / 2 + 1];
1168 1.1 jklos bus_dma_segment_t segs[TX_MAX_SEGS];
1169 1.1 jklos uint32_t wr_hi, wr_lo, sgl_flits;
1170 1.1 jklos
1171 1.1 jklos struct tx_desc *txd;
1172 1.1 jklos struct cpl_tx_pkt *cpl;
1173 1.1 jklos
1174 1.1 jklos m0 = *m;
1175 1.1 jklos sc = p->adapter;
1176 1.1 jklos
1177 1.1 jklos DPRINTF("t3_encap port_id=%d qsidx=%d ", p->port_id, p->first_qset);
1178 1.1 jklos
1179 1.1 jklos /* port_id=1 qsid=1 txpkt_intf=2 tx_chan=0 */
1180 1.1 jklos
1181 1.1 jklos qs = &sc->sge.qs[p->first_qset];
1182 1.1 jklos
1183 1.1 jklos txq = &qs->txq[TXQ_ETH];
1184 1.1 jklos stx = &txq->sdesc[txq->pidx];
1185 1.1 jklos txd = &txq->desc[txq->pidx];
1186 1.1 jklos cpl = (struct cpl_tx_pkt *)txd;
1187 1.1 jklos mlen = m0->m_pkthdr.len;
1188 1.1 jklos cpl->len = htonl(mlen | 0x80000000);
1189 1.1 jklos
1190 1.1 jklos DPRINTF("mlen=%d txpkt_intf=%d tx_chan=%d\n", mlen, p->txpkt_intf, p->tx_chan);
1191 1.1 jklos /*
1192 1.1 jklos * XXX handle checksum, TSO, and VLAN here
1193 1.1 jklos *
1194 1.1 jklos */
1195 1.1 jklos cntrl = V_TXPKT_INTF(p->txpkt_intf);
1196 1.1 jklos
1197 1.1 jklos /*
1198 1.1 jklos * XXX need to add VLAN support for 6.x
1199 1.1 jklos */
1200 1.1 jklos #ifdef VLAN_SUPPORTED
1201 1.1 jklos if (m0->m_flags & M_VLANTAG)
1202 1.1 jklos cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(m0->m_pkthdr.ether_vtag);
1203 1.1 jklos if (m0->m_pkthdr.csum_flags & (CSUM_TSO))
1204 1.1 jklos tso_info = V_LSO_MSS(m0->m_pkthdr.tso_segsz);
1205 1.1 jklos #endif
1206 1.1 jklos if (tso_info) {
1207 1.1 jklos int eth_type;
1208 1.1 jklos struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *) cpl;
1209 1.1 jklos struct ip *ip;
1210 1.1 jklos struct tcphdr *tcp;
1211 1.1 jklos char *pkthdr, tmp[TCPPKTHDRSIZE]; /* is this too large for the stack? */
1212 1.1 jklos
1213 1.1 jklos txd->flit[2] = 0;
1214 1.1 jklos cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT_LSO);
1215 1.1 jklos hdr->cntrl = htonl(cntrl);
1216 1.1 jklos
1217 1.1 jklos if (__predict_false(m0->m_len < TCPPKTHDRSIZE)) {
1218 1.1 jklos pkthdr = &tmp[0];
1219 1.1 jklos m_copydata(m0, 0, TCPPKTHDRSIZE, pkthdr);
1220 1.1 jklos } else {
1221 1.1 jklos pkthdr = mtod(m0, char *);
1222 1.1 jklos }
1223 1.1 jklos
1224 1.1 jklos #ifdef VLAN_SUPPORTED
1225 1.1 jklos if (__predict_false(m0->m_flags & M_VLANTAG)) {
1226 1.1 jklos eth_type = CPL_ETH_II_VLAN;
1227 1.1 jklos ip = (struct ip *)(pkthdr + ETHER_HDR_LEN +
1228 1.1 jklos ETHER_VLAN_ENCAP_LEN);
1229 1.1 jklos } else {
1230 1.1 jklos eth_type = CPL_ETH_II;
1231 1.1 jklos ip = (struct ip *)(pkthdr + ETHER_HDR_LEN);
1232 1.1 jklos }
1233 1.1 jklos #else
1234 1.1 jklos eth_type = CPL_ETH_II;
1235 1.1 jklos ip = (struct ip *)(pkthdr + ETHER_HDR_LEN);
1236 1.1 jklos #endif
1237 1.1 jklos tcp = (struct tcphdr *)((uint8_t *)ip +
1238 1.1 jklos sizeof(*ip));
1239 1.1 jklos
1240 1.1 jklos tso_info |= V_LSO_ETH_TYPE(eth_type) |
1241 1.1 jklos V_LSO_IPHDR_WORDS(ip->ip_hl) |
1242 1.1 jklos V_LSO_TCPHDR_WORDS(tcp->th_off);
1243 1.1 jklos hdr->lso_info = htonl(tso_info);
1244 1.1 jklos flits = 3;
1245 1.1 jklos } else {
1246 1.1 jklos cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT);
1247 1.1 jklos cpl->cntrl = htonl(cntrl);
1248 1.1 jklos
1249 1.1 jklos if (mlen <= WR_LEN - sizeof(*cpl)) {
1250 1.1 jklos txq_prod(txq, 1, &txqs);
1251 1.1 jklos txq->sdesc[txqs.pidx].m = NULL;
1252 1.1 jklos
1253 1.1 jklos if (m0->m_len == m0->m_pkthdr.len)
1254 1.1 jklos memcpy(&txd->flit[2], mtod(m0, uint8_t *), mlen);
1255 1.1 jklos else
1256 1.1 jklos m_copydata(m0, 0, mlen, (void *)&txd->flit[2]);
1257 1.1 jklos
1258 1.1 jklos *free_it = 1;
1259 1.1 jklos flits = (mlen + 7) / 8 + 2;
1260 1.1 jklos cpl->wr.wr_hi = htonl(V_WR_BCNTLFLT(mlen & 7) |
1261 1.1 jklos V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) |
1262 1.1 jklos F_WR_SOP | F_WR_EOP | txqs.compl);
1263 1.1 jklos wmb();
1264 1.1 jklos cpl->wr.wr_lo = htonl(V_WR_LEN(flits) |
1265 1.1 jklos V_WR_GEN(txqs.gen) | V_WR_TID(txq->token));
1266 1.1 jklos
1267 1.1 jklos wr_gen2(txd, txqs.gen);
1268 1.1 jklos check_ring_tx_db(sc, txq);
1269 1.1 jklos return (0);
1270 1.1 jklos }
1271 1.1 jklos flits = 2;
1272 1.1 jklos }
1273 1.1 jklos
1274 1.1 jklos wrp = (struct work_request_hdr *)txd;
1275 1.1 jklos
1276 1.1 jklos if ((err = busdma_map_mbufs(m, txq, stx, segs, &nsegs)) != 0) {
1277 1.1 jklos return (err);
1278 1.1 jklos }
1279 1.1 jklos m0 = *m;
1280 1.1 jklos ndesc = calc_tx_descs(m0, nsegs);
1281 1.1 jklos
1282 1.1 jklos sgp = (ndesc == 1) ? (struct sg_ent *)&txd->flit[flits] : sgl;
1283 1.1 jklos make_sgl(sgp, segs, nsegs);
1284 1.1 jklos
1285 1.1 jklos sgl_flits = sgl_len(nsegs);
1286 1.1 jklos
1287 1.1 jklos DPRINTF("make_sgl success nsegs==%d ndesc==%d\n", nsegs, ndesc);
1288 1.1 jklos txq_prod(txq, ndesc, &txqs);
1289 1.1 jklos txsd = &txq->sdesc[txqs.pidx];
1290 1.1 jklos wr_hi = htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | txqs.compl);
1291 1.1 jklos wr_lo = htonl(V_WR_TID(txq->token));
1292 1.1 jklos txsd->m = m0;
1293 1.1 jklos m_set_priority(m0, txqs.pidx);
1294 1.1 jklos
1295 1.1 jklos write_wr_hdr_sgl(ndesc, txd, &txqs, txq, sgl, flits, sgl_flits, wr_hi, wr_lo);
1296 1.1 jklos check_ring_tx_db(p->adapter, txq);
1297 1.1 jklos
1298 1.1 jklos return (0);
1299 1.1 jklos }
1300 1.1 jklos
1301 1.1 jklos
1302 1.1 jklos /**
1303 1.1 jklos * write_imm - write a packet into a Tx descriptor as immediate data
1304 1.1 jklos * @d: the Tx descriptor to write
1305 1.1 jklos * @m: the packet
1306 1.1 jklos * @len: the length of packet data to write as immediate data
1307 1.1 jklos * @gen: the generation bit value to write
1308 1.1 jklos *
1309 1.1 jklos * Writes a packet as immediate data into a Tx descriptor. The packet
1310 1.1 jklos * contains a work request at its beginning. We must write the packet
1311 1.1 jklos * carefully so the SGE doesn't read accidentally before it's written in
1312 1.1 jklos * its entirety.
1313 1.1 jklos */
1314 1.1 jklos static __inline void
1315 1.1 jklos write_imm(struct tx_desc *d, struct mbuf *m,
1316 1.1 jklos unsigned int len, unsigned int gen)
1317 1.1 jklos {
1318 1.1 jklos struct work_request_hdr *from = mtod(m, struct work_request_hdr *);
1319 1.1 jklos struct work_request_hdr *to = (struct work_request_hdr *)d;
1320 1.1 jklos
1321 1.1 jklos memcpy(&to[1], &from[1], len - sizeof(*from));
1322 1.1 jklos to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP |
1323 1.1 jklos V_WR_BCNTLFLT(len & 7));
1324 1.1 jklos wmb();
1325 1.1 jklos to->wr_lo = from->wr_lo | htonl(V_WR_GEN(gen) |
1326 1.1 jklos V_WR_LEN((len + 7) / 8));
1327 1.1 jklos wr_gen2(d, gen);
1328 1.1 jklos m_freem(m);
1329 1.1 jklos }
1330 1.1 jklos
1331 1.1 jklos /**
1332 1.1 jklos * check_desc_avail - check descriptor availability on a send queue
1333 1.1 jklos * @adap: the adapter
1334 1.1 jklos * @q: the TX queue
1335 1.1 jklos * @m: the packet needing the descriptors
1336 1.1 jklos * @ndesc: the number of Tx descriptors needed
1337 1.1 jklos * @qid: the Tx queue number in its queue set (TXQ_OFLD or TXQ_CTRL)
1338 1.1 jklos *
1339 1.1 jklos * Checks if the requested number of Tx descriptors is available on an
1340 1.1 jklos * SGE send queue. If the queue is already suspended or not enough
1341 1.1 jklos * descriptors are available the packet is queued for later transmission.
1342 1.1 jklos * Must be called with the Tx queue locked.
1343 1.1 jklos *
1344 1.1 jklos * Returns 0 if enough descriptors are available, 1 if there aren't
1345 1.1 jklos * enough descriptors and the packet has been queued, and 2 if the caller
1346 1.1 jklos * needs to retry because there weren't enough descriptors at the
1347 1.1 jklos * beginning of the call but some freed up in the mean time.
1348 1.1 jklos */
1349 1.1 jklos static __inline int
1350 1.1 jklos check_desc_avail(adapter_t *adap, struct sge_txq *q,
1351 1.1 jklos struct mbuf *m, unsigned int ndesc,
1352 1.1 jklos unsigned int qid)
1353 1.1 jklos {
1354 1.1 jklos /*
1355 1.1 jklos * XXX We currently only use this for checking the control queue
1356 1.1 jklos * the control queue is only used for binding qsets which happens
1357 1.1 jklos * at init time so we are guaranteed enough descriptors
1358 1.1 jklos */
1359 1.1 jklos if (__predict_false(!mbufq_empty(&q->sendq))) {
1360 1.1 jklos addq_exit: mbufq_tail(&q->sendq, m);
1361 1.1 jklos return 1;
1362 1.1 jklos }
1363 1.1 jklos if (__predict_false(q->size - q->in_use < ndesc)) {
1364 1.1 jklos
1365 1.1 jklos struct sge_qset *qs = txq_to_qset(q, qid);
1366 1.1 jklos
1367 1.1 jklos setbit(&qs->txq_stopped, qid);
1368 1.1 jklos smp_mb();
1369 1.1 jklos
1370 1.1 jklos if (should_restart_tx(q) &&
1371 1.1 jklos test_and_clear_bit(qid, &qs->txq_stopped))
1372 1.1 jklos return 2;
1373 1.1 jklos
1374 1.1 jklos q->stops++;
1375 1.1 jklos goto addq_exit;
1376 1.1 jklos }
1377 1.1 jklos return 0;
1378 1.1 jklos }
1379 1.1 jklos
1380 1.1 jklos
1381 1.1 jklos /**
1382 1.1 jklos * reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
1383 1.1 jklos * @q: the SGE control Tx queue
1384 1.1 jklos *
1385 1.1 jklos * This is a variant of reclaim_completed_tx() that is used for Tx queues
1386 1.1 jklos * that send only immediate data (presently just the control queues) and
1387 1.1 jklos * thus do not have any mbufs
1388 1.1 jklos */
1389 1.1 jklos static __inline void
1390 1.1 jklos reclaim_completed_tx_imm(struct sge_txq *q)
1391 1.1 jklos {
1392 1.1 jklos unsigned int reclaim = q->processed - q->cleaned;
1393 1.1 jklos
1394 1.1 jklos mtx_assert(&q->lock, MA_OWNED);
1395 1.1 jklos
1396 1.1 jklos q->in_use -= reclaim;
1397 1.1 jklos q->cleaned += reclaim;
1398 1.1 jklos }
1399 1.1 jklos
1400 1.1 jklos static __inline int
1401 1.1 jklos immediate(const struct mbuf *m)
1402 1.1 jklos {
1403 1.1 jklos return m->m_len <= WR_LEN && m->m_pkthdr.len <= WR_LEN ;
1404 1.1 jklos }
1405 1.1 jklos
1406 1.1 jklos /**
1407 1.1 jklos * ctrl_xmit - send a packet through an SGE control Tx queue
1408 1.1 jklos * @adap: the adapter
1409 1.1 jklos * @q: the control queue
1410 1.1 jklos * @m: the packet
1411 1.1 jklos *
1412 1.1 jklos * Send a packet through an SGE control Tx queue. Packets sent through
1413 1.1 jklos * a control queue must fit entirely as immediate data in a single Tx
1414 1.1 jklos * descriptor and have no page fragments.
1415 1.1 jklos */
1416 1.1 jklos static int
1417 1.1 jklos ctrl_xmit(adapter_t *adap, struct sge_txq *q, struct mbuf *m)
1418 1.1 jklos {
1419 1.1 jklos int ret;
1420 1.1 jklos struct work_request_hdr *wrp = mtod(m, struct work_request_hdr *);
1421 1.1 jklos
1422 1.1 jklos if (__predict_false(!immediate(m))) {
1423 1.1 jklos m_freem(m);
1424 1.1 jklos return 0;
1425 1.1 jklos }
1426 1.1 jklos
1427 1.1 jklos wrp->wr_hi |= htonl(F_WR_SOP | F_WR_EOP);
1428 1.1 jklos wrp->wr_lo = htonl(V_WR_TID(q->token));
1429 1.1 jklos
1430 1.1 jklos mtx_lock(&q->lock);
1431 1.1 jklos again: reclaim_completed_tx_imm(q);
1432 1.1 jklos
1433 1.1 jklos ret = check_desc_avail(adap, q, m, 1, TXQ_CTRL);
1434 1.1 jklos if (__predict_false(ret)) {
1435 1.1 jklos if (ret == 1) {
1436 1.1 jklos mtx_unlock(&q->lock);
1437 1.1 jklos return (-1);
1438 1.1 jklos }
1439 1.1 jklos goto again;
1440 1.1 jklos }
1441 1.1 jklos
1442 1.1 jklos write_imm(&q->desc[q->pidx], m, m->m_len, q->gen);
1443 1.1 jklos
1444 1.1 jklos q->in_use++;
1445 1.1 jklos if (++q->pidx >= q->size) {
1446 1.1 jklos q->pidx = 0;
1447 1.1 jklos q->gen ^= 1;
1448 1.1 jklos }
1449 1.1 jklos mtx_unlock(&q->lock);
1450 1.1 jklos wmb();
1451 1.1 jklos t3_write_reg(adap, A_SG_KDOORBELL,
1452 1.1 jklos F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
1453 1.1 jklos return (0);
1454 1.1 jklos }
1455 1.1 jklos
1456 1.1 jklos
1457 1.1 jklos /**
1458 1.1 jklos * restart_ctrlq - restart a suspended control queue
1459 1.1 jklos * @qs: the queue set cotaining the control queue
1460 1.1 jklos *
1461 1.1 jklos * Resumes transmission on a suspended Tx control queue.
1462 1.1 jklos */
1463 1.1 jklos static void
1464 1.1 jklos restart_ctrlq(struct work *wk, void *data)
1465 1.1 jklos {
1466 1.1 jklos struct mbuf *m;
1467 1.1 jklos struct sge_qset *qs = (struct sge_qset *)data;
1468 1.1 jklos struct sge_txq *q = &qs->txq[TXQ_CTRL];
1469 1.1 jklos adapter_t *adap = qs->port->adapter;
1470 1.1 jklos
1471 1.1 jklos mtx_lock(&q->lock);
1472 1.1 jklos again: reclaim_completed_tx_imm(q);
1473 1.1 jklos
1474 1.1 jklos while (q->in_use < q->size &&
1475 1.1 jklos (m = mbufq_dequeue(&q->sendq)) != NULL) {
1476 1.1 jklos
1477 1.1 jklos write_imm(&q->desc[q->pidx], m, m->m_len, q->gen);
1478 1.1 jklos
1479 1.1 jklos if (++q->pidx >= q->size) {
1480 1.1 jklos q->pidx = 0;
1481 1.1 jklos q->gen ^= 1;
1482 1.1 jklos }
1483 1.1 jklos q->in_use++;
1484 1.1 jklos }
1485 1.1 jklos if (!mbufq_empty(&q->sendq)) {
1486 1.1 jklos setbit(&qs->txq_stopped, TXQ_CTRL);
1487 1.1 jklos smp_mb();
1488 1.1 jklos
1489 1.1 jklos if (should_restart_tx(q) &&
1490 1.1 jklos test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped))
1491 1.1 jklos goto again;
1492 1.1 jklos q->stops++;
1493 1.1 jklos }
1494 1.1 jklos mtx_unlock(&q->lock);
1495 1.1 jklos t3_write_reg(adap, A_SG_KDOORBELL,
1496 1.1 jklos F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
1497 1.1 jklos }
1498 1.1 jklos
1499 1.1 jklos
1500 1.1 jklos /*
1501 1.1 jklos * Send a management message through control queue 0
1502 1.1 jklos */
1503 1.1 jklos int
1504 1.1 jklos t3_mgmt_tx(struct adapter *adap, struct mbuf *m)
1505 1.1 jklos {
1506 1.1 jklos return ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], m);
1507 1.1 jklos }
1508 1.1 jklos
1509 1.1 jklos /**
1510 1.1 jklos * free_qset - free the resources of an SGE queue set
1511 1.1 jklos * @sc: the controller owning the queue set
1512 1.1 jklos * @q: the queue set
1513 1.1 jklos *
1514 1.1 jklos * Release the HW and SW resources associated with an SGE queue set, such
1515 1.1 jklos * as HW contexts, packet buffers, and descriptor rings. Traffic to the
1516 1.1 jklos * queue set must be quiesced prior to calling this.
1517 1.1 jklos */
1518 1.1 jklos static void
1519 1.1 jklos t3_free_qset(adapter_t *sc, struct sge_qset *q)
1520 1.1 jklos {
1521 1.1 jklos int i;
1522 1.1 jklos
1523 1.1 jklos for (i = 0; i < SGE_RXQ_PER_SET; ++i) {
1524 1.1 jklos if (q->fl[i].desc) {
1525 1.1 jklos mtx_lock(&sc->sge.reg_lock);
1526 1.1 jklos t3_sge_disable_fl(sc, q->fl[i].cntxt_id);
1527 1.1 jklos mtx_unlock(&sc->sge.reg_lock);
1528 1.1 jklos bus_dmamap_unload(q->fl[i].desc_tag, q->fl[i].desc_map);
1529 1.1 jklos INT3;
1530 1.1 jklos // bus_dmamem_free(q->fl[i].desc_tag, &q->fl[i].phys_addr, 1);
1531 1.1 jklos // XXXXXXXXXXX destroy DMA tags????
1532 1.1 jklos }
1533 1.1 jklos if (q->fl[i].sdesc) {
1534 1.1 jklos free_rx_bufs(sc, &q->fl[i]);
1535 1.1 jklos free(q->fl[i].sdesc, M_DEVBUF);
1536 1.1 jklos }
1537 1.1 jklos }
1538 1.1 jklos
1539 1.1 jklos for (i = 0; i < SGE_TXQ_PER_SET; i++) {
1540 1.1 jklos if (q->txq[i].desc) {
1541 1.1 jklos mtx_lock(&sc->sge.reg_lock);
1542 1.1 jklos t3_sge_enable_ecntxt(sc, q->txq[i].cntxt_id, 0);
1543 1.1 jklos mtx_unlock(&sc->sge.reg_lock);
1544 1.1 jklos bus_dmamap_unload(q->txq[i].desc_tag,
1545 1.1 jklos q->txq[i].desc_map);
1546 1.1 jklos INT3;
1547 1.1 jklos // bus_dmamem_free(q->txq[i].desc_tag, &q->txq[i].phys_addr, 1);
1548 1.1 jklos // XXXXXXXXXXX destroy DMA tags???? And the lock?!??!
1549 1.1 jklos
1550 1.1 jklos }
1551 1.1 jklos if (q->txq[i].sdesc) {
1552 1.1 jklos free(q->txq[i].sdesc, M_DEVBUF);
1553 1.1 jklos }
1554 1.1 jklos }
1555 1.1 jklos
1556 1.1 jklos if (q->rspq.desc) {
1557 1.1 jklos mtx_lock(&sc->sge.reg_lock);
1558 1.1 jklos t3_sge_disable_rspcntxt(sc, q->rspq.cntxt_id);
1559 1.1 jklos mtx_unlock(&sc->sge.reg_lock);
1560 1.1 jklos
1561 1.1 jklos bus_dmamap_unload(q->rspq.desc_tag, q->rspq.desc_map);
1562 1.1 jklos INT3;
1563 1.1 jklos // bus_dmamem_free(q->rspq.desc_tag, &q->rspq.phys_addr, 1);
1564 1.1 jklos // XXXXXXXXXXX destroy DMA tags???? and the LOCK ?!?!?
1565 1.1 jklos }
1566 1.1 jklos
1567 1.1 jklos memset(q, 0, sizeof(*q));
1568 1.1 jklos }
1569 1.1 jklos
1570 1.1 jklos /**
1571 1.1 jklos * t3_free_sge_resources - free SGE resources
1572 1.1 jklos * @sc: the adapter softc
1573 1.1 jklos *
1574 1.1 jklos * Frees resources used by the SGE queue sets.
1575 1.1 jklos */
1576 1.1 jklos void
1577 1.1 jklos t3_free_sge_resources(adapter_t *sc)
1578 1.1 jklos {
1579 1.1 jklos int i, nqsets;
1580 1.1 jklos
1581 1.1 jklos for (nqsets = i = 0; i < (sc)->params.nports; i++)
1582 1.1 jklos nqsets += sc->port[i].nqsets;
1583 1.1 jklos
1584 1.1 jklos for (i = 0; i < nqsets; ++i)
1585 1.1 jklos t3_free_qset(sc, &sc->sge.qs[i]);
1586 1.1 jklos }
1587 1.1 jklos
1588 1.1 jklos /**
1589 1.1 jklos * t3_sge_start - enable SGE
1590 1.1 jklos * @sc: the controller softc
1591 1.1 jklos *
1592 1.1 jklos * Enables the SGE for DMAs. This is the last step in starting packet
1593 1.1 jklos * transfers.
1594 1.1 jklos */
1595 1.1 jklos void
1596 1.1 jklos t3_sge_start(adapter_t *sc)
1597 1.1 jklos {
1598 1.1 jklos t3_set_reg_field(sc, A_SG_CONTROL, F_GLOBALENABLE, F_GLOBALENABLE);
1599 1.1 jklos }
1600 1.1 jklos
1601 1.1 jklos /**
1602 1.1 jklos * t3_sge_stop - disable SGE operation
1603 1.1 jklos * @sc: the adapter
1604 1.1 jklos *
1605 1.1 jklos * Disables the DMA engine. This can be called in emeregencies (e.g.,
1606 1.1 jklos * from error interrupts) or from normal process context. In the latter
1607 1.1 jklos * case it also disables any pending queue restart tasklets. Note that
1608 1.1 jklos * if it is called in interrupt context it cannot disable the restart
1609 1.1 jklos * tasklets as it cannot wait, however the tasklets will have no effect
1610 1.1 jklos * since the doorbells are disabled and the driver will call this again
1611 1.1 jklos * later from process context, at which time the tasklets will be stopped
1612 1.1 jklos * if they are still running.
1613 1.1 jklos */
1614 1.1 jklos void
1615 1.1 jklos t3_sge_stop(adapter_t *sc)
1616 1.1 jklos {
1617 1.1 jklos int i, nqsets;
1618 1.1 jklos
1619 1.1 jklos t3_set_reg_field(sc, A_SG_CONTROL, F_GLOBALENABLE, 0);
1620 1.1 jklos
1621 1.1 jklos for (nqsets = i = 0; i < (sc)->params.nports; i++)
1622 1.1 jklos nqsets += sc->port[i].nqsets;
1623 1.1 jklos
1624 1.1 jklos for (i = 0; i < nqsets; ++i) {
1625 1.1 jklos }
1626 1.1 jklos }
1627 1.1 jklos
1628 1.1 jklos
1629 1.1 jklos /**
1630 1.1 jklos * free_tx_desc - reclaims Tx descriptors and their buffers
1631 1.1 jklos * @adapter: the adapter
1632 1.1 jklos * @q: the Tx queue to reclaim descriptors from
1633 1.1 jklos * @n: the number of descriptors to reclaim
1634 1.1 jklos *
1635 1.1 jklos * Reclaims Tx descriptors from an SGE Tx queue and frees the associated
1636 1.1 jklos * Tx buffers. Called with the Tx queue lock held.
1637 1.1 jklos */
1638 1.1 jklos int
1639 1.1 jklos free_tx_desc(struct sge_txq *q, int n, struct mbuf **m_vec)
1640 1.1 jklos {
1641 1.1 jklos struct tx_sw_desc *d;
1642 1.1 jklos unsigned int cidx = q->cidx;
1643 1.1 jklos int nbufs = 0;
1644 1.1 jklos
1645 1.1 jklos #ifdef T3_TRACE
1646 1.1 jklos T3_TRACE2(sc->tb[q->cntxt_id & 7],
1647 1.1 jklos "reclaiming %u Tx descriptors at cidx %u", n, cidx);
1648 1.1 jklos #endif
1649 1.1 jklos d = &q->sdesc[cidx];
1650 1.1 jklos
1651 1.1 jklos while (n-- > 0) {
1652 1.1 jklos DPRINTF("cidx=%d d=%p\n", cidx, d);
1653 1.1 jklos if (d->m) {
1654 1.1 jklos if (d->flags & TX_SW_DESC_MAPPED) {
1655 1.1 jklos bus_dmamap_unload(q->entry_tag, d->map);
1656 1.1 jklos bus_dmamap_destroy(q->entry_tag, d->map);
1657 1.1 jklos d->flags &= ~TX_SW_DESC_MAPPED;
1658 1.1 jklos }
1659 1.1 jklos if (m_get_priority(d->m) == cidx) {
1660 1.1 jklos m_vec[nbufs] = d->m;
1661 1.1 jklos d->m = NULL;
1662 1.1 jklos nbufs++;
1663 1.1 jklos } else {
1664 1.1 jklos printf("pri=%d cidx=%d\n", (int)m_get_priority(d->m), cidx);
1665 1.1 jklos }
1666 1.1 jklos }
1667 1.1 jklos ++d;
1668 1.1 jklos if (++cidx == q->size) {
1669 1.1 jklos cidx = 0;
1670 1.1 jklos d = q->sdesc;
1671 1.1 jklos }
1672 1.1 jklos }
1673 1.1 jklos q->cidx = cidx;
1674 1.1 jklos
1675 1.1 jklos return (nbufs);
1676 1.1 jklos }
1677 1.1 jklos
1678 1.1 jklos /**
1679 1.1 jklos * is_new_response - check if a response is newly written
1680 1.1 jklos * @r: the response descriptor
1681 1.1 jklos * @q: the response queue
1682 1.1 jklos *
1683 1.1 jklos * Returns true if a response descriptor contains a yet unprocessed
1684 1.1 jklos * response.
1685 1.1 jklos */
1686 1.1 jklos static __inline int
1687 1.1 jklos is_new_response(const struct rsp_desc *r,
1688 1.1 jklos const struct sge_rspq *q)
1689 1.1 jklos {
1690 1.1 jklos return (r->intr_gen & F_RSPD_GEN2) == q->gen;
1691 1.1 jklos }
1692 1.1 jklos
1693 1.1 jklos #define RSPD_GTS_MASK (F_RSPD_TXQ0_GTS | F_RSPD_TXQ1_GTS)
1694 1.1 jklos #define RSPD_CTRL_MASK (RSPD_GTS_MASK | \
1695 1.1 jklos V_RSPD_TXQ0_CR(M_RSPD_TXQ0_CR) | \
1696 1.1 jklos V_RSPD_TXQ1_CR(M_RSPD_TXQ1_CR) | \
1697 1.1 jklos V_RSPD_TXQ2_CR(M_RSPD_TXQ2_CR))
1698 1.1 jklos
1699 1.1 jklos /* How long to delay the next interrupt in case of memory shortage, in 0.1us. */
1700 1.1 jklos #define NOMEM_INTR_DELAY 2500
1701 1.1 jklos
1702 1.1 jklos /**
1703 1.1 jklos * write_ofld_wr - write an offload work request
1704 1.1 jklos * @adap: the adapter
1705 1.1 jklos * @m: the packet to send
1706 1.1 jklos * @q: the Tx queue
1707 1.1 jklos * @pidx: index of the first Tx descriptor to write
1708 1.1 jklos * @gen: the generation value to use
1709 1.1 jklos * @ndesc: number of descriptors the packet will occupy
1710 1.1 jklos *
1711 1.1 jklos * Write an offload work request to send the supplied packet. The packet
1712 1.1 jklos * data already carry the work request with most fields populated.
1713 1.1 jklos */
1714 1.1 jklos static void
1715 1.1 jklos write_ofld_wr(adapter_t *adap, struct mbuf *m,
1716 1.1 jklos struct sge_txq *q, unsigned int pidx,
1717 1.1 jklos unsigned int gen, unsigned int ndesc,
1718 1.1 jklos bus_dma_segment_t *segs, unsigned int nsegs)
1719 1.1 jklos {
1720 1.1 jklos unsigned int sgl_flits, flits;
1721 1.1 jklos struct work_request_hdr *from;
1722 1.1 jklos struct sg_ent *sgp, sgl[TX_MAX_SEGS / 2 + 1];
1723 1.1 jklos struct tx_desc *d = &q->desc[pidx];
1724 1.1 jklos struct txq_state txqs;
1725 1.1 jklos
1726 1.1 jklos if (immediate(m)) {
1727 1.1 jklos q->sdesc[pidx].m = NULL;
1728 1.1 jklos write_imm(d, m, m->m_len, gen);
1729 1.1 jklos return;
1730 1.1 jklos }
1731 1.1 jklos
1732 1.1 jklos /* Only TX_DATA builds SGLs */
1733 1.1 jklos
1734 1.1 jklos from = mtod(m, struct work_request_hdr *);
1735 1.1 jklos INT3; /// DEBUG this???
1736 1.1 jklos flits = 3; // XXXXXXXXXXXXXX
1737 1.1 jklos
1738 1.1 jklos sgp = (ndesc == 1) ? (struct sg_ent *)&d->flit[flits] : sgl;
1739 1.1 jklos
1740 1.1 jklos make_sgl(sgp, segs, nsegs);
1741 1.1 jklos sgl_flits = sgl_len(nsegs);
1742 1.1 jklos
1743 1.1 jklos txqs.gen = q->gen;
1744 1.1 jklos txqs.pidx = q->pidx;
1745 1.1 jklos txqs.compl = (q->unacked & 8) << (S_WR_COMPL - 3);
1746 1.1 jklos write_wr_hdr_sgl(ndesc, d, &txqs, q, sgl, flits, sgl_flits,
1747 1.1 jklos from->wr_hi, from->wr_lo);
1748 1.1 jklos }
1749 1.1 jklos
1750 1.1 jklos /**
1751 1.1 jklos * calc_tx_descs_ofld - calculate # of Tx descriptors for an offload packet
1752 1.1 jklos * @m: the packet
1753 1.1 jklos *
1754 1.1 jklos * Returns the number of Tx descriptors needed for the given offload
1755 1.1 jklos * packet. These packets are already fully constructed.
1756 1.1 jklos */
1757 1.1 jklos static __inline unsigned int
1758 1.1 jklos calc_tx_descs_ofld(struct mbuf *m, unsigned int nsegs)
1759 1.1 jklos {
1760 1.1 jklos unsigned int flits, cnt = 0;
1761 1.1 jklos
1762 1.1 jklos
1763 1.1 jklos if (m->m_len <= WR_LEN)
1764 1.1 jklos return 1; /* packet fits as immediate data */
1765 1.1 jklos
1766 1.1 jklos if (m->m_flags & M_IOVEC)
1767 1.1 jklos cnt = mtomv(m)->mv_count;
1768 1.1 jklos
1769 1.1 jklos INT3; // Debug this????
1770 1.1 jklos flits = 3; // XXXXXXXXX
1771 1.1 jklos
1772 1.1 jklos return flits_to_desc(flits + sgl_len(cnt));
1773 1.1 jklos }
1774 1.1 jklos
1775 1.1 jklos /**
1776 1.1 jklos * ofld_xmit - send a packet through an offload queue
1777 1.1 jklos * @adap: the adapter
1778 1.1 jklos * @q: the Tx offload queue
1779 1.1 jklos * @m: the packet
1780 1.1 jklos *
1781 1.1 jklos * Send an offload packet through an SGE offload queue.
1782 1.1 jklos */
1783 1.1 jklos static int
1784 1.1 jklos ofld_xmit(adapter_t *adap, struct sge_txq *q, struct mbuf *m)
1785 1.1 jklos {
1786 1.1 jklos int ret, nsegs;
1787 1.1 jklos unsigned int ndesc;
1788 1.1 jklos unsigned int pidx, gen;
1789 1.1 jklos struct mbuf *m_vec[TX_CLEAN_MAX_DESC];
1790 1.1 jklos bus_dma_segment_t segs[TX_MAX_SEGS];
1791 1.1 jklos int i, cleaned;
1792 1.1 jklos struct tx_sw_desc *stx = &q->sdesc[q->pidx];
1793 1.1 jklos
1794 1.1 jklos mtx_lock(&q->lock);
1795 1.1 jklos if ((ret = busdma_map_mbufs(&m, q, stx, segs, &nsegs)) != 0) {
1796 1.1 jklos mtx_unlock(&q->lock);
1797 1.1 jklos return (ret);
1798 1.1 jklos }
1799 1.1 jklos ndesc = calc_tx_descs_ofld(m, nsegs);
1800 1.1 jklos again: cleaned = reclaim_completed_tx(q, TX_CLEAN_MAX_DESC, m_vec);
1801 1.1 jklos
1802 1.1 jklos ret = check_desc_avail(adap, q, m, ndesc, TXQ_OFLD);
1803 1.1 jklos if (__predict_false(ret)) {
1804 1.1 jklos if (ret == 1) {
1805 1.1 jklos m_set_priority(m, ndesc); /* save for restart */
1806 1.1 jklos mtx_unlock(&q->lock);
1807 1.1 jklos return EINTR;
1808 1.1 jklos }
1809 1.1 jklos goto again;
1810 1.1 jklos }
1811 1.1 jklos
1812 1.1 jklos gen = q->gen;
1813 1.1 jklos q->in_use += ndesc;
1814 1.1 jklos pidx = q->pidx;
1815 1.1 jklos q->pidx += ndesc;
1816 1.1 jklos if (q->pidx >= q->size) {
1817 1.1 jklos q->pidx -= q->size;
1818 1.1 jklos q->gen ^= 1;
1819 1.1 jklos }
1820 1.1 jklos #ifdef T3_TRACE
1821 1.1 jklos T3_TRACE5(adap->tb[q->cntxt_id & 7],
1822 1.1 jklos "ofld_xmit: ndesc %u, pidx %u, len %u, main %u, frags %u",
1823 1.1 jklos ndesc, pidx, skb->len, skb->len - skb->data_len,
1824 1.1 jklos skb_shinfo(skb)->nr_frags);
1825 1.1 jklos #endif
1826 1.1 jklos mtx_unlock(&q->lock);
1827 1.1 jklos
1828 1.1 jklos write_ofld_wr(adap, m, q, pidx, gen, ndesc, segs, nsegs);
1829 1.1 jklos check_ring_tx_db(adap, q);
1830 1.1 jklos
1831 1.1 jklos for (i = 0; i < cleaned; i++) {
1832 1.1 jklos m_freem_vec(m_vec[i]);
1833 1.1 jklos }
1834 1.1 jklos return (0);
1835 1.1 jklos }
1836 1.1 jklos
1837 1.1 jklos /**
1838 1.1 jklos * restart_offloadq - restart a suspended offload queue
1839 1.1 jklos * @qs: the queue set cotaining the offload queue
1840 1.1 jklos *
1841 1.1 jklos * Resumes transmission on a suspended Tx offload queue.
1842 1.1 jklos */
1843 1.1 jklos static void
1844 1.1 jklos restart_offloadq(struct work *wk, void *data)
1845 1.1 jklos {
1846 1.1 jklos
1847 1.1 jklos struct mbuf *m;
1848 1.1 jklos struct sge_qset *qs = data;
1849 1.1 jklos struct sge_txq *q = &qs->txq[TXQ_OFLD];
1850 1.1 jklos adapter_t *adap = qs->port->adapter;
1851 1.1 jklos struct mbuf *m_vec[TX_CLEAN_MAX_DESC];
1852 1.1 jklos bus_dma_segment_t segs[TX_MAX_SEGS];
1853 1.1 jklos int nsegs, i, cleaned;
1854 1.1 jklos struct tx_sw_desc *stx = &q->sdesc[q->pidx];
1855 1.1 jklos
1856 1.1 jklos mtx_lock(&q->lock);
1857 1.1 jklos again: cleaned = reclaim_completed_tx(q, TX_CLEAN_MAX_DESC, m_vec);
1858 1.1 jklos
1859 1.1 jklos while ((m = mbufq_peek(&q->sendq)) != NULL) {
1860 1.1 jklos unsigned int gen, pidx;
1861 1.1 jklos unsigned int ndesc = m_get_priority(m);
1862 1.1 jklos
1863 1.1 jklos if (__predict_false(q->size - q->in_use < ndesc)) {
1864 1.1 jklos setbit(&qs->txq_stopped, TXQ_OFLD);
1865 1.1 jklos smp_mb();
1866 1.1 jklos
1867 1.1 jklos if (should_restart_tx(q) &&
1868 1.1 jklos test_and_clear_bit(TXQ_OFLD, &qs->txq_stopped))
1869 1.1 jklos goto again;
1870 1.1 jklos q->stops++;
1871 1.1 jklos break;
1872 1.1 jklos }
1873 1.1 jklos
1874 1.1 jklos gen = q->gen;
1875 1.1 jklos q->in_use += ndesc;
1876 1.1 jklos pidx = q->pidx;
1877 1.1 jklos q->pidx += ndesc;
1878 1.1 jklos if (q->pidx >= q->size) {
1879 1.1 jklos q->pidx -= q->size;
1880 1.1 jklos q->gen ^= 1;
1881 1.1 jklos }
1882 1.1 jklos
1883 1.1 jklos (void)mbufq_dequeue(&q->sendq);
1884 1.1 jklos busdma_map_mbufs(&m, q, stx, segs, &nsegs);
1885 1.1 jklos mtx_unlock(&q->lock);
1886 1.1 jklos write_ofld_wr(adap, m, q, pidx, gen, ndesc, segs, nsegs);
1887 1.1 jklos mtx_lock(&q->lock);
1888 1.1 jklos }
1889 1.1 jklos mtx_unlock(&q->lock);
1890 1.1 jklos
1891 1.1 jklos #if USE_GTS
1892 1.1 jklos set_bit(TXQ_RUNNING, &q->flags);
1893 1.1 jklos set_bit(TXQ_LAST_PKT_DB, &q->flags);
1894 1.1 jklos #endif
1895 1.1 jklos t3_write_reg(adap, A_SG_KDOORBELL,
1896 1.1 jklos F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
1897 1.1 jklos
1898 1.1 jklos for (i = 0; i < cleaned; i++) {
1899 1.1 jklos m_freem_vec(m_vec[i]);
1900 1.1 jklos }
1901 1.1 jklos }
1902 1.1 jklos
1903 1.1 jklos /**
1904 1.1 jklos * queue_set - return the queue set a packet should use
1905 1.1 jklos * @m: the packet
1906 1.1 jklos *
1907 1.1 jklos * Maps a packet to the SGE queue set it should use. The desired queue
1908 1.1 jklos * set is carried in bits 1-3 in the packet's priority.
1909 1.1 jklos */
1910 1.1 jklos static __inline int
1911 1.1 jklos queue_set(const struct mbuf *m)
1912 1.1 jklos {
1913 1.1 jklos return m_get_priority(m) >> 1;
1914 1.1 jklos }
1915 1.1 jklos
1916 1.1 jklos /**
1917 1.1 jklos * is_ctrl_pkt - return whether an offload packet is a control packet
1918 1.1 jklos * @m: the packet
1919 1.1 jklos *
1920 1.1 jklos * Determines whether an offload packet should use an OFLD or a CTRL
1921 1.1 jklos * Tx queue. This is indicated by bit 0 in the packet's priority.
1922 1.1 jklos */
1923 1.1 jklos static __inline int
1924 1.1 jklos is_ctrl_pkt(const struct mbuf *m)
1925 1.1 jklos {
1926 1.1 jklos return m_get_priority(m) & 1;
1927 1.1 jklos }
1928 1.1 jklos
1929 1.1 jklos /**
1930 1.1 jklos * t3_offload_tx - send an offload packet
1931 1.1 jklos * @tdev: the offload device to send to
1932 1.1 jklos * @m: the packet
1933 1.1 jklos *
1934 1.1 jklos * Sends an offload packet. We use the packet priority to select the
1935 1.1 jklos * appropriate Tx queue as follows: bit 0 indicates whether the packet
1936 1.1 jklos * should be sent as regular or control, bits 1-3 select the queue set.
1937 1.1 jklos */
1938 1.1 jklos int
1939 1.1 jklos t3_offload_tx(struct toedev *tdev, struct mbuf *m)
1940 1.1 jklos {
1941 1.1 jklos adapter_t *adap = tdev2adap(tdev);
1942 1.1 jklos struct sge_qset *qs = &adap->sge.qs[queue_set(m)];
1943 1.1 jklos
1944 1.1 jklos if (__predict_false(is_ctrl_pkt(m)))
1945 1.1 jklos return ctrl_xmit(adap, &qs->txq[TXQ_CTRL], m);
1946 1.1 jklos
1947 1.1 jklos return ofld_xmit(adap, &qs->txq[TXQ_OFLD], m);
1948 1.1 jklos }
1949 1.1 jklos
1950 1.1 jklos static void
1951 1.1 jklos restart_tx(struct sge_qset *qs)
1952 1.1 jklos {
1953 1.1 jklos if (isset(&qs->txq_stopped, TXQ_OFLD) &&
1954 1.1 jklos should_restart_tx(&qs->txq[TXQ_OFLD]) &&
1955 1.1 jklos test_and_clear_bit(TXQ_OFLD, &qs->txq_stopped)) {
1956 1.1 jklos qs->txq[TXQ_OFLD].restarts++;
1957 1.1 jklos workqueue_enqueue(qs->txq[TXQ_OFLD].qresume_task.wq, &qs->txq[TXQ_OFLD].qresume_task.w, NULL);
1958 1.1 jklos }
1959 1.1 jklos if (isset(&qs->txq_stopped, TXQ_CTRL) &&
1960 1.1 jklos should_restart_tx(&qs->txq[TXQ_CTRL]) &&
1961 1.1 jklos test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped)) {
1962 1.1 jklos qs->txq[TXQ_CTRL].restarts++;
1963 1.1 jklos workqueue_enqueue(qs->txq[TXQ_CTRL].qresume_task.wq, &qs->txq[TXQ_CTRL].qresume_task.w, NULL);
1964 1.1 jklos }
1965 1.1 jklos }
1966 1.1 jklos
1967 1.1 jklos /**
1968 1.1 jklos * t3_sge_alloc_qset - initialize an SGE queue set
1969 1.1 jklos * @sc: the controller softc
1970 1.1 jklos * @id: the queue set id
1971 1.1 jklos * @nports: how many Ethernet ports will be using this queue set
1972 1.1 jklos * @irq_vec_idx: the IRQ vector index for response queue interrupts
1973 1.1 jklos * @p: configuration parameters for this queue set
1974 1.1 jklos * @ntxq: number of Tx queues for the queue set
1975 1.1 jklos * @pi: port info for queue set
1976 1.1 jklos *
1977 1.1 jklos * Allocate resources and initialize an SGE queue set. A queue set
1978 1.1 jklos * comprises a response queue, two Rx free-buffer queues, and up to 3
1979 1.1 jklos * Tx queues. The Tx queues are assigned roles in the order Ethernet
1980 1.1 jklos * queue, offload queue, and control queue.
1981 1.1 jklos */
1982 1.1 jklos int
1983 1.1 jklos t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx,
1984 1.1 jklos const struct qset_params *p, int ntxq, struct port_info *pi)
1985 1.1 jklos {
1986 1.1 jklos struct sge_qset *q = &sc->sge.qs[id];
1987 1.1 jklos int i, ret = 0;
1988 1.1 jklos
1989 1.1 jklos init_qset_cntxt(q, id);
1990 1.1 jklos
1991 1.1 jklos if ((ret = alloc_ring(sc, p->fl_size, sizeof(struct rx_desc),
1992 1.1 jklos sizeof(struct rx_sw_desc), &q->fl[0].phys_addr,
1993 1.1 jklos &q->fl[0].desc, &q->fl[0].sdesc,
1994 1.1 jklos &q->fl[0].desc_tag, &q->fl[0].desc_map,
1995 1.1 jklos sc->rx_dmat, &q->fl[0].entry_tag)) != 0) {
1996 1.1 jklos goto err;
1997 1.1 jklos }
1998 1.1 jklos
1999 1.1 jklos if ((ret = alloc_ring(sc, p->jumbo_size, sizeof(struct rx_desc),
2000 1.1 jklos sizeof(struct rx_sw_desc), &q->fl[1].phys_addr,
2001 1.1 jklos &q->fl[1].desc, &q->fl[1].sdesc,
2002 1.1 jklos &q->fl[1].desc_tag, &q->fl[1].desc_map,
2003 1.1 jklos sc->rx_jumbo_dmat, &q->fl[1].entry_tag)) != 0) {
2004 1.1 jklos goto err;
2005 1.1 jklos }
2006 1.1 jklos
2007 1.1 jklos if ((ret = alloc_ring(sc, p->rspq_size, sizeof(struct rsp_desc), 0,
2008 1.1 jklos &q->rspq.phys_addr, &q->rspq.desc, NULL,
2009 1.1 jklos &q->rspq.desc_tag, &q->rspq.desc_map,
2010 1.1 jklos NULL, NULL)) != 0) {
2011 1.1 jklos goto err;
2012 1.1 jklos }
2013 1.1 jklos
2014 1.1 jklos for (i = 0; i < ntxq; ++i) {
2015 1.1 jklos /*
2016 1.1 jklos * The control queue always uses immediate data so does not
2017 1.1 jklos * need to keep track of any mbufs.
2018 1.1 jklos * XXX Placeholder for future TOE support.
2019 1.1 jklos */
2020 1.1 jklos size_t sz = i == TXQ_CTRL ? 0 : sizeof(struct tx_sw_desc);
2021 1.1 jklos
2022 1.1 jklos if ((ret = alloc_ring(sc, p->txq_size[i],
2023 1.1 jklos sizeof(struct tx_desc), sz,
2024 1.1 jklos &q->txq[i].phys_addr, &q->txq[i].desc,
2025 1.1 jklos &q->txq[i].sdesc, &q->txq[i].desc_tag,
2026 1.1 jklos &q->txq[i].desc_map,
2027 1.1 jklos sc->tx_dmat, &q->txq[i].entry_tag)) != 0) {
2028 1.1 jklos goto err;
2029 1.1 jklos }
2030 1.1 jklos mbufq_init(&q->txq[i].sendq);
2031 1.1 jklos q->txq[i].gen = 1;
2032 1.1 jklos q->txq[i].size = p->txq_size[i];
2033 1.1 jklos snprintf(q->txq[i].lockbuf, TXQ_NAME_LEN, "t3 txq lock %d:%d:%d",
2034 1.1 jklos 0, irq_vec_idx, i);
2035 1.1 jklos MTX_INIT(&q->txq[i].lock, q->txq[i].lockbuf, NULL, MTX_DEF);
2036 1.1 jklos }
2037 1.1 jklos
2038 1.1 jklos q->txq[TXQ_ETH].port = pi;
2039 1.1 jklos
2040 1.1 jklos q->txq[TXQ_OFLD].qresume_task.name = "restart_offloadq";
2041 1.1 jklos q->txq[TXQ_OFLD].qresume_task.func = restart_offloadq;
2042 1.1 jklos q->txq[TXQ_OFLD].qresume_task.context = q;
2043 1.1 jklos kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &q->txq[TXQ_OFLD].qresume_task, NULL, "cxgb_make_task");
2044 1.1 jklos
2045 1.1 jklos q->txq[TXQ_CTRL].qresume_task.name = "restart_ctrlq";
2046 1.1 jklos q->txq[TXQ_CTRL].qresume_task.func = restart_ctrlq;
2047 1.1 jklos q->txq[TXQ_CTRL].qresume_task.context = q;
2048 1.1 jklos kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &q->txq[TXQ_CTRL].qresume_task, NULL, "cxgb_make_task");
2049 1.1 jklos
2050 1.1 jklos q->txq[TXQ_ETH].qreclaim_task.name = "sge_txq_reclaim_handler";
2051 1.1 jklos q->txq[TXQ_ETH].qreclaim_task.func = sge_txq_reclaim_handler;
2052 1.1 jklos q->txq[TXQ_ETH].qreclaim_task.context = &q->txq[TXQ_ETH];
2053 1.1 jklos kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &q->txq[TXQ_ETH].qreclaim_task, NULL, "cxgb_make_task");
2054 1.1 jklos
2055 1.1 jklos q->txq[TXQ_OFLD].qreclaim_task.name = "sge_txq_reclaim_handler";
2056 1.1 jklos q->txq[TXQ_OFLD].qreclaim_task.func = sge_txq_reclaim_handler;
2057 1.1 jklos q->txq[TXQ_OFLD].qreclaim_task.context = &q->txq[TXQ_OFLD];
2058 1.1 jklos kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &q->txq[TXQ_OFLD].qreclaim_task, NULL, "cxgb_make_task");
2059 1.1 jklos
2060 1.1 jklos q->fl[0].gen = q->fl[1].gen = 1;
2061 1.1 jklos q->fl[0].size = p->fl_size;
2062 1.1 jklos q->fl[1].size = p->jumbo_size;
2063 1.1 jklos
2064 1.1 jklos q->rspq.gen = 1;
2065 1.1 jklos q->rspq.cidx = 0;
2066 1.1 jklos q->rspq.size = p->rspq_size;
2067 1.1 jklos
2068 1.1 jklos q->txq[TXQ_ETH].stop_thres = nports *
2069 1.1 jklos flits_to_desc(sgl_len(TX_MAX_SEGS + 1) + 3);
2070 1.1 jklos
2071 1.1 jklos q->fl[0].buf_size = MCLBYTES;
2072 1.1 jklos q->fl[1].buf_size = MJUMPAGESIZE;
2073 1.1 jklos
2074 1.1 jklos q->lro.enabled = lro_default;
2075 1.1 jklos
2076 1.1 jklos mtx_lock(&sc->sge.reg_lock);
2077 1.1 jklos ret = -t3_sge_init_rspcntxt(sc, q->rspq.cntxt_id, irq_vec_idx,
2078 1.1 jklos q->rspq.phys_addr, q->rspq.size,
2079 1.1 jklos q->fl[0].buf_size, 1, 0);
2080 1.1 jklos if (ret) {
2081 1.1 jklos printf("error %d from t3_sge_init_rspcntxt\n", ret);
2082 1.1 jklos goto err_unlock;
2083 1.1 jklos }
2084 1.1 jklos
2085 1.1 jklos for (i = 0; i < SGE_RXQ_PER_SET; ++i) {
2086 1.1 jklos ret = -t3_sge_init_flcntxt(sc, q->fl[i].cntxt_id, 0,
2087 1.1 jklos q->fl[i].phys_addr, q->fl[i].size,
2088 1.1 jklos q->fl[i].buf_size, p->cong_thres, 1,
2089 1.1 jklos 0);
2090 1.1 jklos if (ret) {
2091 1.1 jklos printf("error %d from t3_sge_init_flcntxt for index i=%d\n", ret, i);
2092 1.1 jklos goto err_unlock;
2093 1.1 jklos }
2094 1.1 jklos }
2095 1.1 jklos
2096 1.1 jklos ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_ETH].cntxt_id, USE_GTS,
2097 1.1 jklos SGE_CNTXT_ETH, id, q->txq[TXQ_ETH].phys_addr,
2098 1.1 jklos q->txq[TXQ_ETH].size, q->txq[TXQ_ETH].token,
2099 1.1 jklos 1, 0);
2100 1.1 jklos if (ret) {
2101 1.1 jklos printf("error %d from t3_sge_init_ecntxt\n", ret);
2102 1.1 jklos goto err_unlock;
2103 1.1 jklos }
2104 1.1 jklos
2105 1.1 jklos if (ntxq > 1) {
2106 1.1 jklos ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_OFLD].cntxt_id,
2107 1.1 jklos USE_GTS, SGE_CNTXT_OFLD, id,
2108 1.1 jklos q->txq[TXQ_OFLD].phys_addr,
2109 1.1 jklos q->txq[TXQ_OFLD].size, 0, 1, 0);
2110 1.1 jklos if (ret) {
2111 1.1 jklos printf("error %d from t3_sge_init_ecntxt\n", ret);
2112 1.1 jklos goto err_unlock;
2113 1.1 jklos }
2114 1.1 jklos }
2115 1.1 jklos
2116 1.1 jklos if (ntxq > 2) {
2117 1.1 jklos ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_CTRL].cntxt_id, 0,
2118 1.1 jklos SGE_CNTXT_CTRL, id,
2119 1.1 jklos q->txq[TXQ_CTRL].phys_addr,
2120 1.1 jklos q->txq[TXQ_CTRL].size,
2121 1.1 jklos q->txq[TXQ_CTRL].token, 1, 0);
2122 1.1 jklos if (ret) {
2123 1.1 jklos printf("error %d from t3_sge_init_ecntxt\n", ret);
2124 1.1 jklos goto err_unlock;
2125 1.1 jklos }
2126 1.1 jklos }
2127 1.1 jklos
2128 1.1 jklos snprintf(q->rspq.lockbuf, RSPQ_NAME_LEN, "t3 rspq lock %d:%d",
2129 1.1 jklos 0, irq_vec_idx);
2130 1.1 jklos MTX_INIT(&q->rspq.lock, q->rspq.lockbuf, NULL, MTX_DEF);
2131 1.1 jklos
2132 1.1 jklos mtx_unlock(&sc->sge.reg_lock);
2133 1.1 jklos t3_update_qset_coalesce(q, p);
2134 1.1 jklos q->port = pi;
2135 1.1 jklos
2136 1.1 jklos refill_fl(sc, &q->fl[0], q->fl[0].size);
2137 1.1 jklos refill_fl(sc, &q->fl[1], q->fl[1].size);
2138 1.1 jklos refill_rspq(sc, &q->rspq, q->rspq.size - 1);
2139 1.1 jklos
2140 1.1 jklos t3_write_reg(sc, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) |
2141 1.1 jklos V_NEWTIMER(q->rspq.holdoff_tmr));
2142 1.1 jklos
2143 1.1 jklos return (0);
2144 1.1 jklos
2145 1.1 jklos err_unlock:
2146 1.1 jklos mtx_unlock(&sc->sge.reg_lock);
2147 1.1 jklos err:
2148 1.1 jklos t3_free_qset(sc, q);
2149 1.1 jklos
2150 1.1 jklos return (ret);
2151 1.1 jklos }
2152 1.1 jklos
2153 1.1 jklos void
2154 1.1 jklos t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad)
2155 1.1 jklos {
2156 1.1 jklos struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad);
2157 1.1 jklos struct port_info *pi = &adap->port[adap->rxpkt_map[cpl->iff]];
2158 1.1 jklos struct ifnet *ifp = pi->ifp;
2159 1.1 jklos
2160 1.1 jklos DPRINTF("rx_eth m=%p m->m_data=%p p->iff=%d\n", m, mtod(m, uint8_t *), cpl->iff);
2161 1.1 jklos
2162 1.1 jklos /*
2163 1.1 jklos * XXX need to add VLAN support for 6.x
2164 1.1 jklos */
2165 1.1 jklos #ifdef VLAN_SUPPORTED
2166 1.1 jklos if (__predict_false(cpl->vlan_valid)) {
2167 1.1 jklos m->m_pkthdr.ether_vtag = ntohs(cpl->vlan);
2168 1.1 jklos m->m_flags |= M_VLANTAG;
2169 1.1 jklos }
2170 1.1 jklos #endif
2171 1.1 jklos
2172 1.1 jklos m->m_pkthdr.rcvif = ifp;
2173 1.1 jklos m_explode(m);
2174 1.1 jklos /*
2175 1.1 jklos * adjust after conversion to mbuf chain
2176 1.1 jklos */
2177 1.1 jklos m_adj(m, sizeof(*cpl) + ethpad);
2178 1.1 jklos
2179 1.3 ozaki if_percpuq_enqueue(ifp->if_percpuq, m);
2180 1.1 jklos }
2181 1.1 jklos
2182 1.1 jklos /**
2183 1.1 jklos * get_packet - return the next ingress packet buffer from a free list
2184 1.1 jklos * @adap: the adapter that received the packet
2185 1.1 jklos * @drop_thres: # of remaining buffers before we start dropping packets
2186 1.1 jklos * @qs: the qset that the SGE free list holding the packet belongs to
2187 1.1 jklos * @mh: the mbuf header, contains a pointer to the head and tail of the mbuf chain
2188 1.1 jklos * @r: response descriptor
2189 1.1 jklos *
2190 1.1 jklos * Get the next packet from a free list and complete setup of the
2191 1.1 jklos * sk_buff. If the packet is small we make a copy and recycle the
2192 1.1 jklos * original buffer, otherwise we use the original buffer itself. If a
2193 1.1 jklos * positive drop threshold is supplied packets are dropped and their
2194 1.1 jklos * buffers recycled if (a) the number of remaining buffers is under the
2195 1.1 jklos * threshold and the packet is too big to copy, or (b) the packet should
2196 1.1 jklos * be copied but there is no memory for the copy.
2197 1.1 jklos */
2198 1.1 jklos #ifdef DISABLE_MBUF_IOVEC
2199 1.1 jklos
2200 1.1 jklos static int
2201 1.1 jklos get_packet(adapter_t *adap, unsigned int drop_thres, struct sge_qset *qs,
2202 1.1 jklos struct t3_mbuf_hdr *mh, struct rsp_desc *r, struct mbuf *m)
2203 1.1 jklos {
2204 1.1 jklos
2205 1.1 jklos unsigned int len_cq = ntohl(r->len_cq);
2206 1.1 jklos struct sge_fl *fl = (len_cq & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
2207 1.1 jklos struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
2208 1.1 jklos uint32_t len = G_RSPD_LEN(len_cq);
2209 1.1 jklos uint32_t flags = ntohl(r->flags);
2210 1.1 jklos uint8_t sopeop = G_RSPD_SOP_EOP(flags);
2211 1.1 jklos int ret = 0;
2212 1.1 jklos
2213 1.1 jklos prefetch(sd->cl);
2214 1.1 jklos
2215 1.1 jklos fl->credits--;
2216 1.1 jklos bus_dmamap_sync(fl->entry_tag, sd->map, 0, len, BUS_DMASYNC_POSTREAD);
2217 1.1 jklos bus_dmamap_unload(fl->entry_tag, sd->map);
2218 1.1 jklos
2219 1.1 jklos m->m_len = len;
2220 1.1 jklos m_cljset(m, sd->cl, fl->type);
2221 1.1 jklos
2222 1.1 jklos switch(sopeop) {
2223 1.1 jklos case RSPQ_SOP_EOP:
2224 1.1 jklos DBG(DBG_RX, ("get_packet: SOP-EOP m %p\n", m));
2225 1.1 jklos mh->mh_head = mh->mh_tail = m;
2226 1.1 jklos m->m_pkthdr.len = len;
2227 1.1 jklos m->m_flags |= M_PKTHDR;
2228 1.1 jklos ret = 1;
2229 1.1 jklos break;
2230 1.1 jklos case RSPQ_NSOP_NEOP:
2231 1.1 jklos DBG(DBG_RX, ("get_packet: NO_SOP-NO_EOP m %p\n", m));
2232 1.1 jklos m->m_flags &= ~M_PKTHDR;
2233 1.1 jklos if (mh->mh_tail == NULL) {
2234 1.1 jklos if (cxgb_debug)
2235 1.1 jklos printf("discarding intermediate descriptor entry\n");
2236 1.1 jklos m_freem(m);
2237 1.1 jklos break;
2238 1.1 jklos }
2239 1.1 jklos mh->mh_tail->m_next = m;
2240 1.1 jklos mh->mh_tail = m;
2241 1.1 jklos mh->mh_head->m_pkthdr.len += len;
2242 1.1 jklos ret = 0;
2243 1.1 jklos break;
2244 1.1 jklos case RSPQ_SOP:
2245 1.1 jklos DBG(DBG_RX, ("get_packet: SOP m %p\n", m));
2246 1.1 jklos m->m_pkthdr.len = len;
2247 1.1 jklos mh->mh_head = mh->mh_tail = m;
2248 1.1 jklos m->m_flags |= M_PKTHDR;
2249 1.1 jklos ret = 0;
2250 1.1 jklos break;
2251 1.1 jklos case RSPQ_EOP:
2252 1.1 jklos DBG(DBG_RX, ("get_packet: EOP m %p\n", m));
2253 1.1 jklos m->m_flags &= ~M_PKTHDR;
2254 1.1 jklos mh->mh_head->m_pkthdr.len += len;
2255 1.1 jklos mh->mh_tail->m_next = m;
2256 1.1 jklos mh->mh_tail = m;
2257 1.1 jklos ret = 1;
2258 1.1 jklos break;
2259 1.1 jklos }
2260 1.1 jklos if (++fl->cidx == fl->size)
2261 1.1 jklos fl->cidx = 0;
2262 1.1 jklos
2263 1.1 jklos return (ret);
2264 1.1 jklos }
2265 1.1 jklos
2266 1.1 jklos #else
2267 1.1 jklos static int
2268 1.1 jklos get_packet(adapter_t *adap, unsigned int drop_thres, struct sge_qset *qs,
2269 1.1 jklos struct mbuf *m, struct rsp_desc *r)
2270 1.1 jklos {
2271 1.1 jklos
2272 1.1 jklos unsigned int len_cq = ntohl(r->len_cq);
2273 1.1 jklos struct sge_fl *fl = (len_cq & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
2274 1.1 jklos struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
2275 1.1 jklos uint32_t len = G_RSPD_LEN(len_cq);
2276 1.1 jklos uint32_t flags = ntohl(r->flags);
2277 1.1 jklos uint8_t sopeop = G_RSPD_SOP_EOP(flags);
2278 1.1 jklos void *cl;
2279 1.1 jklos int ret = 0;
2280 1.1 jklos
2281 1.1 jklos prefetch(sd->cl);
2282 1.1 jklos
2283 1.1 jklos fl->credits--;
2284 1.1 jklos bus_dmamap_sync(fl->entry_tag, sd->map, 0, len, BUS_DMASYNC_POSTREAD);
2285 1.1 jklos
2286 1.1 jklos if (recycle_enable && len <= SGE_RX_COPY_THRES && sopeop == RSPQ_SOP_EOP) {
2287 1.1 jklos cl = mtod(m, void *);
2288 1.1 jklos memcpy(cl, sd->cl, len);
2289 1.1 jklos recycle_rx_buf(adap, fl, fl->cidx);
2290 1.1 jklos } else {
2291 1.1 jklos cl = sd->cl;
2292 1.1 jklos bus_dmamap_unload(fl->entry_tag, sd->map);
2293 1.1 jklos }
2294 1.1 jklos switch(sopeop) {
2295 1.1 jklos case RSPQ_SOP_EOP:
2296 1.1 jklos DBG(DBG_RX, ("get_packet: SOP-EOP m %p\n", m));
2297 1.1 jklos m->m_len = m->m_pkthdr.len = len;
2298 1.1 jklos if (cl == sd->cl)
2299 1.1 jklos m_cljset(m, cl, fl->type);
2300 1.1 jklos ret = 1;
2301 1.1 jklos goto done;
2302 1.1 jklos break;
2303 1.1 jklos case RSPQ_NSOP_NEOP:
2304 1.1 jklos DBG(DBG_RX, ("get_packet: NO_SOP-NO_EOP m %p\n", m));
2305 1.1 jklos ret = 0;
2306 1.1 jklos break;
2307 1.1 jklos case RSPQ_SOP:
2308 1.1 jklos DBG(DBG_RX, ("get_packet: SOP m %p\n", m));
2309 1.1 jklos m_iovinit(m);
2310 1.1 jklos ret = 0;
2311 1.1 jklos break;
2312 1.1 jklos case RSPQ_EOP:
2313 1.1 jklos DBG(DBG_RX, ("get_packet: EOP m %p\n", m));
2314 1.1 jklos ret = 1;
2315 1.1 jklos break;
2316 1.1 jklos }
2317 1.1 jklos m_iovappend(m, cl, fl->buf_size, len, 0);
2318 1.1 jklos
2319 1.1 jklos done:
2320 1.1 jklos if (++fl->cidx == fl->size)
2321 1.1 jklos fl->cidx = 0;
2322 1.1 jklos
2323 1.1 jklos return (ret);
2324 1.1 jklos }
2325 1.1 jklos #endif
2326 1.1 jklos /**
2327 1.1 jklos * handle_rsp_cntrl_info - handles control information in a response
2328 1.1 jklos * @qs: the queue set corresponding to the response
2329 1.1 jklos * @flags: the response control flags
2330 1.1 jklos *
2331 1.1 jklos * Handles the control information of an SGE response, such as GTS
2332 1.1 jklos * indications and completion credits for the queue set's Tx queues.
2333 1.1 jklos * HW coalesces credits, we don't do any extra SW coalescing.
2334 1.1 jklos */
2335 1.1 jklos static __inline void
2336 1.1 jklos handle_rsp_cntrl_info(struct sge_qset *qs, uint32_t flags)
2337 1.1 jklos {
2338 1.1 jklos unsigned int credits;
2339 1.1 jklos
2340 1.1 jklos #if USE_GTS
2341 1.1 jklos if (flags & F_RSPD_TXQ0_GTS)
2342 1.1 jklos clear_bit(TXQ_RUNNING, &qs->txq[TXQ_ETH].flags);
2343 1.1 jklos #endif
2344 1.1 jklos credits = G_RSPD_TXQ0_CR(flags);
2345 1.1 jklos if (credits) {
2346 1.1 jklos qs->txq[TXQ_ETH].processed += credits;
2347 1.1 jklos if (desc_reclaimable(&qs->txq[TXQ_ETH]) > TX_START_MAX_DESC)
2348 1.1 jklos workqueue_enqueue(qs->port->timer_reclaim_task.wq,
2349 1.1 jklos &qs->port->timer_reclaim_task.w, NULL);
2350 1.1 jklos }
2351 1.1 jklos
2352 1.1 jklos credits = G_RSPD_TXQ2_CR(flags);
2353 1.1 jklos if (credits)
2354 1.1 jklos qs->txq[TXQ_CTRL].processed += credits;
2355 1.1 jklos
2356 1.1 jklos # if USE_GTS
2357 1.1 jklos if (flags & F_RSPD_TXQ1_GTS)
2358 1.1 jklos clear_bit(TXQ_RUNNING, &qs->txq[TXQ_OFLD].flags);
2359 1.1 jklos # endif
2360 1.1 jklos credits = G_RSPD_TXQ1_CR(flags);
2361 1.1 jklos if (credits)
2362 1.1 jklos qs->txq[TXQ_OFLD].processed += credits;
2363 1.1 jklos }
2364 1.1 jklos
2365 1.1 jklos static void
2366 1.1 jklos check_ring_db(adapter_t *adap, struct sge_qset *qs,
2367 1.1 jklos unsigned int sleeping)
2368 1.1 jklos {
2369 1.1 jklos ;
2370 1.1 jklos }
2371 1.1 jklos
2372 1.1 jklos /**
2373 1.1 jklos * process_responses - process responses from an SGE response queue
2374 1.1 jklos * @adap: the adapter
2375 1.1 jklos * @qs: the queue set to which the response queue belongs
2376 1.1 jklos * @budget: how many responses can be processed in this round
2377 1.1 jklos *
2378 1.1 jklos * Process responses from an SGE response queue up to the supplied budget.
2379 1.1 jklos * Responses include received packets as well as credits and other events
2380 1.1 jklos * for the queues that belong to the response queue's queue set.
2381 1.1 jklos * A negative budget is effectively unlimited.
2382 1.1 jklos *
2383 1.1 jklos * Additionally choose the interrupt holdoff time for the next interrupt
2384 1.1 jklos * on this queue. If the system is under memory shortage use a fairly
2385 1.1 jklos * long delay to help recovery.
2386 1.1 jklos */
2387 1.1 jklos static int
2388 1.1 jklos process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
2389 1.1 jklos {
2390 1.1 jklos struct sge_rspq *rspq = &qs->rspq;
2391 1.1 jklos struct rsp_desc *r = &rspq->desc[rspq->cidx];
2392 1.1 jklos int budget_left = budget;
2393 1.1 jklos unsigned int sleeping = 0;
2394 1.1 jklos int lro = qs->lro.enabled;
2395 1.1 jklos #ifdef DEBUG
2396 1.1 jklos static int last_holdoff = 0;
2397 1.1 jklos if (cxgb_debug && rspq->holdoff_tmr != last_holdoff) {
2398 1.1 jklos printf("next_holdoff=%d\n", rspq->holdoff_tmr);
2399 1.1 jklos last_holdoff = rspq->holdoff_tmr;
2400 1.1 jklos }
2401 1.1 jklos #endif
2402 1.1 jklos rspq->next_holdoff = rspq->holdoff_tmr;
2403 1.1 jklos
2404 1.1 jklos while (__predict_true(budget_left && is_new_response(r, rspq))) {
2405 1.1 jklos int eth, eop = 0, ethpad = 0;
2406 1.1 jklos uint32_t flags = ntohl(r->flags);
2407 1.1 jklos uint32_t rss_csum = *(const uint32_t *)r;
2408 1.1 jklos uint32_t rss_hash = r->rss_hdr.rss_hash_val;
2409 1.1 jklos
2410 1.1 jklos eth = (r->rss_hdr.opcode == CPL_RX_PKT);
2411 1.1 jklos
2412 1.1 jklos if (__predict_false(flags & F_RSPD_ASYNC_NOTIF)) {
2413 1.1 jklos /* XXX */
2414 1.1 jklos } else if (flags & F_RSPD_IMM_DATA_VALID) {
2415 1.1 jklos #ifdef DISABLE_MBUF_IOVEC
2416 1.1 jklos if (cxgb_debug)
2417 1.1 jklos printf("IMM DATA VALID opcode=0x%x rspq->cidx=%d\n", r->rss_hdr.opcode, rspq->cidx);
2418 1.1 jklos
2419 1.1 jklos if(get_imm_packet(adap, r, &rspq->rspq_mh) == 0) {
2420 1.1 jklos rspq->next_holdoff = NOMEM_INTR_DELAY;
2421 1.1 jklos budget_left--;
2422 1.1 jklos break;
2423 1.1 jklos } else {
2424 1.1 jklos eop = 1;
2425 1.1 jklos }
2426 1.1 jklos #else
2427 1.1 jklos struct mbuf *m = NULL;
2428 1.1 jklos
2429 1.1 jklos if (rspq->rspq_mbuf == NULL)
2430 1.1 jklos rspq->rspq_mbuf = m_gethdr(M_DONTWAIT, MT_DATA);
2431 1.1 jklos else
2432 1.1 jklos m = m_gethdr(M_DONTWAIT, MT_DATA);
2433 1.1 jklos
2434 1.1 jklos /*
2435 1.1 jklos * XXX revisit me
2436 1.1 jklos */
2437 1.1 jklos if (rspq->rspq_mbuf == NULL && m == NULL) {
2438 1.1 jklos rspq->next_holdoff = NOMEM_INTR_DELAY;
2439 1.1 jklos budget_left--;
2440 1.1 jklos break;
2441 1.1 jklos }
2442 1.1 jklos if (get_imm_packet(adap, r, rspq->rspq_mbuf, m, flags))
2443 1.1 jklos goto skip;
2444 1.1 jklos eop = 1;
2445 1.1 jklos #endif
2446 1.1 jklos rspq->imm_data++;
2447 1.1 jklos } else if (r->len_cq) {
2448 1.1 jklos int drop_thresh = eth ? SGE_RX_DROP_THRES : 0;
2449 1.1 jklos
2450 1.1 jklos #ifdef DISABLE_MBUF_IOVEC
2451 1.1 jklos struct mbuf *m;
2452 1.1 jklos m = m_gethdr(M_NOWAIT, MT_DATA);
2453 1.1 jklos
2454 1.1 jklos if (m == NULL) {
2455 1.1 jklos log(LOG_WARNING, "failed to get mbuf for packet\n");
2456 1.1 jklos break;
2457 1.1 jklos }
2458 1.1 jklos
2459 1.1 jklos eop = get_packet(adap, drop_thresh, qs, &rspq->rspq_mh, r, m);
2460 1.1 jklos #else
2461 1.1 jklos if (rspq->rspq_mbuf == NULL)
2462 1.1 jklos rspq->rspq_mbuf = m_gethdr(M_DONTWAIT, MT_DATA);
2463 1.1 jklos if (rspq->rspq_mbuf == NULL) {
2464 1.1 jklos log(LOG_WARNING, "failed to get mbuf for packet\n");
2465 1.1 jklos break;
2466 1.1 jklos }
2467 1.1 jklos eop = get_packet(adap, drop_thresh, qs, rspq->rspq_mbuf, r);
2468 1.1 jklos #endif
2469 1.1 jklos ethpad = 2;
2470 1.1 jklos } else {
2471 1.1 jklos DPRINTF("pure response\n");
2472 1.1 jklos rspq->pure_rsps++;
2473 1.1 jklos }
2474 1.1 jklos
2475 1.1 jklos if (flags & RSPD_CTRL_MASK) {
2476 1.1 jklos sleeping |= flags & RSPD_GTS_MASK;
2477 1.1 jklos handle_rsp_cntrl_info(qs, flags);
2478 1.1 jklos }
2479 1.1 jklos #ifndef DISABLE_MBUF_IOVEC
2480 1.1 jklos skip:
2481 1.1 jklos #endif
2482 1.1 jklos r++;
2483 1.1 jklos if (__predict_false(++rspq->cidx == rspq->size)) {
2484 1.1 jklos rspq->cidx = 0;
2485 1.1 jklos rspq->gen ^= 1;
2486 1.1 jklos r = rspq->desc;
2487 1.1 jklos }
2488 1.1 jklos
2489 1.1 jklos prefetch(r);
2490 1.1 jklos if (++rspq->credits >= (rspq->size / 4)) {
2491 1.1 jklos refill_rspq(adap, rspq, rspq->credits);
2492 1.1 jklos rspq->credits = 0;
2493 1.1 jklos }
2494 1.1 jklos
2495 1.1 jklos if (eop) {
2496 1.1 jklos prefetch(mtod(rspq->rspq_mh.mh_head, uint8_t *));
2497 1.1 jklos prefetch(mtod(rspq->rspq_mh.mh_head, uint8_t *) + L1_CACHE_BYTES);
2498 1.1 jklos
2499 1.1 jklos if (eth) {
2500 1.1 jklos t3_rx_eth_lro(adap, rspq, rspq->rspq_mh.mh_head, ethpad,
2501 1.1 jklos rss_hash, rss_csum, lro);
2502 1.1 jklos
2503 1.1 jklos rspq->rspq_mh.mh_head = NULL;
2504 1.1 jklos } else {
2505 1.1 jklos rspq->rspq_mh.mh_head->m_pkthdr.csum_data = rss_csum;
2506 1.1 jklos /*
2507 1.1 jklos * XXX size mismatch
2508 1.1 jklos */
2509 1.1 jklos m_set_priority(rspq->rspq_mh.mh_head, rss_hash);
2510 1.1 jklos }
2511 1.1 jklos __refill_fl(adap, &qs->fl[0]);
2512 1.1 jklos __refill_fl(adap, &qs->fl[1]);
2513 1.1 jklos
2514 1.1 jklos }
2515 1.1 jklos --budget_left;
2516 1.1 jklos }
2517 1.1 jklos
2518 1.1 jklos t3_lro_flush(adap, qs, &qs->lro);
2519 1.1 jklos
2520 1.1 jklos if (sleeping)
2521 1.1 jklos check_ring_db(adap, qs, sleeping);
2522 1.1 jklos
2523 1.1 jklos smp_mb(); /* commit Tx queue processed updates */
2524 1.1 jklos if (__predict_false(qs->txq_stopped != 0))
2525 1.1 jklos restart_tx(qs);
2526 1.1 jklos
2527 1.1 jklos budget -= budget_left;
2528 1.1 jklos return (budget);
2529 1.1 jklos }
2530 1.1 jklos
2531 1.1 jklos /*
2532 1.1 jklos * A helper function that processes responses and issues GTS.
2533 1.1 jklos */
2534 1.1 jklos static __inline int
2535 1.1 jklos process_responses_gts(adapter_t *adap, struct sge_rspq *rq)
2536 1.1 jklos {
2537 1.1 jklos int work;
2538 1.1 jklos static int last_holdoff = 0;
2539 1.1 jklos
2540 1.1 jklos work = process_responses(adap, rspq_to_qset(rq), -1);
2541 1.1 jklos
2542 1.1 jklos if (cxgb_debug && (rq->next_holdoff != last_holdoff)) {
2543 1.1 jklos printf("next_holdoff=%d\n", rq->next_holdoff);
2544 1.1 jklos last_holdoff = rq->next_holdoff;
2545 1.1 jklos }
2546 1.1 jklos if (work)
2547 1.1 jklos t3_write_reg(adap, A_SG_GTS, V_RSPQ(rq->cntxt_id) |
2548 1.1 jklos V_NEWTIMER(rq->next_holdoff) | V_NEWINDEX(rq->cidx));
2549 1.1 jklos return work;
2550 1.1 jklos }
2551 1.1 jklos
2552 1.1 jklos
2553 1.1 jklos /*
2554 1.1 jklos * Interrupt handler for legacy INTx interrupts for T3B-based cards.
2555 1.1 jklos * Handles data events from SGE response queues as well as error and other
2556 1.1 jklos * async events as they all use the same interrupt pin. We use one SGE
2557 1.1 jklos * response queue per port in this mode and protect all response queues with
2558 1.1 jklos * queue 0's lock.
2559 1.1 jklos */
2560 1.1 jklos int
2561 1.1 jklos t3b_intr(void *data)
2562 1.1 jklos {
2563 1.1 jklos uint32_t i, map;
2564 1.1 jklos adapter_t *adap = data;
2565 1.1 jklos struct sge_rspq *q0 = &adap->sge.qs[0].rspq;
2566 1.1 jklos
2567 1.1 jklos t3_write_reg(adap, A_PL_CLI, 0);
2568 1.1 jklos map = t3_read_reg(adap, A_SG_DATA_INTR);
2569 1.1 jklos
2570 1.1 jklos if (!map)
2571 1.1 jklos return (FALSE);
2572 1.1 jklos
2573 1.1 jklos if (__predict_false(map & F_ERRINTR))
2574 1.1 jklos workqueue_enqueue(adap->slow_intr_task.wq, &adap->slow_intr_task.w, NULL);
2575 1.1 jklos
2576 1.1 jklos mtx_lock(&q0->lock);
2577 1.1 jklos for_each_port(adap, i)
2578 1.1 jklos if (map & (1 << i))
2579 1.1 jklos process_responses_gts(adap, &adap->sge.qs[i].rspq);
2580 1.1 jklos mtx_unlock(&q0->lock);
2581 1.1 jklos
2582 1.1 jklos return (TRUE);
2583 1.1 jklos }
2584 1.1 jklos
2585 1.1 jklos /*
2586 1.1 jklos * The MSI interrupt handler. This needs to handle data events from SGE
2587 1.1 jklos * response queues as well as error and other async events as they all use
2588 1.1 jklos * the same MSI vector. We use one SGE response queue per port in this mode
2589 1.1 jklos * and protect all response queues with queue 0's lock.
2590 1.1 jklos */
2591 1.1 jklos int
2592 1.1 jklos t3_intr_msi(void *data)
2593 1.1 jklos {
2594 1.1 jklos adapter_t *adap = data;
2595 1.1 jklos struct sge_rspq *q0 = &adap->sge.qs[0].rspq;
2596 1.1 jklos int i, new_packets = 0;
2597 1.1 jklos
2598 1.1 jklos mtx_lock(&q0->lock);
2599 1.1 jklos
2600 1.1 jklos for_each_port(adap, i)
2601 1.1 jklos if (process_responses_gts(adap, &adap->sge.qs[i].rspq))
2602 1.1 jklos new_packets = 1;
2603 1.1 jklos mtx_unlock(&q0->lock);
2604 1.1 jklos if (new_packets == 0)
2605 1.1 jklos workqueue_enqueue(adap->slow_intr_task.wq, &adap->slow_intr_task.w, NULL);
2606 1.1 jklos
2607 1.1 jklos return (TRUE);
2608 1.1 jklos }
2609 1.1 jklos
2610 1.1 jklos int
2611 1.1 jklos t3_intr_msix(void *data)
2612 1.1 jklos {
2613 1.1 jklos struct sge_qset *qs = data;
2614 1.1 jklos adapter_t *adap = qs->port->adapter;
2615 1.1 jklos struct sge_rspq *rspq = &qs->rspq;
2616 1.1 jklos
2617 1.1 jklos mtx_lock(&rspq->lock);
2618 1.1 jklos if (process_responses_gts(adap, rspq) == 0)
2619 1.1 jklos rspq->unhandled_irqs++;
2620 1.1 jklos mtx_unlock(&rspq->lock);
2621 1.1 jklos
2622 1.1 jklos return (TRUE);
2623 1.1 jklos }
2624 1.1 jklos
2625 1.1 jklos /**
2626 1.1 jklos * t3_get_desc - dump an SGE descriptor for debugging purposes
2627 1.1 jklos * @qs: the queue set
2628 1.1 jklos * @qnum: identifies the specific queue (0..2: Tx, 3:response, 4..5: Rx)
2629 1.1 jklos * @idx: the descriptor index in the queue
2630 1.1 jklos * @data: where to dump the descriptor contents
2631 1.1 jklos *
2632 1.1 jklos * Dumps the contents of a HW descriptor of an SGE queue. Returns the
2633 1.1 jklos * size of the descriptor.
2634 1.1 jklos */
2635 1.1 jklos int
2636 1.1 jklos t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
2637 1.1 jklos unsigned char *data)
2638 1.1 jklos {
2639 1.1 jklos if (qnum >= 6)
2640 1.1 jklos return (EINVAL);
2641 1.1 jklos
2642 1.1 jklos if (qnum < 3) {
2643 1.1 jklos if (!qs->txq[qnum].desc || idx >= qs->txq[qnum].size)
2644 1.1 jklos return -EINVAL;
2645 1.1 jklos memcpy(data, &qs->txq[qnum].desc[idx], sizeof(struct tx_desc));
2646 1.1 jklos return sizeof(struct tx_desc);
2647 1.1 jklos }
2648 1.1 jklos
2649 1.1 jklos if (qnum == 3) {
2650 1.1 jklos if (!qs->rspq.desc || idx >= qs->rspq.size)
2651 1.1 jklos return (EINVAL);
2652 1.1 jklos memcpy(data, &qs->rspq.desc[idx], sizeof(struct rsp_desc));
2653 1.1 jklos return sizeof(struct rsp_desc);
2654 1.1 jklos }
2655 1.1 jklos
2656 1.1 jklos qnum -= 4;
2657 1.1 jklos if (!qs->fl[qnum].desc || idx >= qs->fl[qnum].size)
2658 1.1 jklos return (EINVAL);
2659 1.1 jklos memcpy(data, &qs->fl[qnum].desc[idx], sizeof(struct rx_desc));
2660 1.1 jklos return sizeof(struct rx_desc);
2661 1.1 jklos }
2662