1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, v.1, (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2014-2017 Cavium, Inc.
24 * The contents of this file are subject to the terms of the Common Development
25 * and Distribution License, v.1, (the "License").
26
27 * You may not use this file except in compliance with the License.
28
29 * You can obtain a copy of the License at available
30 * at http://opensource.org/licenses/CDDL-1.0
31
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35
36 #include "qede.h"
37
38 static qede_dma_handle_entry_t *
qede_get_dmah_entry(qede_tx_ring_t * tx_ring)39 qede_get_dmah_entry(qede_tx_ring_t *tx_ring)
40 {
41 qede_dma_handles_list_t *list = &tx_ring->dmah_list;
42 qede_dma_handle_entry_t *dmah;
43
44 mutex_enter(&list->lock);
45 dmah = list->free_list[list->head];
46 list->free_list[list->head] = NULL;
47 list->head = (list->head + 1) & TX_RING_MASK;
48 mutex_exit(&list->lock);
49
50 return (dmah);
51 }
52
53 static void
qede_put_dmah_entries(qede_tx_ring_t * tx_ring,qede_dma_handle_entry_t * dmah)54 qede_put_dmah_entries(qede_tx_ring_t *tx_ring, qede_dma_handle_entry_t *dmah)
55 {
56 qede_dma_handles_list_t *list = &tx_ring->dmah_list;
57 qede_dma_handle_entry_t *next;
58 u16 index;
59
60 mutex_enter(&list->lock);
61 index = list->tail;
62
63 while (dmah != NULL) {
64 next = dmah->next;
65 dmah->next = NULL;
66 list->free_list[index] = dmah;
67 index = (index + 1) & TX_RING_MASK;
68 dmah = next;
69 }
70
71 list->tail = index;
72
73 mutex_exit(&list->lock);
74 }
75
76 static qede_tx_bcopy_pkt_t *
qede_get_bcopy_pkt(qede_tx_ring_t * tx_ring)77 qede_get_bcopy_pkt(qede_tx_ring_t *tx_ring)
78 {
79 qede_tx_bcopy_list_t *list = &tx_ring->bcopy_list;
80 qede_tx_bcopy_pkt_t *pkt;
81
82 mutex_enter(&list->lock);
83 pkt = list->free_list[list->head];
84 list->free_list[list->head] = NULL;
85 list->head = (list->head + 1) & TX_RING_MASK;
86 mutex_exit(&list->lock);
87
88 return (pkt);
89 }
90
91 static void
qede_put_bcopy_pkt(qede_tx_ring_t * tx_ring,qede_tx_bcopy_pkt_t * pkt)92 qede_put_bcopy_pkt(qede_tx_ring_t *tx_ring, qede_tx_bcopy_pkt_t *pkt)
93 {
94 qede_tx_bcopy_list_t *list = &tx_ring->bcopy_list;
95
96 mutex_enter(&list->lock);
97 list->free_list[list->tail] = pkt;
98 list->tail = (list->tail + 1) & TX_RING_MASK;
99 mutex_exit(&list->lock);
100 }
101
102 void
qede_print_tx_indexes(qede_tx_ring_t * tx_ring)103 qede_print_tx_indexes(qede_tx_ring_t *tx_ring)
104 {
105 uint16_t hw_consumer = LE_16(*tx_ring->hw_cons_ptr);
106 uint16_t chain_idx = ecore_chain_get_cons_idx(&tx_ring->tx_bd_ring);
107 hw_consumer &= TX_RING_MASK;
108 chain_idx &= TX_RING_MASK;
109 qede_print_err("!indices: hw_cons %d, chain_cons = %d, sw_prod = %d",
110 hw_consumer, chain_idx, tx_ring->sw_tx_prod);
111 }
112
113 void
qede_print_rx_indexes(qede_rx_ring_t * rx_ring)114 qede_print_rx_indexes(qede_rx_ring_t *rx_ring)
115 {
116 u16 hw_bd_cons = HOST_TO_LE_16(*rx_ring->hw_cons_ptr);
117 u16 sw_bd_cons = ecore_chain_get_cons_idx(&rx_ring->rx_cqe_ring);
118
119 hw_bd_cons &= (rx_ring->qede->rx_ring_size - 1);
120 sw_bd_cons &= (rx_ring->qede->rx_ring_size - 1);
121 qede_print_err("!RX indices: hw_cons %d, chain_cons = %d",
122 hw_bd_cons, sw_bd_cons);
123 }
124
125
126 /*
127 * Called from tx_completion intr handler.
128 * NOTE: statu_block dma mem. must be sync'ed
129 * in the interrupt handler
130 */
131 int
qede_process_tx_completions(qede_tx_ring_t * tx_ring)132 qede_process_tx_completions(qede_tx_ring_t *tx_ring)
133 {
134 int count = 0;
135 u16 hw_consumer;
136 struct eth_tx_bd *tx_bd;
137 uint16_t chain_idx;
138 u16 nbd, sw_consumer = tx_ring->sw_tx_cons;
139 struct eth_tx_1st_bd *first_bd;
140 u16 bd_consumed = 0;
141 qede_tx_recycle_list_t *recycle_entry;
142 qede_dma_handle_entry_t *dmah, *head = NULL, *tail = NULL;
143 qede_tx_bcopy_pkt_t *bcopy_pkt;
144
145 hw_consumer = LE_16(*tx_ring->hw_cons_ptr);
146 chain_idx = ecore_chain_get_cons_idx(&tx_ring->tx_bd_ring);
147
148 while (hw_consumer != chain_idx) {
149 nbd = 0;
150 bd_consumed = 0;
151 first_bd = NULL;
152
153 recycle_entry = &tx_ring->tx_recycle_list[sw_consumer];
154 if (recycle_entry->dmah_entry != NULL) {
155 dmah = recycle_entry->dmah_entry;
156
157 head = dmah;
158
159 if (head->mp) {
160 freemsg(head->mp);
161 }
162
163 while (dmah != NULL) {
164 (void) ddi_dma_unbind_handle(dmah->dma_handle);
165 dmah = dmah->next;
166 }
167
168
169 qede_put_dmah_entries(tx_ring,
170 head);
171 recycle_entry->dmah_entry = NULL;
172 } else if (recycle_entry->bcopy_pkt != NULL) {
173 bcopy_pkt = recycle_entry->bcopy_pkt;
174
175 qede_put_bcopy_pkt(tx_ring, bcopy_pkt);
176 recycle_entry->bcopy_pkt = NULL;
177 } else {
178 qede_warn(tx_ring->qede,
179 "Invalid completion at index %d",
180 sw_consumer);
181 }
182
183 sw_consumer = (sw_consumer + 1) & TX_RING_MASK;
184
185 first_bd =
186 (struct eth_tx_1st_bd *)ecore_chain_consume(
187 &tx_ring->tx_bd_ring);
188 bd_consumed++;
189
190 nbd = first_bd->data.nbds;
191
192 while (bd_consumed++ < nbd) {
193 ecore_chain_consume(&tx_ring->tx_bd_ring);
194 }
195
196 chain_idx = ecore_chain_get_cons_idx(&tx_ring->tx_bd_ring);
197 count++;
198 }
199
200 tx_ring->sw_tx_cons = sw_consumer;
201
202 if (count && tx_ring->tx_q_sleeping) {
203 tx_ring->tx_q_sleeping = 0;
204 #ifndef NO_CROSSBOW
205 RESUME_TX(tx_ring);
206 #else
207 mac_tx_update(tx_ring->qede->mac_handle);
208 #endif
209 }
210
211 return (count);
212 }
213
214 static int
qede_has_tx_work(qede_tx_ring_t * tx_ring)215 qede_has_tx_work(qede_tx_ring_t *tx_ring)
216 {
217 u16 hw_bd_cons = LE_16(*tx_ring->hw_cons_ptr);
218 u16 sw_bd_cons = ecore_chain_get_cons_idx(&tx_ring->tx_bd_ring);
219
220 if (sw_bd_cons == (hw_bd_cons + 1)) {
221 return (0);
222 }
223 return (hw_bd_cons != sw_bd_cons);
224 }
225
226 static int
qede_has_rx_work(qede_rx_ring_t * rx_ring)227 qede_has_rx_work(qede_rx_ring_t *rx_ring)
228 {
229 u16 hw_bd_cons = HOST_TO_LE_16(*rx_ring->hw_cons_ptr);
230 u16 sw_bd_cons = ecore_chain_get_cons_idx(&rx_ring->rx_cqe_ring);
231 return (hw_bd_cons != sw_bd_cons);
232 }
233
234 static void
qede_set_cksum_flags(mblk_t * mp,uint16_t parse_flags)235 qede_set_cksum_flags(mblk_t *mp,
236 uint16_t parse_flags)
237 {
238 uint32_t cksum_flags = 0;
239 int error = 0;
240 bool l4_is_calc, l4_csum_err, iphdr_len_err;
241
242 l4_is_calc =
243 (parse_flags >> PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT)
244 & PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK;
245 l4_csum_err = (parse_flags >> PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT)
246 & PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK;
247 iphdr_len_err = (parse_flags >> PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT)
248 & PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK;
249
250 if (l4_is_calc) {
251 if (l4_csum_err) {
252 error = 1;
253 } else if (iphdr_len_err) {
254 error = 2;
255 } else {
256 cksum_flags = HCK_FULLCKSUM_OK | HCK_IPV4_HDRCKSUM_OK;
257 }
258 }
259
260 if (error == 1) {
261 qede_print_err("!%s: got L4 csum error",__func__);
262 } else if (error == 2) {
263 qede_print_err("!%s: got IPHDER csum error" ,__func__);
264 }
265
266 mac_hcksum_set(mp, 0, 0, 0, 0, cksum_flags);
267 }
268
269 static qede_rx_buffer_t *
qede_get_next_rx_buffer(qede_rx_ring_t * rx_ring,uint32_t * free_buffer_count)270 qede_get_next_rx_buffer(qede_rx_ring_t *rx_ring,
271 uint32_t *free_buffer_count)
272 {
273 qede_rx_buffer_t *rx_buffer;
274 uint32_t num_entries;
275
276 rx_buffer = qede_get_from_active_list(rx_ring, &num_entries);
277 ASSERT(rx_buffer != NULL);
278 ecore_chain_consume(&rx_ring->rx_bd_ring);
279 *free_buffer_count = num_entries;
280
281 return (rx_buffer);
282 }
283
284 static uint32_t
qede_get_next_lro_buffer(qede_rx_ring_t * rx_ring,qede_lro_info_t * lro_info)285 qede_get_next_lro_buffer(qede_rx_ring_t *rx_ring,
286 qede_lro_info_t *lro_info)
287 {
288 lro_info->rx_buffer[lro_info->bd_count] =
289 qede_get_next_rx_buffer(rx_ring,
290 &lro_info->free_buffer_count);
291 lro_info->bd_count++;
292 return (DDI_SUCCESS);
293 }
294 #ifdef DEBUG_LRO
295 int agg_count = 0;
296 bool agg_print = B_TRUE;
297 #endif
298 static void
qede_lro_start(qede_rx_ring_t * rx_ring,struct eth_fast_path_rx_tpa_start_cqe * cqe)299 qede_lro_start(qede_rx_ring_t *rx_ring,
300 struct eth_fast_path_rx_tpa_start_cqe *cqe)
301 {
302 qede_lro_info_t *lro_info;
303 int i, len_on_first_bd, seg_len;
304
305 lro_info = &rx_ring->lro_info[cqe->tpa_agg_index];
306
307 /* ASSERT(lro_info->agg_state != QEDE_AGG_STATE_NONE); */
308
309 #ifdef DEBUG_LRO
310 if (agg_count++ < 30) {
311 qede_dump_start_lro_cqe(cqe);
312 } else {
313 agg_print = B_FALSE;
314 }
315 #endif
316
317 memset(lro_info, 0, sizeof (qede_lro_info_t));
318 lro_info->agg_state = QEDE_AGG_STATE_START;
319 rx_ring->lro_active_count++;
320
321 /* Parsing and error flags from the parser */;
322
323 lro_info->pars_flags = LE_16(cqe->pars_flags.flags);
324 lro_info->pad = LE_16(cqe->placement_offset);
325 lro_info->header_len = (uint32_t)cqe->header_len;
326 lro_info->vlan_tag = LE_16(cqe->vlan_tag);
327 lro_info->rss_hash = LE_32(cqe->rss_hash);
328
329 seg_len = (int)LE_16(cqe->seg_len);
330 len_on_first_bd = (int)LE_16(cqe->len_on_first_bd);
331 /*
332 * Get the first bd
333 */
334 qede_get_next_lro_buffer(rx_ring, lro_info);
335
336 if (len_on_first_bd < seg_len) {
337 /*
338 * We end up here with jumbo frames
339 * since a TCP segment can span
340 * multiple buffer descriptors.
341 */
342 for (i = 0; i < ETH_TPA_CQE_START_LEN_LIST_SIZE; i++) {
343 if (cqe->ext_bd_len_list[i] == 0) {
344 break;
345 }
346 qede_get_next_lro_buffer(rx_ring, lro_info);
347 }
348 }
349 }
350
351 static void
qede_lro_cont(qede_rx_ring_t * rx_ring,struct eth_fast_path_rx_tpa_cont_cqe * cqe)352 qede_lro_cont(qede_rx_ring_t *rx_ring,
353 struct eth_fast_path_rx_tpa_cont_cqe *cqe)
354 {
355 qede_lro_info_t *lro_info;
356 int i;
357
358 lro_info = &rx_ring->lro_info[cqe->tpa_agg_index];
359
360 /* ASSERT(lro_info->agg_state != QEDE_AGG_STATE_START); */
361 #ifdef DEBUG_LRO
362 if (agg_print) {
363 qede_dump_cont_lro_cqe(cqe);
364 }
365 #endif
366
367 for (i = 0; i < ETH_TPA_CQE_CONT_LEN_LIST_SIZE; i++) {
368 if (cqe->len_list[i] == 0) {
369 break;
370 }
371 qede_get_next_lro_buffer(rx_ring, lro_info);
372 }
373 }
374
375 static mblk_t *
qede_lro_end(qede_rx_ring_t * rx_ring,struct eth_fast_path_rx_tpa_end_cqe * cqe,int * pkt_bytes)376 qede_lro_end(qede_rx_ring_t *rx_ring,
377 struct eth_fast_path_rx_tpa_end_cqe *cqe,
378 int *pkt_bytes)
379 {
380 qede_lro_info_t *lro_info;
381 mblk_t *head = NULL, *tail = NULL, *mp = NULL;
382 qede_rx_buffer_t *rx_buffer;
383 int i, bd_len;
384 uint16_t work_length, total_packet_length;
385 uint32_t rx_buf_size = rx_ring->rx_buf_size;
386 qede_dma_info_t *dma_info;
387
388 lro_info = &rx_ring->lro_info[cqe->tpa_agg_index];
389
390 /* ASSERT(lro_info->agg_state != QEDE_AGG_STATE_START); */
391
392 #ifdef DEBUG_LRO
393 if (agg_print) {
394 qede_dump_end_lro_cqe(cqe);
395 }
396 #endif
397
398 work_length = total_packet_length = LE_16(cqe->total_packet_len);
399
400 /*
401 * Get any buffer descriptors for this cqe
402 */
403 for (i=0; i<ETH_TPA_CQE_END_LEN_LIST_SIZE; i++) {
404 if (cqe->len_list[i] == 0) {
405 break;
406 }
407 qede_get_next_lro_buffer(rx_ring, lro_info);
408 }
409
410 /* ASSERT(lro_info->bd_count != cqe->num_of_bds); */
411
412 if (lro_info->free_buffer_count <
413 rx_ring->rx_low_buffer_threshold) {
414 for (i = 0; i < lro_info->bd_count; i++) {
415 qede_recycle_copied_rx_buffer(
416 lro_info->rx_buffer[i]);
417 lro_info->rx_buffer[i] = NULL;
418 }
419 rx_ring->rx_low_water_cnt++;
420 lro_info->agg_state = QEDE_AGG_STATE_NONE;
421 return (NULL);
422 }
423 /*
424 * Loop through list of buffers for this
425 * aggregation. For each one:
426 * 1. Calculate the buffer length
427 * 2. Adjust the mblk read/write pointers
428 * 3. Link the mblk to the local chain using
429 * b_cont pointers.
430 * Note: each buffer will be rx_buf_size except
431 * the first (subtract the placement_offset)
432 * and the last which contains the remainder
433 * of cqe_end->total_packet_len minus length
434 * of all other buffers.
435 */
436 for (i = 0; i < lro_info->bd_count; i++) {
437
438 rx_buffer = lro_info->rx_buffer[i];
439
440 bd_len =
441 (work_length > rx_buf_size) ? rx_buf_size : work_length;
442 if (i == 0 &&
443 (cqe->num_of_bds > 1)) {
444 bd_len -= lro_info->pad;
445 }
446
447 dma_info = &rx_buffer->dma_info;
448 ddi_dma_sync(dma_info->dma_handle,
449 dma_info->offset,
450 rx_buf_size,
451 DDI_DMA_SYNC_FORKERNEL);
452
453 mp = rx_buffer->mp;
454 mp->b_next = mp->b_cont = NULL;
455
456 if (head == NULL) {
457 head = tail = mp;
458 mp->b_rptr += lro_info->pad;
459 } else {
460 tail->b_cont = mp;
461 tail = mp;
462 }
463
464 mp->b_wptr = (uchar_t *)((unsigned long)mp->b_rptr + bd_len);
465 work_length -= bd_len;
466 }
467
468 qede_set_cksum_flags(head, lro_info->pars_flags);
469
470 rx_ring->rx_lro_pkt_cnt++;
471 rx_ring->lro_active_count--;
472 lro_info->agg_state = QEDE_AGG_STATE_NONE;
473
474 #ifdef DEBUG_LRO
475 if (agg_print) {
476 qede_dump_mblk_chain_bcont_ptr(rx_ring->qede, head);
477 }
478 #endif
479 *pkt_bytes = (int)total_packet_length;
480 return (head);
481 }
482
483
484
485 #ifdef DEBUG_JUMBO
486 int jumbo_count = 0;
487 bool jumbo_print = B_TRUE;
488 #endif
489 static mblk_t *
qede_reg_jumbo_cqe(qede_rx_ring_t * rx_ring,struct eth_fast_path_rx_reg_cqe * cqe)490 qede_reg_jumbo_cqe(qede_rx_ring_t *rx_ring,
491 struct eth_fast_path_rx_reg_cqe *cqe)
492 {
493 int i;
494 qede_rx_buffer_t *rx_buf, *rx_buffer[ETH_RX_MAX_BUFF_PER_PKT];
495 mblk_t *mp = NULL, *head = NULL, *tail = NULL;
496 uint32_t free_buffer_count = 0;
497 uint16_t work_length;
498 uint32_t rx_buf_size = rx_ring->rx_buf_size, bd_len;
499 qede_dma_info_t *dma_info;
500 u8 pad = cqe->placement_offset;
501
502 #ifdef DEBUG_JUMBO
503 if (jumbo_count++ < 8) {
504 qede_dump_reg_cqe(cqe);
505 } else {
506 jumbo_print = B_FALSE;
507 }
508 #endif
509
510 work_length = HOST_TO_LE_16(cqe->pkt_len);
511
512 /*
513 * Get the buffers/mps for this cqe
514 */
515 for (i = 0; i < cqe->bd_num; i++) {
516 rx_buffer[i] =
517 qede_get_next_rx_buffer(rx_ring, &free_buffer_count);
518 }
519
520 /*
521 * If the buffer ring is running low, drop the
522 * packet and return these buffers.
523 */
524 if (free_buffer_count <
525 rx_ring->rx_low_buffer_threshold) {
526 for (i = 0; i < cqe->bd_num; i++) {
527 qede_recycle_copied_rx_buffer(rx_buffer[i]);
528 }
529 rx_ring->rx_low_water_cnt++;
530 return (NULL);
531 }
532
533 for (i = 0; i < cqe->bd_num; i++) {
534 rx_buf = rx_buffer[i];
535
536 bd_len =
537 (work_length > rx_buf_size) ? rx_buf_size : work_length;
538
539 /*
540 * Adjust for placement offset
541 * on first bufffer.
542 */
543 if (i == 0) {
544 bd_len -= pad;
545 }
546
547 dma_info = &rx_buf->dma_info;
548 ddi_dma_sync(dma_info->dma_handle,
549 dma_info->offset,
550 rx_buf_size,
551 DDI_DMA_SYNC_FORKERNEL);
552
553 mp = rx_buf->mp;
554 mp->b_next = mp->b_cont = NULL;
555 /*
556 * Adjust for placement offset
557 * on first bufffer.
558 */
559 if (i == 0) {
560 mp->b_rptr += pad;
561 }
562
563 mp->b_wptr = (uchar_t *)((unsigned long)mp->b_rptr + bd_len);
564
565 if (head == NULL) {
566 head = tail = mp;
567 } else {
568 tail->b_cont = mp;
569 tail = mp;
570 }
571
572 work_length -= bd_len;
573 }
574
575 qede_set_cksum_flags(head,
576 HOST_TO_LE_16(cqe->pars_flags.flags));
577 #ifdef DEBUG_JUMBO
578 if (jumbo_print) {
579 qede_dump_mblk_chain_bcont_ptr(rx_ring->qede, head);
580 }
581 #endif
582 rx_ring->rx_jumbo_pkt_cnt++;
583 return (head);
584 }
585
586 static mblk_t *
qede_reg_cqe(qede_rx_ring_t * rx_ring,struct eth_fast_path_rx_reg_cqe * cqe,int * pkt_bytes)587 qede_reg_cqe(qede_rx_ring_t *rx_ring,
588 struct eth_fast_path_rx_reg_cqe *cqe,
589 int *pkt_bytes)
590 {
591 qede_t *qede = rx_ring->qede;
592 qede_rx_buffer_t *rx_buffer;
593 uint32_t free_buffer_count;
594 mblk_t *mp;
595 uint16_t pkt_len = HOST_TO_LE_16(cqe->pkt_len);
596 u8 pad = cqe->placement_offset;
597 qede_dma_info_t *dma_info;
598 ddi_dma_handle_t dma_handle;
599 char *virt_addr;
600
601 /*
602 * Update the byte count as it will
603 * be the same for normal and jumbo
604 */
605 *pkt_bytes = (int)pkt_len;
606
607 if (cqe->bd_num > 1) {
608 /*
609 * If this cqe uses more than one
610 * rx buffer then it must be
611 * jumbo. Call another handler
612 * for this because the process is
613 * quite different.
614 */
615 return (qede_reg_jumbo_cqe(rx_ring, cqe));
616 }
617
618
619 rx_buffer = qede_get_next_rx_buffer(rx_ring,
620 &free_buffer_count);
621
622 if (free_buffer_count <
623 rx_ring->rx_low_buffer_threshold) {
624 qede_recycle_copied_rx_buffer(rx_buffer);
625 rx_ring->rx_low_water_cnt++;
626 *pkt_bytes = 0;
627 return (NULL);
628 }
629
630 dma_info = &rx_buffer->dma_info;
631 virt_addr = dma_info->virt_addr;
632 dma_handle = dma_info->dma_handle;
633 ddi_dma_sync(dma_handle,
634 0, 0, DDI_DMA_SYNC_FORKERNEL);
635
636 if (pkt_len <= rx_ring->rx_copy_threshold) {
637 mp = allocb(pkt_len + 2, 0); /* IP HDR_ALIGN */
638 if (mp != NULL) {
639 virt_addr += pad;
640 bcopy(virt_addr, mp->b_rptr, pkt_len);
641 } else {
642 /*
643 * Post the buffer back to fw and
644 * drop packet
645 */
646 qede_print_err("!%s(%d): allocb failed",
647 __func__,
648 rx_ring->qede->instance);
649 qede->allocbFailures++;
650 goto freebuf;
651 }
652 /*
653 * We've copied it (or not) and are done with it
654 * so put it back into the passive list.
655 */
656 ddi_dma_sync(dma_handle,
657 0, 0, DDI_DMA_SYNC_FORDEV);
658 qede_recycle_copied_rx_buffer(rx_buffer);
659 rx_ring->rx_copy_cnt++;
660 } else {
661
662 /*
663 * We are going to send this mp/buffer
664 * up to the mac layer. Adjust the
665 * pointeres and link it to our chain.
666 * the rx_buffer is returned to us in
667 * the recycle function so we drop it
668 * here.
669 */
670 mp = rx_buffer->mp;
671 mp->b_rptr += pad;
672 }
673 mp->b_cont = mp->b_next = NULL;
674 mp->b_wptr = (uchar_t *)((unsigned long)mp->b_rptr + pkt_len);
675
676 qede_set_cksum_flags(mp,
677 HOST_TO_LE_16(cqe->pars_flags.flags));
678 #ifdef DEBUG_JUMBO
679 if (jumbo_print) {
680 qede_dump_mblk_chain_bnext_ptr(rx_ring->qede, mp);
681 }
682 #endif
683
684 rx_ring->rx_reg_pkt_cnt++;
685 return (mp);
686
687 freebuf:
688 qede_recycle_copied_rx_buffer(rx_buffer);
689 return (NULL);
690 }
691
692 /*
693 * Routine to process the rx packets on the
694 * passed rx_ring. Can be called for intr or
695 * poll context/routines
696 */
697 static mblk_t *
qede_process_rx_ring(qede_rx_ring_t * rx_ring,int nbytes,int npkts)698 qede_process_rx_ring(qede_rx_ring_t *rx_ring, int nbytes, int npkts)
699 {
700 union eth_rx_cqe *cqe;
701 u16 last_cqe_consumer = rx_ring->last_cqe_consumer;
702 enum eth_rx_cqe_type cqe_type;
703 u16 sw_comp_cons, hw_comp_cons;
704 mblk_t *mp = NULL, *first_mp = NULL, *last_mp = NULL;
705 int pkt_bytes = 0, byte_cnt = 0, pkt_cnt = 0;
706
707 hw_comp_cons = HOST_TO_LE_16(*rx_ring->hw_cons_ptr);
708
709 /* Completion ring sw consumer */
710 sw_comp_cons = ecore_chain_get_cons_idx(&rx_ring->rx_cqe_ring);
711
712 while (sw_comp_cons != hw_comp_cons) {
713 if ((byte_cnt >= nbytes) ||
714 (pkt_cnt >= npkts)) {
715 break;
716 }
717
718 cqe = (union eth_rx_cqe *)
719 ecore_chain_consume(&rx_ring->rx_cqe_ring);
720 /* Get next element and increment the cons_idx */
721
722 (void) ddi_dma_sync(rx_ring->rx_cqe_dmah,
723 last_cqe_consumer, sizeof (*cqe),
724 DDI_DMA_SYNC_FORKERNEL);
725
726 cqe_type = cqe->fast_path_regular.type;
727
728 switch (cqe_type) {
729 case ETH_RX_CQE_TYPE_SLOW_PATH:
730 ecore_eth_cqe_completion(&rx_ring->qede->edev.hwfns[0],
731 (struct eth_slow_path_rx_cqe *)cqe);
732 goto next_cqe;
733 case ETH_RX_CQE_TYPE_REGULAR:
734 mp = qede_reg_cqe(rx_ring,
735 &cqe->fast_path_regular,
736 &pkt_bytes);
737 break;
738 case ETH_RX_CQE_TYPE_TPA_START:
739 qede_lro_start(rx_ring,
740 &cqe->fast_path_tpa_start);
741 goto next_cqe;
742 case ETH_RX_CQE_TYPE_TPA_CONT:
743 qede_lro_cont(rx_ring,
744 &cqe->fast_path_tpa_cont);
745 goto next_cqe;
746 case ETH_RX_CQE_TYPE_TPA_END:
747 mp = qede_lro_end(rx_ring,
748 &cqe->fast_path_tpa_end,
749 &pkt_bytes);
750 break;
751 default:
752 if (cqe_type != 0) {
753 qede_print_err("!%s(%d): cqe_type %x not "
754 "supported", __func__,
755 rx_ring->qede->instance,
756 cqe_type);
757 }
758 goto exit_rx;
759 }
760
761 /*
762 * If we arrive here with no mp,
763 * then we hit an RX buffer threshold
764 * where we had to drop the packet and
765 * give the buffers back to the device.
766 */
767 if (mp == NULL) {
768 rx_ring->rx_drop_cnt++;
769 goto next_cqe;
770 }
771
772 if (first_mp) {
773 last_mp->b_next = mp;
774 } else {
775 first_mp = mp;
776 }
777 last_mp = mp;
778 pkt_cnt++;
779 byte_cnt += pkt_bytes;
780 next_cqe:
781 ecore_chain_recycle_consumed(&rx_ring->rx_cqe_ring);
782 last_cqe_consumer = sw_comp_cons;
783 sw_comp_cons = ecore_chain_get_cons_idx(&rx_ring->rx_cqe_ring);
784 if (!(qede_has_rx_work(rx_ring))) {
785 ecore_sb_update_sb_idx(rx_ring->fp->sb_info);
786 }
787 hw_comp_cons = HOST_TO_LE_16(*rx_ring->hw_cons_ptr);
788 }
789 rx_ring->rx_pkt_cnt += pkt_cnt;
790 rx_ring->rx_byte_cnt += byte_cnt;
791
792 exit_rx:
793 if (first_mp) {
794 last_mp->b_next = NULL;
795 }
796
797 /*
798 * Since prod update will result in
799 * reading of the bd's, do a dma_sync
800 */
801 qede_replenish_rx_buffers(rx_ring);
802 qede_update_rx_q_producer(rx_ring);
803 rx_ring->last_cqe_consumer = last_cqe_consumer;
804
805 return (first_mp);
806 }
807
808 mblk_t *
qede_process_fastpath(qede_fastpath_t * fp,int nbytes,int npkts,int * work_done)809 qede_process_fastpath(qede_fastpath_t *fp,
810 int nbytes, int npkts, int *work_done)
811 {
812 int i = 0;
813 qede_tx_ring_t *tx_ring;
814 qede_rx_ring_t *rx_ring;
815 mblk_t *mp = NULL;
816
817 rx_ring = fp->rx_ring;
818
819 for (i = 0; i < fp->qede->num_tc; i++) {
820 tx_ring = fp->tx_ring[i];
821 if (qede_has_tx_work(tx_ring)) {
822 /* process tx completions */
823 if (mutex_tryenter(&tx_ring->tx_lock) != 0) {
824 *work_done +=
825 qede_process_tx_completions(tx_ring);
826 mutex_exit(&tx_ring->tx_lock);
827 }
828 }
829 }
830
831 if (!(qede_has_rx_work(rx_ring))) {
832 ecore_sb_update_sb_idx(fp->sb_info);
833 }
834
835 rx_ring = fp->rx_ring;
836 if (qede_has_rx_work(rx_ring)) {
837 mutex_enter(&rx_ring->rx_lock);
838 mp = qede_process_rx_ring(rx_ring,
839 nbytes, npkts);
840 if (mp) {
841 *work_done += 1;
842 }
843 mutex_exit(&rx_ring->rx_lock);
844 }
845
846 return (mp);
847 }
848
849 /*
850 * Parse the mblk to extract information
851 * from the protocol headers.
852 * The routine assumes that the l4 header is tcp. Also
853 * it does not account for ipv6 headers since ipv6 lso is
854 * unsupported
855 */
856 static void
qede_pkt_parse_lso_headers(qede_tx_pktinfo_t * pktinfo,mblk_t * mp)857 qede_pkt_parse_lso_headers(qede_tx_pktinfo_t *pktinfo, mblk_t *mp)
858 {
859 struct ether_header *eth_hdr =
860 (struct ether_header *)(void *)mp->b_rptr;
861 ipha_t *ip_hdr;
862 struct tcphdr *tcp_hdr;
863
864 /* mac header type and len */
865 if (ntohs(eth_hdr->ether_type) == ETHERTYPE_IP) {
866 pktinfo->ether_type = ntohs(eth_hdr->ether_type);
867 pktinfo->mac_hlen = sizeof (struct ether_header);
868 } else if (ntohs(eth_hdr->ether_type) == ETHERTYPE_VLAN) {
869 struct ether_vlan_header *vlan_hdr =
870 (struct ether_vlan_header *)(void *)mp->b_rptr;
871 pktinfo->ether_type = ntohs(vlan_hdr->ether_type);
872 pktinfo->mac_hlen = sizeof (struct ether_vlan_header);
873 }
874
875 /* ip header type and len */
876 ip_hdr = (ipha_t *)(void *)((u8 *)mp->b_rptr + pktinfo->mac_hlen);
877 pktinfo->ip_hlen = IPH_HDR_LENGTH(ip_hdr);
878
879 /* Assume TCP protocol */
880 pktinfo->l4_proto = 0x06;
881
882 tcp_hdr = (struct tcphdr *)(void *)
883 ((u8 *)mp->b_rptr + pktinfo->mac_hlen + pktinfo->ip_hlen);
884 pktinfo->l4_hlen = TCP_HDR_LENGTH(tcp_hdr);
885
886
887 pktinfo->total_hlen =
888 pktinfo->mac_hlen +
889 pktinfo->ip_hlen +
890 pktinfo->l4_hlen;
891 }
892
893 static void
qede_get_pkt_offload_info(qede_t * qede,mblk_t * mp,u32 * use_cksum,boolean_t * use_lso,uint16_t * mss)894 qede_get_pkt_offload_info(qede_t *qede, mblk_t *mp,
895 u32 *use_cksum, boolean_t *use_lso, uint16_t *mss)
896 {
897 u32 pflags;
898
899 mac_hcksum_get(mp, NULL, NULL, NULL, NULL, &pflags);
900
901 *use_cksum = pflags;
902 if (qede->lso_enable) {
903 u32 pkt_mss = 0;
904 u32 lso_flags = 0;
905
906 mac_lso_get(mp, &pkt_mss, &lso_flags);
907 *use_lso = (lso_flags == HW_LSO);
908 *mss = (u16)pkt_mss;
909 }
910 }
911
912 static void
913 /* LINTED E_FUNC_ARG_UNUSED */
qede_get_pkt_info(qede_t * qede,mblk_t * mp,qede_tx_pktinfo_t * pktinfo)914 qede_get_pkt_info(qede_t *qede, mblk_t *mp,
915 qede_tx_pktinfo_t *pktinfo)
916 {
917 mblk_t *bp;
918 size_t size;
919 struct ether_header *eth_hdr =
920 (struct ether_header *)(void *)mp->b_rptr;
921
922 pktinfo->total_len = 0;
923 pktinfo->mblk_no = 0;
924
925 /*
926 * Count the total length and the number of
927 * chained mblks in the packet
928 */
929 for (bp = mp; bp != NULL; bp = bp->b_cont) {
930 size = MBLKL(bp);
931 if (size == 0) {
932 continue;
933 }
934
935 pktinfo->total_len += size;
936 pktinfo->mblk_no++;
937 }
938 /* mac header type and len */
939 if (ntohs(eth_hdr->ether_type) == ETHERTYPE_IP) {
940 pktinfo->ether_type = ntohs(eth_hdr->ether_type);
941 pktinfo->mac_hlen = sizeof (struct ether_header);
942 } else if (ntohs(eth_hdr->ether_type) == ETHERTYPE_VLAN) {
943 struct ether_vlan_header *vlan_hdr =
944 (struct ether_vlan_header *)(void *)mp->b_rptr;
945 pktinfo->ether_type = ntohs(vlan_hdr->ether_type);
946 pktinfo->mac_hlen = sizeof (struct ether_vlan_header);
947 }
948
949 }
950
951 /*
952 * Routine to sync dma mem for multiple
953 * descriptors in a chain
954 */
955 void
qede_desc_dma_mem_sync(ddi_dma_handle_t * dma_handle,uint_t start,uint_t count,uint_t range,uint_t unit_size,uint_t direction)956 qede_desc_dma_mem_sync(ddi_dma_handle_t *dma_handle,
957 uint_t start, uint_t count, uint_t range,
958 uint_t unit_size, uint_t direction)
959 {
960 if ((start + count) < range) {
961 (void) ddi_dma_sync(*dma_handle,
962 start * unit_size, count * unit_size, direction);
963 } else {
964 (void) ddi_dma_sync(*dma_handle, start * unit_size,
965 0, direction);
966 (void) ddi_dma_sync(*dma_handle, 0,
967 (start + count - range) * unit_size,
968 direction);
969 }
970 }
971
972 /*
973 * Send tx pkt by copying incoming packet in a
974 * preallocated and mapped dma buffer
975 * Not designed to handle lso for now
976 */
977 static enum qede_xmit_status
qede_tx_bcopy(qede_tx_ring_t * tx_ring,mblk_t * mp,qede_tx_pktinfo_t * pktinfo)978 qede_tx_bcopy(qede_tx_ring_t *tx_ring, mblk_t *mp, qede_tx_pktinfo_t *pktinfo)
979 {
980 qede_tx_bcopy_pkt_t *bcopy_pkt = NULL;
981 /* Only one bd will be needed for bcopy packets */
982 struct eth_tx_1st_bd *first_bd;
983 u16 last_producer = tx_ring->sw_tx_prod;
984 uint8_t *txb;
985 mblk_t *bp;
986 u32 mblen;
987
988 bcopy_pkt = qede_get_bcopy_pkt(tx_ring);
989 if (bcopy_pkt == NULL) {
990 qede_print_err("!%s(%d): entry NULL at _tx_ bcopy_list head",
991 __func__, tx_ring->qede->instance);
992 return (XMIT_FAILED);
993 }
994
995 /*
996 * Copy the packet data to our copy
997 * buffer
998 */
999 txb = bcopy_pkt->virt_addr;
1000
1001 for (bp = mp; bp != NULL; bp = bp->b_cont) {
1002 mblen = MBLKL(bp);
1003 if (mblen == 0) {
1004 continue;
1005 }
1006 bcopy(bp->b_rptr, txb, mblen);
1007 txb += mblen;
1008 }
1009
1010 (void) ddi_dma_sync(bcopy_pkt->dma_handle,
1011 0, pktinfo->total_len,
1012 DDI_DMA_SYNC_FORDEV);
1013
1014
1015 mutex_enter(&tx_ring->tx_lock);
1016 if (ecore_chain_get_elem_left(&tx_ring->tx_bd_ring)<
1017 QEDE_TX_COPY_PATH_PAUSE_THRESHOLD) {
1018 tx_ring->tx_q_sleeping = 1;
1019 qede_put_bcopy_pkt(tx_ring, bcopy_pkt);
1020 mutex_exit(&tx_ring->tx_lock);
1021 #ifdef DEBUG_TX_RECYCLE
1022 qede_print_err("!%s(%d): Pausing tx queue",
1023 __func__, tx_ring->qede->instance);
1024 #endif
1025 return (XMIT_PAUSE_QUEUE);
1026 }
1027
1028 first_bd = ecore_chain_produce(&tx_ring->tx_bd_ring);
1029 bzero(first_bd, sizeof (*first_bd));
1030 first_bd->data.nbds = 1;
1031 first_bd->data.bd_flags.bitfields =
1032 (1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT);
1033
1034 if (pktinfo->cksum_flags & HCK_IPV4_HDRCKSUM) {
1035 first_bd->data.bd_flags.bitfields |=
1036 (1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT);
1037 }
1038
1039 if (pktinfo->cksum_flags & HCK_FULLCKSUM) {
1040 first_bd->data.bd_flags.bitfields |=
1041 (1 << ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT);
1042 }
1043
1044 BD_SET_ADDR_LEN(first_bd,
1045 bcopy_pkt->phys_addr,
1046 pktinfo->total_len);
1047
1048 first_bd->data.bitfields |=
1049 (pktinfo->total_len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK)
1050 << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT;
1051
1052 tx_ring->tx_db.data.bd_prod =
1053 HOST_TO_LE_16(ecore_chain_get_prod_idx(&tx_ring->tx_bd_ring));
1054
1055 tx_ring->tx_recycle_list[tx_ring->sw_tx_prod].bcopy_pkt = bcopy_pkt;
1056 tx_ring->tx_recycle_list[tx_ring->sw_tx_prod].dmah_entry = NULL;
1057
1058 tx_ring->sw_tx_prod++;
1059 tx_ring->sw_tx_prod &= TX_RING_MASK;
1060
1061 (void) ddi_dma_sync(tx_ring->tx_bd_dmah,
1062 last_producer, sizeof (*first_bd),
1063 DDI_DMA_SYNC_FORDEV);
1064
1065 QEDE_DOORBELL_WR(tx_ring, tx_ring->tx_db.raw);
1066 mutex_exit(&tx_ring->tx_lock);
1067
1068 freemsg(mp);
1069
1070 return (XMIT_DONE);
1071 }
1072
1073 /*
1074 * Send tx packet by mapping the mp(kernel addr)
1075 * to an existing dma_handle in the driver
1076 */
1077 static enum qede_xmit_status
qede_tx_mapped(qede_tx_ring_t * tx_ring,mblk_t * mp,qede_tx_pktinfo_t * pktinfo)1078 qede_tx_mapped(qede_tx_ring_t *tx_ring, mblk_t *mp, qede_tx_pktinfo_t *pktinfo)
1079 {
1080 enum qede_xmit_status status = XMIT_FAILED;
1081 int ret;
1082 qede_dma_handle_entry_t *dmah_entry = NULL;
1083 qede_dma_handle_entry_t *head = NULL, *tail = NULL, *hdl;
1084 struct eth_tx_1st_bd *first_bd;
1085 struct eth_tx_2nd_bd *second_bd = 0;
1086 struct eth_tx_3rd_bd *third_bd = 0;
1087 struct eth_tx_bd *tx_data_bd;
1088 struct eth_tx_bd local_bd[64] = { 0 };
1089 ddi_dma_cookie_t cookie[64];
1090 u32 ncookies, total_cookies = 0, max_cookies = 0, index = 0;
1091 ddi_dma_handle_t dma_handle;
1092 mblk_t *bp;
1093 u32 mblen;
1094 bool is_premapped = B_FALSE;
1095 u64 dma_premapped = 0, dma_bound = 0;
1096 u32 hdl_reserved = 0;
1097 u8 nbd = 0;
1098 int i, bd_index;
1099 u16 last_producer;
1100 qede_tx_recycle_list_t *tx_recycle_list = tx_ring->tx_recycle_list;
1101 u64 data_addr;
1102 size_t data_size;
1103
1104 if (pktinfo->use_lso) {
1105 /*
1106 * For tso pkt, we can use as many as 255 bds
1107 */
1108 max_cookies = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET - 1;
1109 qede_pkt_parse_lso_headers(pktinfo, mp);
1110 } else {
1111 /*
1112 * For non-tso packet, only 18 bds can be used
1113 */
1114 max_cookies = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET - 1;
1115 }
1116
1117 for (bp = mp; bp != NULL; bp = bp->b_cont) {
1118 mblen = MBLKL(bp);
1119 if (mblen == 0) {
1120 continue;
1121 }
1122 is_premapped = B_FALSE;
1123 /*
1124 * If the mblk is premapped then get the
1125 * dma_handle and sync the dma mem. otherwise
1126 * reserve an handle from the driver dma
1127 * handles list
1128 */
1129 #ifdef DBLK_DMA_PREMAP
1130 if (bp->b_datap->db_flags & DBLK_DMA_PREMAP) {
1131 #ifdef DEBUG_PREMAP
1132 qede_info(tx_ring->qede, "mp is premapped");
1133 #endif
1134 tx_ring->tx_premap_count++;
1135 ret = dblk_dma_info_get(tx_ring->pm_handle,
1136 bp->b_rptr, mblen,
1137 bp->b_datap, &cookie[index],
1138 &ncookies, &dma_handle);
1139 if (ret == DDI_DMA_MAPPED) {
1140 is_premapped = B_TRUE;
1141 dma_premapped++;
1142 (void) ddi_dma_sync(dma_handle, 0, 0,
1143 DDI_DMA_SYNC_FORDEV);
1144 } else {
1145 tx_ring->tx_premap_fail++;
1146 }
1147 }
1148 #endif /* DBLK_DMA_PREMAP */
1149
1150 if (!is_premapped) {
1151 dmah_entry = qede_get_dmah_entry(tx_ring);
1152 if (dmah_entry == NULL) {
1153 qede_info(tx_ring->qede, "dmah_entry NULL, "
1154 "Fallback to copy mode...");
1155 status = XMIT_FAILED;
1156 goto err_map;
1157 }
1158
1159 if (ddi_dma_addr_bind_handle(dmah_entry->dma_handle,
1160 NULL, (caddr_t)bp->b_rptr, mblen,
1161 DDI_DMA_STREAMING | DDI_DMA_WRITE,
1162 DDI_DMA_DONTWAIT, NULL, &cookie[index], &ncookies)
1163 != DDI_DMA_MAPPED) {
1164
1165 #ifdef DEBUG_PULLUP
1166 qede_info(tx_ring->qede, "addr_bind() failed for "
1167 "handle %p, len %d mblk_no %d tot_len 0x%x"
1168 " use_lso %d", dmah_entry->dma_handle,
1169 mblen, pktinfo->mblk_no, pktinfo->total_len,
1170 pktinfo->use_lso);
1171
1172 qede_info(tx_ring->qede, "Falling back to pullup");
1173 #endif
1174 status = XMIT_FALLBACK_PULLUP;
1175 tx_ring->tx_bind_fail++;
1176 goto err_map;
1177 }
1178 tx_ring->tx_bind_count++;
1179
1180 if (index == 0) {
1181 dmah_entry->mp = mp;
1182 } else {
1183 dmah_entry->mp = NULL;
1184 }
1185
1186 /* queue into recycle list for tx completion routine */
1187 if (tail == NULL) {
1188 head = tail = dmah_entry;
1189 } else {
1190 tail->next = dmah_entry;
1191 tail = dmah_entry;
1192 }
1193
1194 hdl_reserved++;
1195 dma_bound++;
1196 }
1197
1198 total_cookies += ncookies;
1199 if (total_cookies > max_cookies) {
1200 tx_ring->tx_too_many_cookies++;
1201 #ifdef DEBUG_PULLUP
1202 qede_info(tx_ring->qede,
1203 "total_cookies > max_cookies, "
1204 "pktlen %d, mb num %d",
1205 pktinfo->total_len, pktinfo->mblk_no);
1206 #endif
1207 status = XMIT_TOO_MANY_COOKIES;
1208 goto err_map_sec;
1209 }
1210
1211 if (is_premapped) {
1212 index += ncookies;
1213 } else {
1214 index++;
1215 /*
1216 * Dec. ncookies since we already stored cookie[0]
1217 */
1218 ncookies--;
1219
1220 for (i = 0; i < ncookies; i++, index++)
1221 ddi_dma_nextcookie(dmah_entry->dma_handle,
1222 &cookie[index]);
1223 }
1224 }
1225
1226 /*
1227 * Guard against the case where we get a series of mblks that cause us
1228 * not to end up with any mapped data.
1229 */
1230 if (total_cookies == 0) {
1231 status = XMIT_FAILED;
1232 goto err_map_sec;
1233 }
1234
1235 if (total_cookies > max_cookies) {
1236 tx_ring->tx_too_many_cookies++;
1237 status = XMIT_TOO_MANY_COOKIES;
1238 goto err_map_sec;
1239 }
1240 first_bd = (struct eth_tx_1st_bd *)&local_bd[0];
1241
1242 /*
1243 * Mark this bd as start bd
1244 */
1245 first_bd->data.bd_flags.bitfields =
1246 (1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT);
1247
1248 if (pktinfo->cksum_flags & HCK_IPV4_HDRCKSUM) {
1249 first_bd->data.bd_flags.bitfields |=
1250 (1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT);
1251 }
1252
1253 if (pktinfo->cksum_flags & HCK_FULLCKSUM) {
1254 first_bd->data.bd_flags.bitfields |=
1255 (1 << ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT);
1256 }
1257
1258
1259 /* Fill-up local bds with the tx data and flags */
1260 for (i = 0, bd_index = 0; i < total_cookies; i++, bd_index++) {
1261 if (bd_index == 0) {
1262 BD_SET_ADDR_LEN(first_bd,
1263 cookie[i].dmac_laddress,
1264 cookie[i].dmac_size);
1265
1266 if (pktinfo->use_lso) {
1267 first_bd->data.bd_flags.bitfields |=
1268 1 << ETH_TX_1ST_BD_FLAGS_LSO_SHIFT;
1269
1270 second_bd = (struct eth_tx_2nd_bd *)&local_bd[1];
1271
1272 /*
1273 * If the fisrt bd contains
1274 * hdr + data (partial or full data), then spilt
1275 * the hdr and data between 1st and 2nd
1276 * bd respectively
1277 */
1278 if (first_bd->nbytes > pktinfo->total_hlen) {
1279 data_addr = cookie[0].dmac_laddress
1280 + pktinfo->total_hlen;
1281 data_size = cookie[i].dmac_size
1282 - pktinfo->total_hlen;
1283
1284 BD_SET_ADDR_LEN(second_bd,
1285 data_addr,
1286 data_size);
1287
1288 /*
1289 * First bd already contains the addr to
1290 * to start of pkt, just adjust the dma
1291 * len of first_bd
1292 */
1293 first_bd->nbytes = pktinfo->total_hlen;
1294 bd_index++;
1295 } else if (first_bd->nbytes < pktinfo->total_hlen) {
1296 #ifdef DEBUG_PULLUP
1297 qede_info(tx_ring->qede,
1298 "Headers not in single bd");
1299 #endif
1300 status = XMIT_FALLBACK_PULLUP;
1301 goto err_map_sec;
1302
1303 }
1304
1305 /*
1306 * Third bd is used to indicates to fw
1307 * that tso needs to be performed. It should
1308 * be present even if only two cookies are
1309 * needed for the mblk
1310 */
1311 third_bd = (struct eth_tx_3rd_bd *)&local_bd[2];
1312 third_bd->data.lso_mss |=
1313 HOST_TO_LE_16(pktinfo->mss);
1314 third_bd->data.bitfields |=
1315 1 << ETH_TX_DATA_3RD_BD_HDR_NBD_SHIFT;
1316 }
1317
1318 continue;
1319 }
1320
1321 tx_data_bd = &local_bd[bd_index];
1322 BD_SET_ADDR_LEN(tx_data_bd,
1323 cookie[i].dmac_laddress,
1324 cookie[i].dmac_size);
1325 }
1326
1327 if (pktinfo->use_lso) {
1328 if (bd_index < 3) {
1329 nbd = 3;
1330 } else {
1331 nbd = bd_index;
1332 }
1333 } else {
1334 nbd = total_cookies;
1335 first_bd->data.bitfields |=
1336 (pktinfo->total_len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK)
1337 << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT;
1338 }
1339
1340 first_bd->data.nbds = nbd;
1341
1342 mutex_enter(&tx_ring->tx_lock);
1343
1344 /*
1345 * Before copying the local bds into actual,
1346 * check if we have enough on the bd_chain
1347 */
1348 if (ecore_chain_get_elem_left(&tx_ring->tx_bd_ring) <
1349 nbd) {
1350 tx_ring->tx_q_sleeping = 1;
1351 status = XMIT_PAUSE_QUEUE;
1352 #ifdef DEBUG_TX_RECYCLE
1353 qede_info(tx_ring->qede, "Pausing tx queue...");
1354 #endif
1355 mutex_exit(&tx_ring->tx_lock);
1356 goto err_map_sec ;
1357 }
1358
1359 /* Copy the local_bd(s) into the actual bds */
1360 for (i = 0; i < nbd; i++) {
1361 tx_data_bd = ecore_chain_produce(&tx_ring->tx_bd_ring);
1362 bcopy(&local_bd[i], tx_data_bd, sizeof (*tx_data_bd));
1363 }
1364
1365 last_producer = tx_ring->sw_tx_prod;
1366
1367 tx_ring->tx_recycle_list[tx_ring->sw_tx_prod].dmah_entry = head;
1368 tx_ring->tx_recycle_list[tx_ring->sw_tx_prod].bcopy_pkt = NULL;
1369 tx_ring->sw_tx_prod = (tx_ring->sw_tx_prod + 1) & TX_RING_MASK;
1370
1371 tx_ring->tx_db.data.bd_prod =
1372 HOST_TO_LE_16(ecore_chain_get_prod_idx(&tx_ring->tx_bd_ring));
1373
1374 /* Sync the tx_bd dma mem */
1375 qede_desc_dma_mem_sync(&tx_ring->tx_bd_dmah,
1376 last_producer, nbd,
1377 tx_ring->tx_ring_size,
1378 sizeof (struct eth_tx_bd),
1379 DDI_DMA_SYNC_FORDEV);
1380
1381 /*
1382 * Write to doorbell bar
1383 */
1384 QEDE_DOORBELL_WR(tx_ring, tx_ring->tx_db.raw);
1385
1386 mutex_exit(&tx_ring->tx_lock);
1387
1388 return (XMIT_DONE);
1389 err_map:
1390 if (dmah_entry != NULL) {
1391 if (tail == NULL) {
1392 head = tail = dmah_entry;
1393 } else {
1394 tail->next = dmah_entry;
1395 tail = dmah_entry;
1396 }
1397 hdl_reserved++;
1398 }
1399
1400 err_map_sec:
1401
1402 hdl = head;
1403
1404 while (hdl != NULL) {
1405 (void) ddi_dma_unbind_handle(hdl->dma_handle);
1406 hdl = hdl->next;
1407 }
1408
1409 if (head != NULL) {
1410 qede_put_dmah_entries(tx_ring, head);
1411 }
1412
1413 return (status);
1414 }
1415
1416 static enum qede_xmit_status
qede_send_tx_packet(qede_t * qede,qede_tx_ring_t * tx_ring,mblk_t * mp)1417 qede_send_tx_packet(qede_t *qede, qede_tx_ring_t *tx_ring, mblk_t *mp)
1418 {
1419 boolean_t force_pullup = B_FALSE;
1420 enum qede_xmit_status status = XMIT_FAILED;
1421 enum qede_xmit_mode xmit_mode = USE_BCOPY;
1422 qede_tx_pktinfo_t pktinfo;
1423 mblk_t *original_mp = NULL, *pulled_up_mp = NULL;
1424 struct ether_vlan_header *ethvhdr;
1425
1426 mutex_enter(&tx_ring->tx_lock);
1427 if (ecore_chain_get_elem_left(&tx_ring->tx_bd_ring) <
1428 qede->tx_recycle_threshold) {
1429 #ifdef DEBUG_TX_RECYCLE
1430 qede_info(qede, "Recyclycling from tx routine");
1431 #endif
1432 if (qede_process_tx_completions(tx_ring) <
1433 qede->tx_recycle_threshold) {
1434 #ifdef DEBUG_TX_RECYCLE
1435 qede_info(qede, "Still not enough bd after cleanup, "
1436 "pausing tx queue...");
1437 #endif
1438 tx_ring->tx_q_sleeping = 1;
1439 mutex_exit(&tx_ring->tx_lock);
1440 return (XMIT_PAUSE_QUEUE);
1441 }
1442 }
1443
1444 mutex_exit(&tx_ring->tx_lock);
1445
1446 bzero(&pktinfo, sizeof (pktinfo));
1447
1448 /* Get the offload reqd. on the pkt */
1449 qede_get_pkt_offload_info(qede, mp, &pktinfo.cksum_flags,
1450 &pktinfo.use_lso, &pktinfo.mss);
1451
1452 do_pullup:
1453 if (force_pullup) {
1454 tx_ring->tx_pullup_count++;
1455 #ifdef DEBUG_PULLUP
1456 qede_info(qede, "Pulling up original mp %p", mp);
1457 #endif
1458 /*
1459 * Try to accumulate all mblks of this pkt
1460 * into a single mblk
1461 */
1462 original_mp = mp;
1463 if ((pulled_up_mp = msgpullup(mp, -1)) != NULL) {
1464 #ifdef DEBUG_PULLUP
1465 qede_info(qede, "New mp %p, ori %p", pulled_up_mp, mp);
1466 #endif
1467 /*
1468 * Proceed with the new single
1469 * mp
1470 */
1471 mp = pulled_up_mp;
1472 xmit_mode = XMIT_MODE_UNUSED;
1473 pktinfo.pulled_up = B_TRUE;
1474 } else {
1475 #ifdef DEBUG_PULLUP
1476 qede_info(tx_ring->qede, "Pullup failed");
1477 #endif
1478 status = XMIT_FAILED;
1479 goto exit;
1480 }
1481 }
1482
1483 qede_get_pkt_info(qede, mp, &pktinfo);
1484
1485
1486 if ((!pktinfo.use_lso) &&
1487 (pktinfo.total_len > (qede->mtu + pktinfo.mac_hlen))) {
1488 qede_info(tx_ring->qede,
1489 "Packet drop as packet len 0x%x > 0x%x",
1490 pktinfo.total_len, (qede->mtu + QEDE_MAX_ETHER_HDR));
1491 status = XMIT_FAILED;
1492 goto exit;
1493 }
1494
1495
1496 #ifdef DEBUG_PULLUP
1497 if (force_pullup) {
1498 qede_print_err("!%s: mp %p, pktinfo : total_len %d,"
1499 " mblk_no %d, ether_type %d\n"
1500 "mac_hlen %d, ip_hlen %d, l4_hlen %d\n"
1501 "l4_proto %d, use_cksum:use_lso %d:%d mss %d", __func__, mp,
1502 pktinfo.total_len, pktinfo.mblk_no, pktinfo.ether_type,
1503 pktinfo.mac_hlen, pktinfo.ip_hlen, pktinfo.l4_hlen,
1504 pktinfo.l4_proto, pktinfo.cksum_flags, pktinfo.use_lso,
1505 pktinfo.mss);
1506 }
1507 #endif
1508
1509 #ifdef DEBUG_PREMAP
1510 if (DBLK_IS_PREMAPPED(mp->b_datap)) {
1511 qede_print_err("!%s(%d): mp %p id PREMAPPMED",
1512 __func__, qede->instance);
1513 }
1514 #endif
1515
1516 #ifdef DBLK_DMA_PREMAP
1517 if (DBLK_IS_PREMAPPED(mp->b_datap) ||
1518 pktinfo.total_len > qede->tx_bcopy_threshold) {
1519 xmit_mode = USE_DMA_BIND;
1520 }
1521 #else
1522 if (pktinfo.total_len > qede->tx_bcopy_threshold) {
1523 xmit_mode = USE_DMA_BIND;
1524 }
1525 #endif
1526
1527 if (pktinfo.total_len <= qede->tx_bcopy_threshold) {
1528 xmit_mode = USE_BCOPY;
1529 }
1530
1531 /*
1532 * if mac + ip hdr not in one contiguous block,
1533 * use copy mode
1534 */
1535 if (MBLKL(mp) < (ETHER_HEADER_LEN + IP_HEADER_LEN)) {
1536 /*qede_info(qede, "mblk too small, using copy mode, len = %d", MBLKL(mp));*/
1537 xmit_mode = USE_BCOPY;
1538 }
1539
1540 if ((uintptr_t)mp->b_rptr & 1) {
1541 xmit_mode = USE_BCOPY;
1542 }
1543
1544 /*
1545 * if too many mblks and hence the dma cookies, needed
1546 * for tx, then use bcopy or pullup on packet
1547 * currently, ETH_TX_MAX_BDS_PER_NON_LSO_PACKET = 18
1548 */
1549 if (pktinfo.mblk_no > (ETH_TX_MAX_BDS_PER_NON_LSO_PACKET - 1)) {
1550 if (force_pullup) {
1551 tx_ring->tx_too_many_mblks++;
1552 status = XMIT_FAILED;
1553 goto exit;
1554 } else {
1555 xmit_mode = USE_PULLUP;
1556 }
1557 }
1558
1559 #ifdef TX_FORCE_COPY_MODE
1560 xmit_mode = USE_BCOPY;
1561 #elif TX_FORCE_MAPPED_MODE
1562 xmit_mode = USE_DMA_BIND;
1563 #endif
1564
1565 #ifdef DEBUG_PULLUP
1566 if (force_pullup) {
1567 qede_info(qede, "using mode %d on pulled mp %p",
1568 xmit_mode, mp);
1569 }
1570 #endif
1571
1572 /*
1573 * Use Mapped mode for the packet
1574 */
1575 if (xmit_mode == USE_DMA_BIND) {
1576 status = qede_tx_mapped(tx_ring, mp, &pktinfo);
1577 if (status == XMIT_DONE) {
1578 if (pktinfo.use_lso) {
1579 tx_ring->tx_lso_pkt_count++;
1580 } else if(pktinfo.total_len > 1518) {
1581 tx_ring->tx_jumbo_pkt_count++;
1582 }
1583 tx_ring->tx_mapped_pkts++;
1584 goto exit;
1585 } else if ((status == XMIT_TOO_MANY_COOKIES ||
1586 (status == XMIT_FALLBACK_PULLUP)) && !force_pullup) {
1587 xmit_mode = USE_PULLUP;
1588 } else {
1589 status = XMIT_FAILED;
1590 goto exit;
1591 }
1592 }
1593
1594 if (xmit_mode == USE_BCOPY) {
1595 status = qede_tx_bcopy(tx_ring, mp, &pktinfo);
1596 if (status == XMIT_DONE) {
1597 tx_ring->tx_copy_count++;
1598 goto exit;
1599 } else if ((status == XMIT_FALLBACK_PULLUP) &&
1600 !force_pullup) {
1601 xmit_mode = USE_PULLUP;
1602 } else {
1603 goto exit;
1604 }
1605 }
1606
1607 if (xmit_mode == USE_PULLUP) {
1608 force_pullup = B_TRUE;
1609 tx_ring->tx_pullup_count++;
1610 goto do_pullup;
1611 }
1612
1613 exit:
1614 if (status != XMIT_DONE) {
1615 /*
1616 * if msgpullup succeeded, but something else failed,
1617 * free the pulled-up msg and return original mblk to
1618 * stack, indicating tx failure
1619 */
1620 if (pulled_up_mp) {
1621 qede_info(qede, "tx failed, free pullup pkt %p", mp);
1622 freemsg(pulled_up_mp);
1623 mp = original_mp;
1624 }
1625 } else {
1626 tx_ring->tx_byte_count += pktinfo.total_len;
1627 /*
1628 * If tx was successfull after a pullup, then free the
1629 * original mp. The pulled-up will be freed as part of
1630 * tx completions processing
1631 */
1632 if (pulled_up_mp) {
1633 #ifdef DEBUG_PULLUP
1634 qede_info(qede,
1635 "success, free ori mp %p", original_mp);
1636 #endif
1637 freemsg(original_mp);
1638 }
1639 }
1640
1641 return (status);
1642 }
1643
1644 typedef uint32_t ub4; /* unsigned 4-byte quantities */
1645 typedef uint8_t ub1;
1646
1647 #define hashsize(n) ((ub4)1<<(n))
1648 #define hashmask(n) (hashsize(n)-1)
1649
1650 #define mix(a, b, c) \
1651 { \
1652 a -= b; a -= c; a ^= (c>>13); \
1653 b -= c; b -= a; b ^= (a<<8); \
1654 c -= a; c -= b; c ^= (b>>13); \
1655 a -= b; a -= c; a ^= (c>>12); \
1656 b -= c; b -= a; b ^= (a<<16); \
1657 c -= a; c -= b; c ^= (b>>5); \
1658 a -= b; a -= c; a ^= (c>>3); \
1659 b -= c; b -= a; b ^= (a<<10); \
1660 c -= a; c -= b; c ^= (b>>15); \
1661 }
1662
1663 ub4
hash(k,length,initval)1664 hash(k, length, initval)
1665 register ub1 *k; /* the key */
1666 register ub4 length; /* the length of the key */
1667 register ub4 initval; /* the previous hash, or an arbitrary value */
1668 {
1669 register ub4 a, b, c, len;
1670
1671 /* Set up the internal state */
1672 len = length;
1673 a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
1674 c = initval; /* the previous hash value */
1675
1676 /* handle most of the key */
1677 while (len >= 12)
1678 {
1679 a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
1680 b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
1681 c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
1682 mix(a, b, c);
1683 k += 12;
1684 len -= 12;
1685 }
1686
1687 /* handle the last 11 bytes */
1688 c += length;
1689 /* all the case statements fall through */
1690 switch (len)
1691 {
1692 /* FALLTHRU */
1693 case 11:
1694 c += ((ub4)k[10]<<24);
1695 /* FALLTHRU */
1696 case 10:
1697 c += ((ub4)k[9]<<16);
1698 /* FALLTHRU */
1699 case 9 :
1700 c += ((ub4)k[8]<<8);
1701 /* the first byte of c is reserved for the length */
1702 /* FALLTHRU */
1703 case 8 :
1704 b += ((ub4)k[7]<<24);
1705 /* FALLTHRU */
1706 case 7 :
1707 b += ((ub4)k[6]<<16);
1708 /* FALLTHRU */
1709 case 6 :
1710 b += ((ub4)k[5]<<8);
1711 /* FALLTHRU */
1712 case 5 :
1713 b += k[4];
1714 /* FALLTHRU */
1715 case 4 :
1716 a += ((ub4)k[3]<<24);
1717 /* FALLTHRU */
1718 case 3 :
1719 a += ((ub4)k[2]<<16);
1720 /* FALLTHRU */
1721 case 2 :
1722 a += ((ub4)k[1]<<8);
1723 /* FALLTHRU */
1724 case 1 :
1725 a += k[0];
1726 /* case 0: nothing left to add */
1727 }
1728 mix(a, b, c);
1729 /* report the result */
1730 return (c);
1731 }
1732
1733 #ifdef NO_CROSSBOW
1734 static uint8_t
qede_hash_get_txq(qede_t * qede,caddr_t bp)1735 qede_hash_get_txq(qede_t *qede, caddr_t bp)
1736 {
1737 struct ip *iphdr = NULL;
1738 struct ether_header *ethhdr;
1739 struct ether_vlan_header *ethvhdr;
1740 struct tcphdr *tcp_hdr;
1741 struct udphdr *udp_hdr;
1742 uint32_t etherType;
1743 int mac_hdr_len, ip_hdr_len;
1744 uint32_t h = 0; /* 0 by default */
1745 uint8_t tx_ring_id = 0;
1746 uint32_t ip_src_addr = 0;
1747 uint32_t ip_desc_addr = 0;
1748 uint16_t src_port = 0;
1749 uint16_t dest_port = 0;
1750 uint8_t key[12];
1751
1752 if (qede->num_fp == 1) {
1753 return (tx_ring_id);
1754 }
1755
1756 ethhdr = (struct ether_header *)((void *)bp);
1757 ethvhdr = (struct ether_vlan_header *)((void *)bp);
1758
1759 /* Is this vlan packet? */
1760 if (ntohs(ethvhdr->ether_tpid) == ETHERTYPE_VLAN) {
1761 mac_hdr_len = sizeof (struct ether_vlan_header);
1762 etherType = ntohs(ethvhdr->ether_type);
1763 } else {
1764 mac_hdr_len = sizeof (struct ether_header);
1765 etherType = ntohs(ethhdr->ether_type);
1766 }
1767 /* Is this IPv4 or IPv6 packet? */
1768 if (etherType == ETHERTYPE_IP /* 0800 */) {
1769 if (IPH_HDR_VERSION((ipha_t *)(void *)(bp+mac_hdr_len))
1770 == IPV4_VERSION) {
1771 iphdr = (struct ip *)(void *)(bp+mac_hdr_len);
1772 }
1773 if (((unsigned long)iphdr) & 0x3) {
1774 /* IP hdr not 4-byte aligned */
1775 return (tx_ring_id);
1776 }
1777 }
1778 /* ipV4 packets */
1779 if (iphdr) {
1780
1781 ip_hdr_len = IPH_HDR_LENGTH(iphdr);
1782 ip_src_addr = iphdr->ip_src.s_addr;
1783 ip_desc_addr = iphdr->ip_dst.s_addr;
1784
1785 if (iphdr->ip_p == IPPROTO_TCP) {
1786 tcp_hdr = (struct tcphdr *)(void *)
1787 ((uint8_t *)iphdr + ip_hdr_len);
1788 src_port = tcp_hdr->th_sport;
1789 dest_port = tcp_hdr->th_dport;
1790 } else if (iphdr->ip_p == IPPROTO_UDP) {
1791 udp_hdr = (struct udphdr *)(void *)
1792 ((uint8_t *)iphdr + ip_hdr_len);
1793 src_port = udp_hdr->uh_sport;
1794 dest_port = udp_hdr->uh_dport;
1795 }
1796 key[0] = (uint8_t)((ip_src_addr) &0xFF);
1797 key[1] = (uint8_t)((ip_src_addr >> 8) &0xFF);
1798 key[2] = (uint8_t)((ip_src_addr >> 16) &0xFF);
1799 key[3] = (uint8_t)((ip_src_addr >> 24) &0xFF);
1800 key[4] = (uint8_t)((ip_desc_addr) &0xFF);
1801 key[5] = (uint8_t)((ip_desc_addr >> 8) &0xFF);
1802 key[6] = (uint8_t)((ip_desc_addr >> 16) &0xFF);
1803 key[7] = (uint8_t)((ip_desc_addr >> 24) &0xFF);
1804 key[8] = (uint8_t)((src_port) &0xFF);
1805 key[9] = (uint8_t)((src_port >> 8) &0xFF);
1806 key[10] = (uint8_t)((dest_port) &0xFF);
1807 key[11] = (uint8_t)((dest_port >> 8) &0xFF);
1808 h = hash(key, 12, 0); /* return 32 bit */
1809 tx_ring_id = (h & (qede->num_fp - 1));
1810 if (tx_ring_id >= qede->num_fp) {
1811 cmn_err(CE_WARN, "%s bad tx_ring_id %d\n",
1812 __func__, tx_ring_id);
1813 tx_ring_id = 0;
1814 }
1815 }
1816 return (tx_ring_id);
1817 }
1818 #endif
1819
1820 mblk_t *
qede_ring_tx(void * arg,mblk_t * mp)1821 qede_ring_tx(void *arg, mblk_t *mp)
1822 {
1823 qede_fastpath_t *fp = (qede_fastpath_t *)arg;
1824 qede_t *qede = fp->qede;
1825 #ifndef NO_CROSSBOW
1826 qede_tx_ring_t *tx_ring = fp->tx_ring[0];
1827 #else
1828 qede_tx_ring_t *tx_ring;
1829 #endif
1830 uint32_t ring_id;
1831 mblk_t *next = NULL;
1832 enum qede_xmit_status status = XMIT_FAILED;
1833 caddr_t bp;
1834
1835 ASSERT(mp->b_next == NULL);
1836
1837 #ifndef NO_CROSSBOW
1838 if (!fp || !tx_ring) {
1839 qede_print_err("!%s: error, fp %p, tx_ring %p",
1840 __func__, fp, tx_ring);
1841 goto exit;
1842 }
1843 #endif
1844 if (qede->qede_state != QEDE_STATE_STARTED) {
1845 qede_print_err("!%s(%d): qede_state %d invalid",
1846 __func__, qede->instance, qede->qede_state);
1847 goto exit;
1848 }
1849
1850 if (!qede->params.link_state) {
1851 goto exit;
1852 }
1853
1854 while (mp != NULL) {
1855 #ifdef NO_CROSSBOW
1856 /*
1857 * Figure out which tx ring to send this packet to.
1858 * Currently multiple rings are not exposed to mac layer
1859 * and fanout done by driver
1860 */
1861 bp = (caddr_t)mp->b_rptr;
1862 ring_id = qede_hash_get_txq(qede, bp);
1863 fp = &qede->fp_array[ring_id];
1864 tx_ring = fp->tx_ring[0];
1865
1866 if (qede->num_tc > 1) {
1867 qede_info(qede,
1868 "Traffic classes(%d) > 1 not supported",
1869 qede->num_tc);
1870 goto exit;
1871 }
1872 #endif
1873 next = mp->b_next;
1874 mp->b_next = NULL;
1875
1876 status = qede_send_tx_packet(qede, tx_ring, mp);
1877 if (status == XMIT_DONE) {
1878 tx_ring->tx_pkt_count++;
1879 mp = next;
1880 } else if (status == XMIT_PAUSE_QUEUE) {
1881 tx_ring->tx_ring_pause++;
1882 mp->b_next = next;
1883 break;
1884 } else if (status == XMIT_FAILED) {
1885 goto exit;
1886 }
1887 }
1888
1889 return (mp);
1890 exit:
1891 tx_ring->tx_pkt_dropped++;
1892 freemsgchain(mp);
1893 mp = NULL;
1894 return (mp);
1895 }
1896