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