4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
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]
21 * Copyright (c) 2002-2006 Neterion, Inc.
25 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
30 #include "xgehal-device.h"
33 #include "xgehal-ring.h"
34 #include "xgehal-fifo.h"
37 * xge_hal_device_bar0 - Get BAR0 mapped address.
38 * @hldev: HAL device handle.
40 * Returns: BAR0 address of the specified device.
42 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
char *
43 xge_hal_device_bar0(xge_hal_device_t
*hldev
)
49 * xge_hal_device_isrbar0 - Get BAR0 mapped address.
50 * @hldev: HAL device handle.
52 * Returns: BAR0 address of the specified device.
54 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
char *
55 xge_hal_device_isrbar0(xge_hal_device_t
*hldev
)
57 return hldev
->isrbar0
;
61 * xge_hal_device_bar1 - Get BAR1 mapped address.
62 * @hldev: HAL device handle.
64 * Returns: BAR1 address of the specified device.
66 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
char *
67 xge_hal_device_bar1(xge_hal_device_t
*hldev
)
73 * xge_hal_device_bar0_set - Set BAR0 mapped address.
74 * @hldev: HAL device handle.
75 * @bar0: BAR0 mapped address.
76 * * Set BAR0 address in the HAL device object.
78 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
79 xge_hal_device_bar0_set(xge_hal_device_t
*hldev
, char *bar0
)
86 * xge_hal_device_isrbar0_set - Set BAR0 mapped address.
87 * @hldev: HAL device handle.
88 * @isrbar0: BAR0 mapped address.
89 * * Set BAR0 address in the HAL device object.
91 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
92 xge_hal_device_isrbar0_set(xge_hal_device_t
*hldev
, char *isrbar0
)
95 hldev
->isrbar0
= isrbar0
;
99 * xge_hal_device_bar1_set - Set BAR1 mapped address.
100 * @hldev: HAL device handle.
101 * @channelh: Channel handle.
102 * @bar1: BAR1 mapped address.
104 * Set BAR1 address for the given channel.
106 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
107 xge_hal_device_bar1_set(xge_hal_device_t
*hldev
, xge_hal_channel_h channelh
,
110 xge_hal_fifo_t
*fifo
= (xge_hal_fifo_t
*)channelh
;
115 /* Initializing the BAR1 address as the start of
116 * the FIFO queue pointer and as a location of FIFO control
119 (xge_hal_fifo_hw_pair_t
*) (bar1
+
120 (fifo
->channel
.post_qid
* XGE_HAL_FIFO_HW_PAIR_OFFSET
));
126 * xge_hal_device_rev - Get Device revision number.
127 * @hldev: HAL device handle.
129 * Returns: Device revision number
131 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
int
132 xge_hal_device_rev(xge_hal_device_t
*hldev
)
134 return hldev
->revision
;
139 * xge_hal_device_begin_irq - Begin IRQ processing.
140 * @hldev: HAL device handle.
141 * @reason: "Reason" for the interrupt, the value of Xframe's
142 * general_int_status register.
144 * The function performs two actions, It first checks whether (shared IRQ) the
145 * interrupt was raised by the device. Next, it masks the device interrupts.
148 * xge_hal_device_begin_irq() does not flush MMIO writes through the
149 * bridge. Therefore, two back-to-back interrupts are potentially possible.
150 * It is the responsibility of the ULD to make sure that only one
151 * xge_hal_device_continue_irq() runs at a time.
153 * Returns: 0, if the interrupt is not "ours" (note that in this case the
154 * device remain enabled).
155 * Otherwise, xge_hal_device_begin_irq() returns 64bit general adapter
157 * See also: xge_hal_device_handle_irq()
159 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE xge_hal_status_e
160 xge_hal_device_begin_irq(xge_hal_device_t
*hldev
, u64
*reason
)
163 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
165 hldev
->stats
.sw_dev_info_stats
.total_intr_cnt
++;
167 val64
= xge_os_pio_mem_read64(hldev
->pdev
,
168 hldev
->regh0
, &isrbar0
->general_int_status
);
169 if (xge_os_unlikely(!val64
)) {
170 /* not Xframe interrupt */
171 hldev
->stats
.sw_dev_info_stats
.not_xge_intr_cnt
++;
173 return XGE_HAL_ERR_WRONG_IRQ
;
176 if (xge_os_unlikely(val64
== XGE_HAL_ALL_FOXES
)) {
178 xge_os_pio_mem_read64(hldev
->pdev
, hldev
->regh0
,
179 &isrbar0
->adapter_status
);
180 if (adapter_status
== XGE_HAL_ALL_FOXES
) {
181 (void) xge_queue_produce(hldev
->queueh
,
182 XGE_HAL_EVENT_SLOT_FREEZE
,
184 1, /* critical: slot freeze */
186 (void*)&adapter_status
);
188 return XGE_HAL_ERR_CRITICAL
;
194 /* separate fast path, i.e. no errors */
195 if (val64
& XGE_HAL_GEN_INTR_RXTRAFFIC
) {
196 hldev
->stats
.sw_dev_info_stats
.rx_traffic_intr_cnt
++;
199 if (val64
& XGE_HAL_GEN_INTR_TXTRAFFIC
) {
200 hldev
->stats
.sw_dev_info_stats
.tx_traffic_intr_cnt
++;
204 hldev
->stats
.sw_dev_info_stats
.not_traffic_intr_cnt
++;
205 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_TXPIC
)) {
206 xge_hal_status_e status
;
207 hldev
->stats
.sw_dev_info_stats
.txpic_intr_cnt
++;
208 status
= __hal_device_handle_txpic(hldev
, val64
);
209 if (status
!= XGE_HAL_OK
) {
214 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_TXDMA
)) {
215 xge_hal_status_e status
;
216 hldev
->stats
.sw_dev_info_stats
.txdma_intr_cnt
++;
217 status
= __hal_device_handle_txdma(hldev
, val64
);
218 if (status
!= XGE_HAL_OK
) {
223 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_TXMAC
)) {
224 xge_hal_status_e status
;
225 hldev
->stats
.sw_dev_info_stats
.txmac_intr_cnt
++;
226 status
= __hal_device_handle_txmac(hldev
, val64
);
227 if (status
!= XGE_HAL_OK
) {
232 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_TXXGXS
)) {
233 xge_hal_status_e status
;
234 hldev
->stats
.sw_dev_info_stats
.txxgxs_intr_cnt
++;
235 status
= __hal_device_handle_txxgxs(hldev
, val64
);
236 if (status
!= XGE_HAL_OK
) {
241 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_RXPIC
)) {
242 xge_hal_status_e status
;
243 hldev
->stats
.sw_dev_info_stats
.rxpic_intr_cnt
++;
244 status
= __hal_device_handle_rxpic(hldev
, val64
);
245 if (status
!= XGE_HAL_OK
) {
250 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_RXDMA
)) {
251 xge_hal_status_e status
;
252 hldev
->stats
.sw_dev_info_stats
.rxdma_intr_cnt
++;
253 status
= __hal_device_handle_rxdma(hldev
, val64
);
254 if (status
!= XGE_HAL_OK
) {
259 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_RXMAC
)) {
260 xge_hal_status_e status
;
261 hldev
->stats
.sw_dev_info_stats
.rxmac_intr_cnt
++;
262 status
= __hal_device_handle_rxmac(hldev
, val64
);
263 if (status
!= XGE_HAL_OK
) {
268 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_RXXGXS
)) {
269 xge_hal_status_e status
;
270 hldev
->stats
.sw_dev_info_stats
.rxxgxs_intr_cnt
++;
271 status
= __hal_device_handle_rxxgxs(hldev
, val64
);
272 if (status
!= XGE_HAL_OK
) {
277 if (xge_os_unlikely(val64
& XGE_HAL_GEN_INTR_MC
)) {
278 xge_hal_status_e status
;
279 hldev
->stats
.sw_dev_info_stats
.mc_intr_cnt
++;
280 status
= __hal_device_handle_mc(hldev
, val64
);
281 if (status
!= XGE_HAL_OK
) {
290 * xge_hal_device_clear_rx - Acknowledge (that is, clear) the
291 * condition that has caused the RX interrupt.
292 * @hldev: HAL device handle.
294 * Acknowledge (that is, clear) the condition that has caused
296 * See also: xge_hal_device_begin_irq(), xge_hal_device_continue_irq(),
297 * xge_hal_device_clear_tx(), xge_hal_device_mask_rx().
299 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
300 xge_hal_device_clear_rx(xge_hal_device_t
*hldev
)
302 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
304 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
305 0xFFFFFFFFFFFFFFFFULL
,
306 &isrbar0
->rx_traffic_int
);
310 * xge_hal_device_clear_tx - Acknowledge (that is, clear) the
311 * condition that has caused the TX interrupt.
312 * @hldev: HAL device handle.
314 * Acknowledge (that is, clear) the condition that has caused
316 * See also: xge_hal_device_begin_irq(), xge_hal_device_continue_irq(),
317 * xge_hal_device_clear_rx(), xge_hal_device_mask_tx().
319 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
320 xge_hal_device_clear_tx(xge_hal_device_t
*hldev
)
322 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
324 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
325 0xFFFFFFFFFFFFFFFFULL
,
326 &isrbar0
->tx_traffic_int
);
330 * xge_hal_device_poll_rx_channel - Poll Rx channel for completed
331 * descriptors and process the same.
332 * @channel: HAL channel.
333 * @got_rx: Buffer to return the flag set if receive interrupt is occured
335 * The function polls the Rx channel for the completed descriptors and calls
336 * the upper-layer driver (ULD) via supplied completion callback.
338 * Returns: XGE_HAL_OK, if the polling is completed successful.
339 * XGE_HAL_COMPLETIONS_REMAIN: There are still more completed
340 * descriptors available which are yet to be processed.
342 * See also: xge_hal_device_poll_tx_channel()
344 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE xge_hal_status_e
345 xge_hal_device_poll_rx_channel(xge_hal_channel_t
*channel
, int *got_rx
)
347 xge_hal_status_e ret
= XGE_HAL_OK
;
348 xge_hal_dtr_h first_dtrh
;
349 xge_hal_device_t
*hldev
= (xge_hal_device_t
*)channel
->devh
;
353 /* for each opened rx channel */
354 got_bytes
= *got_rx
= 0;
355 ((xge_hal_ring_t
*)channel
)->cmpl_cnt
= 0;
356 channel
->poll_bytes
= 0;
357 if ((ret
= xge_hal_ring_dtr_next_completed (channel
, &first_dtrh
,
358 &t_code
)) == XGE_HAL_OK
) {
359 if (channel
->callback(channel
, first_dtrh
,
360 t_code
, channel
->userdata
) != XGE_HAL_OK
) {
361 (*got_rx
) += ((xge_hal_ring_t
*)channel
)->cmpl_cnt
+ 1;
362 got_bytes
+= channel
->poll_bytes
+ 1;
363 ret
= XGE_HAL_COMPLETIONS_REMAIN
;
365 (*got_rx
) += ((xge_hal_ring_t
*)channel
)->cmpl_cnt
+ 1;
366 got_bytes
+= channel
->poll_bytes
+ 1;
371 hldev
->irq_workload_rxd
[channel
->post_qid
] += *got_rx
;
372 hldev
->irq_workload_rxcnt
[channel
->post_qid
] ++;
374 hldev
->irq_workload_rxlen
[channel
->post_qid
] += got_bytes
;
380 * xge_hal_device_poll_tx_channel - Poll Tx channel for completed
381 * descriptors and process the same.
382 * @channel: HAL channel.
383 * @got_tx: Buffer to return the flag set if transmit interrupt is occured
385 * The function polls the Tx channel for the completed descriptors and calls
386 * the upper-layer driver (ULD) via supplied completion callback.
388 * Returns: XGE_HAL_OK, if the polling is completed successful.
389 * XGE_HAL_COMPLETIONS_REMAIN: There are still more completed
390 * descriptors available which are yet to be processed.
392 * See also: xge_hal_device_poll_rx_channel().
394 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE xge_hal_status_e
395 xge_hal_device_poll_tx_channel(xge_hal_channel_t
*channel
, int *got_tx
)
397 xge_hal_dtr_h first_dtrh
;
398 xge_hal_device_t
*hldev
= (xge_hal_device_t
*)channel
->devh
;
402 /* for each opened tx channel */
403 got_bytes
= *got_tx
= 0;
404 channel
->poll_bytes
= 0;
405 if (xge_hal_fifo_dtr_next_completed (channel
, &first_dtrh
,
406 &t_code
) == XGE_HAL_OK
) {
407 if (channel
->callback(channel
, first_dtrh
,
408 t_code
, channel
->userdata
) != XGE_HAL_OK
) {
410 got_bytes
+= channel
->poll_bytes
+ 1;
411 return XGE_HAL_COMPLETIONS_REMAIN
;
414 got_bytes
+= channel
->poll_bytes
+ 1;
418 hldev
->irq_workload_txd
[channel
->post_qid
] += *got_tx
;
419 hldev
->irq_workload_txcnt
[channel
->post_qid
] ++;
421 hldev
->irq_workload_txlen
[channel
->post_qid
] += got_bytes
;
427 * xge_hal_device_poll_rx_channels - Poll Rx channels for completed
428 * descriptors and process the same.
429 * @hldev: HAL device handle.
430 * @got_rx: Buffer to return flag set if receive is ready
432 * The function polls the Rx channels for the completed descriptors and calls
433 * the upper-layer driver (ULD) via supplied completion callback.
435 * Returns: XGE_HAL_OK, if the polling is completed successful.
436 * XGE_HAL_COMPLETIONS_REMAIN: There are still more completed
437 * descriptors available which are yet to be processed.
439 * See also: xge_hal_device_poll_tx_channels(), xge_hal_device_continue_irq().
441 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE xge_hal_status_e
442 xge_hal_device_poll_rx_channels(xge_hal_device_t
*hldev
, int *got_rx
)
445 xge_hal_channel_t
*channel
;
447 /* for each opened rx channel */
448 xge_list_for_each(item
, &hldev
->ring_channels
) {
449 if (hldev
->terminating
)
451 channel
= xge_container_of(item
, xge_hal_channel_t
, item
);
452 if (!(channel
->flags
& XGE_HAL_CHANNEL_FLAG_USE_RX_POLLING
)) {
453 (void) xge_hal_device_poll_rx_channel(channel
, got_rx
);
461 * xge_hal_device_poll_tx_channels - Poll Tx channels for completed
462 * descriptors and process the same.
463 * @hldev: HAL device handle.
464 * @got_tx: Buffer to return flag set if transmit is ready
466 * The function polls the Tx channels for the completed descriptors and calls
467 * the upper-layer driver (ULD) via supplied completion callback.
469 * Returns: XGE_HAL_OK, if the polling is completed successful.
470 * XGE_HAL_COMPLETIONS_REMAIN: There are still more completed
471 * descriptors available which are yet to be processed.
473 * See also: xge_hal_device_poll_rx_channels(), xge_hal_device_continue_irq().
475 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE xge_hal_status_e
476 xge_hal_device_poll_tx_channels(xge_hal_device_t
*hldev
, int *got_tx
)
479 xge_hal_channel_t
*channel
;
481 /* for each opened tx channel */
482 xge_list_for_each(item
, &hldev
->fifo_channels
) {
483 if (hldev
->terminating
)
485 channel
= xge_container_of(item
, xge_hal_channel_t
, item
);
486 (void) xge_hal_device_poll_tx_channel(channel
, got_tx
);
495 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
496 xge_hal_device_rx_channel_enable_polling(xge_hal_channel_t
*channel
)
498 channel
->flags
|= XGE_HAL_CHANNEL_FLAG_USE_RX_POLLING
;
501 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
502 xge_hal_device_rx_channel_disable_polling(xge_hal_channel_t
*channel
)
504 channel
->flags
&= ~XGE_HAL_CHANNEL_FLAG_USE_RX_POLLING
;
508 * xge_hal_device_mask_tx - Mask Tx interrupts.
509 * @hldev: HAL device handle.
511 * Mask Tx device interrupts.
513 * See also: xge_hal_device_unmask_tx(), xge_hal_device_mask_rx(),
514 * xge_hal_device_clear_tx().
516 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
517 xge_hal_device_mask_tx(xge_hal_device_t
*hldev
)
519 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
521 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
522 0xFFFFFFFFFFFFFFFFULL
,
523 &isrbar0
->tx_traffic_mask
);
527 * xge_hal_device_mask_rx - Mask Rx interrupts.
528 * @hldev: HAL device handle.
530 * Mask Rx device interrupts.
532 * See also: xge_hal_device_unmask_rx(), xge_hal_device_mask_tx(),
533 * xge_hal_device_clear_rx().
535 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
536 xge_hal_device_mask_rx(xge_hal_device_t
*hldev
)
538 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
540 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
541 0xFFFFFFFFFFFFFFFFULL
,
542 &isrbar0
->rx_traffic_mask
);
546 * xge_hal_device_mask_all - Mask all device interrupts.
547 * @hldev: HAL device handle.
549 * Mask all device interrupts.
551 * See also: xge_hal_device_unmask_all()
553 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
554 xge_hal_device_mask_all(xge_hal_device_t
*hldev
)
556 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
558 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
559 0xFFFFFFFFFFFFFFFFULL
,
560 &isrbar0
->general_int_mask
);
564 * xge_hal_device_unmask_tx - Unmask Tx interrupts.
565 * @hldev: HAL device handle.
567 * Unmask Tx device interrupts.
569 * See also: xge_hal_device_mask_tx(), xge_hal_device_clear_tx().
571 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
572 xge_hal_device_unmask_tx(xge_hal_device_t
*hldev
)
574 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
576 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
578 &isrbar0
->tx_traffic_mask
);
582 * xge_hal_device_unmask_rx - Unmask Rx interrupts.
583 * @hldev: HAL device handle.
585 * Unmask Rx device interrupts.
587 * See also: xge_hal_device_mask_rx(), xge_hal_device_clear_rx().
589 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
590 xge_hal_device_unmask_rx(xge_hal_device_t
*hldev
)
592 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
594 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
596 &isrbar0
->rx_traffic_mask
);
600 * xge_hal_device_unmask_all - Unmask all device interrupts.
601 * @hldev: HAL device handle.
603 * Unmask all device interrupts.
605 * See also: xge_hal_device_mask_all()
607 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE
void
608 xge_hal_device_unmask_all(xge_hal_device_t
*hldev
)
610 xge_hal_pci_bar0_t
*isrbar0
= (xge_hal_pci_bar0_t
*)hldev
->isrbar0
;
612 xge_os_pio_mem_write64(hldev
->pdev
, hldev
->regh0
,
614 &isrbar0
->general_int_mask
);
619 * xge_hal_device_continue_irq - Continue handling IRQ: process all
620 * completed descriptors.
621 * @hldev: HAL device handle.
623 * Process completed descriptors and unmask the device interrupts.
625 * The xge_hal_device_continue_irq() walks all open channels
626 * and calls upper-layer driver (ULD) via supplied completion
627 * callback. Note that the completion callback is specified at channel open
628 * time, see xge_hal_channel_open().
630 * Note that the xge_hal_device_continue_irq is part of the _fast_ path.
631 * To optimize the processing, the function does _not_ check for
634 * The latter is done in a polling fashion, via xge_hal_device_poll().
636 * Returns: XGE_HAL_OK.
638 * See also: xge_hal_device_handle_irq(), xge_hal_device_poll(),
639 * xge_hal_ring_dtr_next_completed(),
640 * xge_hal_fifo_dtr_next_completed(), xge_hal_channel_callback_f{}.
642 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE xge_hal_status_e
643 xge_hal_device_continue_irq(xge_hal_device_t
*hldev
)
645 int got_rx
= 1, got_tx
= 1;
646 int isr_polling_cnt
= hldev
->config
.isr_polling_cnt
;
652 (void) xge_hal_device_poll_rx_channels(hldev
, &got_rx
);
653 if (got_tx
&& hldev
->tti_enabled
)
654 (void) xge_hal_device_poll_tx_channels(hldev
, &got_tx
);
656 if (!got_rx
&& !got_tx
)
659 count
+= (got_rx
+ got_tx
);
660 }while (isr_polling_cnt
--);
663 hldev
->stats
.sw_dev_info_stats
.not_traffic_intr_cnt
++;
669 * xge_hal_device_handle_irq - Handle device IRQ.
670 * @hldev: HAL device handle.
672 * Perform the complete handling of the line interrupt. The function
673 * performs two calls.
674 * First it uses xge_hal_device_begin_irq() to check the reason for
675 * the interrupt and mask the device interrupts.
676 * Second, it calls xge_hal_device_continue_irq() to process all
677 * completed descriptors and re-enable the interrupts.
679 * Returns: XGE_HAL_OK - success;
680 * XGE_HAL_ERR_WRONG_IRQ - (shared) IRQ produced by other device.
682 * See also: xge_hal_device_begin_irq(), xge_hal_device_continue_irq().
684 __HAL_STATIC_DEVICE __HAL_INLINE_DEVICE xge_hal_status_e
685 xge_hal_device_handle_irq(xge_hal_device_t
*hldev
)
688 xge_hal_status_e status
;
690 xge_hal_device_mask_all(hldev
);
692 status
= xge_hal_device_begin_irq(hldev
, &reason
);
693 if (status
!= XGE_HAL_OK
) {
694 xge_hal_device_unmask_all(hldev
);
698 if (reason
& XGE_HAL_GEN_INTR_RXTRAFFIC
) {
699 xge_hal_device_clear_rx(hldev
);
702 status
= xge_hal_device_continue_irq(hldev
);
704 xge_hal_device_clear_tx(hldev
);
706 xge_hal_device_unmask_all(hldev
);
711 #if defined(XGE_HAL_CONFIG_LRO)
714 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL
int
715 __hal_lro_check_for_session_match(lro_t
*lro
, tcplro_t
*tcp
, iplro_t
*ip
)
718 /* Match Source address field */
719 if ((lro
->ip_hdr
->saddr
!= ip
->saddr
))
722 /* Match Destination address field */
723 if ((lro
->ip_hdr
->daddr
!= ip
->daddr
))
726 /* Match Source Port field */
727 if ((lro
->tcp_hdr
->source
!= tcp
->source
))
730 /* Match Destination Port field */
731 if ((lro
->tcp_hdr
->dest
!= tcp
->dest
))
738 * __hal_tcp_seg_len: Find the tcp seg len.
741 * returns: Tcp seg length.
743 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL u16
744 __hal_tcp_seg_len(iplro_t
*ip
, tcplro_t
*tcp
)
748 ret
= (xge_os_ntohs(ip
->tot_len
) -
749 ((ip
->version_ihl
& 0x0F)<<2) -
750 ((tcp
->doff_res
)>>2));
755 * __hal_ip_lro_capable: Finds whether ip is lro capable.
757 * @ext_info: descriptor info.
759 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
760 __hal_ip_lro_capable(iplro_t
*ip
,
761 xge_hal_dtr_info_t
*ext_info
)
764 #ifdef XGE_LL_DEBUG_DUMP_PKT
767 u8 ch
, *iph
= (u8
*)ip
;
769 xge_debug_ring(XGE_TRACE
, "Dump Ip:" );
770 for (i
=0; i
< 40; i
++) {
771 ch
= ntohs(*((u8
*)(iph
+ i
)) );
772 printf("i:%d %02x, ",i
,ch
);
777 if (ip
->version_ihl
!= IP_FAST_PATH_HDR_MASK
) {
778 xge_debug_ring(XGE_ERR
, "iphdr !=45 :%d",ip
->version_ihl
);
782 if (ext_info
->proto
& XGE_HAL_FRAME_PROTO_IP_FRAGMENTED
) {
783 xge_debug_ring(XGE_ERR
, "IP fragmented");
791 * __hal_tcp_lro_capable: Finds whether tcp is lro capable.
795 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
796 __hal_tcp_lro_capable(iplro_t
*ip
, tcplro_t
*tcp
, lro_t
*lro
, int *ts_off
)
798 #ifdef XGE_LL_DEBUG_DUMP_PKT
803 xge_debug_ring(XGE_TRACE
, "Dump Tcp:" );
804 for (i
=0; i
< 20; i
++) {
805 ch
= ntohs(*((u8
*)((u8
*)tcp
+ i
)) );
806 xge_os_printf("i:%d %02x, ",i
,ch
);
810 if ((TCP_FAST_PATH_HDR_MASK2
!= tcp
->ctrl
) &&
811 (TCP_FAST_PATH_HDR_MASK3
!= tcp
->ctrl
))
815 if (TCP_FAST_PATH_HDR_MASK1
!= tcp
->doff_res
) {
816 u16 tcp_hdr_len
= tcp
->doff_res
>> 2; /* TCP header len */
817 u16 off
= 20; /* Start of tcp options */
820 /* Does Packet can contain time stamp */
821 if (tcp_hdr_len
< 32) {
823 * If the session is not opened, we can consider
824 * this packet for LRO
832 /* Ignore No-operation 0x1 */
833 while (((u8
*)tcp
)[off
] == 0x1)
836 /* Next option == Timestamp */
837 if (((u8
*)tcp
)[off
] != 0x8) {
839 * If the session ie not opened, we can consider
840 * this packet for LRO
853 * Now the session is opened. If the LRO frame doesn't
854 * have time stamp, we cannot consider current packet for
857 if (lro
->ts_off
== -1) {
858 xge_debug_ring(XGE_ERR
, "Pkt received with time stamp after session opened with no time stamp : %02x %02x", tcp
->doff_res
, tcp
->ctrl
);
863 * If the difference is greater than three, then there are
864 * more options possible.
865 * else, there are two cases:
866 * case 1: remaining are padding bytes.
867 * case 2: remaining can contain options or padding
869 off
+= ((u8
*)tcp
)[off
+1];
870 diff
= tcp_hdr_len
- off
;
873 * Probably contains more options.
875 xge_debug_ring(XGE_ERR
, "tcphdr not fastpth : pkt received with tcp options in addition to time stamp after the session is opened %02x %02x ", tcp
->doff_res
, tcp
->ctrl
);
879 for (i
= 0; i
< diff
; i
++) {
880 u8 byte
= ((u8
*)tcp
)[off
+i
];
882 /* Ignore No-operation 0x1 */
883 if ((byte
== 0x0) || (byte
== 0x1))
885 xge_debug_ring(XGE_ERR
, "tcphdr not fastpth : pkt received with tcp options in addition to time stamp after the session is opened %02x %02x ", tcp
->doff_res
, tcp
->ctrl
);
890 * Update the time stamp of LRO frame.
892 xge_os_memcpy(((char *)lro
->tcp_hdr
+ lro
->ts_off
+ 2),
893 (char *)((char *)tcp
+ (*ts_off
) + 2), 8);
899 xge_debug_ring(XGE_TRACE
, "tcphdr not fastpth %02x %02x", tcp
->doff_res
, tcp
->ctrl
);
905 * __hal_lro_capable: Finds whether frame is lro capable.
906 * @buffer: Ethernet frame.
909 * @ext_info: Descriptor info.
911 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
912 __hal_lro_capable( u8
*buffer
,
915 xge_hal_dtr_info_t
*ext_info
)
917 u8 ip_off
, ip_length
;
919 if (!(ext_info
->proto
& XGE_HAL_FRAME_PROTO_TCP
)) {
920 xge_debug_ring(XGE_ERR
, "Cant do lro %d", ext_info
->proto
);
926 #ifdef XGE_LL_DEBUG_DUMP_PKT
931 xge_os_printf("Dump Eth:" );
932 for (i
=0; i
< 60; i
++) {
933 ch
= ntohs(*((u8
*)(buffer
+ i
)) );
934 xge_os_printf("i:%d %02x, ",i
,ch
);
939 switch (ext_info
->frame
) {
940 case XGE_HAL_FRAME_TYPE_DIX
:
941 ip_off
= XGE_HAL_HEADER_ETHERNET_II_802_3_SIZE
;
943 case XGE_HAL_FRAME_TYPE_LLC
:
944 ip_off
= (XGE_HAL_HEADER_ETHERNET_II_802_3_SIZE
+
945 XGE_HAL_HEADER_802_2_SIZE
);
947 case XGE_HAL_FRAME_TYPE_SNAP
:
948 ip_off
= (XGE_HAL_HEADER_ETHERNET_II_802_3_SIZE
+
949 XGE_HAL_HEADER_SNAP_SIZE
);
951 default: // XGE_HAL_FRAME_TYPE_IPX, etc.
956 if (ext_info
->proto
& XGE_HAL_FRAME_PROTO_VLAN_TAGGED
) {
957 ip_off
+= XGE_HAL_HEADER_VLAN_SIZE
;
960 /* Grab ip, tcp headers */
961 *ip
= (iplro_t
*)((char*)buffer
+ ip_off
);
964 ip_length
= (u8
)((*ip
)->version_ihl
& 0x0F);
965 ip_length
= ip_length
<<2;
966 *tcp
= (tcplro_t
*)((char *)*ip
+ ip_length
);
968 xge_debug_ring(XGE_TRACE
, "ip_length:%d ip:"XGE_OS_LLXFMT
969 " tcp:"XGE_OS_LLXFMT
"", (int)ip_length
,
970 (unsigned long long)(ulong_t
)*ip
, (unsigned long long)(ulong_t
)*tcp
);
978 * __hal_open_lro_session: Open a new LRO session.
979 * @buffer: Ethernet frame.
983 * @ext_info: Descriptor info.
984 * @hldev: Hal context.
985 * @ring_lro: LRO descriptor per rx ring.
987 * @tcp_seg_len: Length of tcp segment.
988 * @ts_off: time stamp offset in the packet.
990 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL
void
991 __hal_open_lro_session (u8
*buffer
, iplro_t
*ip
, tcplro_t
*tcp
, lro_t
**lro
,
992 xge_hal_device_t
*hldev
, xge_hal_lro_desc_t
*ring_lro
, int slot
,
993 u32 tcp_seg_len
, int ts_off
)
996 lro_t
*lro_new
= &ring_lro
->lro_pool
[slot
];
999 lro_new
->ll_hdr
= buffer
;
1000 lro_new
->ip_hdr
= ip
;
1001 lro_new
->tcp_hdr
= tcp
;
1002 lro_new
->tcp_next_seq_num
= tcp_seg_len
+ xge_os_ntohl(
1004 lro_new
->tcp_seq_num
= tcp
->seq
;
1005 lro_new
->tcp_ack_num
= tcp
->ack_seq
;
1006 lro_new
->sg_num
= 1;
1007 lro_new
->total_length
= xge_os_ntohs(ip
->tot_len
);
1008 lro_new
->frags_len
= 0;
1009 lro_new
->ts_off
= ts_off
;
1011 hldev
->stats
.sw_dev_info_stats
.tot_frms_lroised
++;
1012 hldev
->stats
.sw_dev_info_stats
.tot_lro_sessions
++;
1014 *lro
= ring_lro
->lro_recent
= lro_new
;
1018 * __hal_lro_get_free_slot: Get a free LRO bucket.
1019 * @ring_lro: LRO descriptor per ring.
1021 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL
int
1022 __hal_lro_get_free_slot (xge_hal_lro_desc_t
*ring_lro
)
1026 for (i
= 0; i
< XGE_HAL_LRO_MAX_BUCKETS
; i
++) {
1027 lro_t
*lro_temp
= &ring_lro
->lro_pool
[i
];
1029 if (!lro_temp
->in_use
)
1036 * __hal_get_lro_session: Gets matching LRO session or creates one.
1037 * @eth_hdr: Ethernet header.
1041 * @ext_info: Descriptor info.
1042 * @hldev: Hal context.
1043 * @ring_lro: LRO descriptor per rx ring
1045 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
1046 __hal_get_lro_session (u8
*eth_hdr
,
1050 xge_hal_dtr_info_t
*ext_info
,
1051 xge_hal_device_t
*hldev
,
1052 xge_hal_lro_desc_t
*ring_lro
,
1053 lro_t
**lro_end3
/* Valid only when ret=END_3 */)
1056 int i
, free_slot
= -1;
1060 *lro
= lro_match
= NULL
;
1062 * Compare the incoming frame with the lro session left from the
1063 * previous call. There is a good chance that this incoming frame
1064 * matches the lro session.
1066 if (ring_lro
->lro_recent
&& ring_lro
->lro_recent
->in_use
) {
1067 if (__hal_lro_check_for_session_match(ring_lro
->lro_recent
,
1070 lro_match
= ring_lro
->lro_recent
;
1075 * Search in the pool of LROs for the session that matches
1076 * the incoming frame.
1078 for (i
= 0; i
< XGE_HAL_LRO_MAX_BUCKETS
; i
++) {
1079 lro_t
*lro_temp
= &ring_lro
->lro_pool
[i
];
1081 if (!lro_temp
->in_use
) {
1082 if (free_slot
== -1)
1087 if (__hal_lro_check_for_session_match(lro_temp
, tcp
,
1088 ip
) == XGE_HAL_OK
) {
1089 lro_match
= lro_temp
;
1098 * Matching LRO Session found
1102 if (lro_match
->tcp_next_seq_num
!= xge_os_ntohl(tcp
->seq
)) {
1103 xge_debug_ring(XGE_ERR
, "**retransmit **"
1105 hldev
->stats
.sw_dev_info_stats
.lro_out_of_seq_pkt_cnt
++;
1106 return XGE_HAL_INF_LRO_END_2
;
1109 if (XGE_HAL_OK
!= __hal_ip_lro_capable(ip
, ext_info
))
1111 return XGE_HAL_INF_LRO_END_2
;
1114 if (XGE_HAL_OK
!= __hal_tcp_lro_capable(ip
, tcp
, lro_match
,
1117 * Close the current session and open a new
1118 * LRO session with this packet,
1119 * provided it has tcp payload
1121 tcp_seg_len
= __hal_tcp_seg_len(ip
, tcp
);
1122 if (tcp_seg_len
== 0)
1124 return XGE_HAL_INF_LRO_END_2
;
1127 /* Get a free bucket */
1128 free_slot
= __hal_lro_get_free_slot(ring_lro
);
1129 if (free_slot
== -1)
1131 return XGE_HAL_INF_LRO_END_2
;
1135 * Open a new LRO session
1137 __hal_open_lro_session (eth_hdr
, ip
, tcp
, lro_end3
,
1138 hldev
, ring_lro
, free_slot
, tcp_seg_len
,
1141 return XGE_HAL_INF_LRO_END_3
;
1145 * The frame is good, in-sequence, can be LRO-ed;
1146 * take its (latest) ACK - unless it is a dupack.
1147 * Note: to be exact need to check window size as well..
1149 if (lro_match
->tcp_ack_num
== tcp
->ack_seq
&&
1150 lro_match
->tcp_seq_num
== tcp
->seq
) {
1151 hldev
->stats
.sw_dev_info_stats
.lro_dup_pkt_cnt
++;
1152 return XGE_HAL_INF_LRO_END_2
;
1155 lro_match
->tcp_seq_num
= tcp
->seq
;
1156 lro_match
->tcp_ack_num
= tcp
->ack_seq
;
1157 lro_match
->frags_len
+= __hal_tcp_seg_len(ip
, tcp
);
1159 ring_lro
->lro_recent
= lro_match
;
1161 return XGE_HAL_INF_LRO_CONT
;
1164 /* ********** New Session ***************/
1165 if (free_slot
== -1)
1166 return XGE_HAL_INF_LRO_UNCAPABLE
;
1168 if (XGE_HAL_FAIL
== __hal_ip_lro_capable(ip
, ext_info
))
1169 return XGE_HAL_INF_LRO_UNCAPABLE
;
1171 if (XGE_HAL_FAIL
== __hal_tcp_lro_capable(ip
, tcp
, NULL
, &ts_off
))
1172 return XGE_HAL_INF_LRO_UNCAPABLE
;
1174 xge_debug_ring(XGE_TRACE
, "Creating lro session.");
1177 * Open a LRO session, provided the packet contains payload.
1179 tcp_seg_len
= __hal_tcp_seg_len(ip
, tcp
);
1180 if (tcp_seg_len
== 0)
1181 return XGE_HAL_INF_LRO_UNCAPABLE
;
1183 __hal_open_lro_session (eth_hdr
, ip
, tcp
, lro
, hldev
, ring_lro
, free_slot
,
1184 tcp_seg_len
, ts_off
);
1186 return XGE_HAL_INF_LRO_BEGIN
;
1190 * __hal_lro_under_optimal_thresh: Finds whether combined session is optimal.
1194 * @hldev: Hal context.
1196 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
1197 __hal_lro_under_optimal_thresh (iplro_t
*ip
,
1200 xge_hal_device_t
*hldev
)
1202 if (!lro
) return XGE_HAL_FAIL
;
1204 if ((lro
->total_length
+ __hal_tcp_seg_len(ip
, tcp
) ) >
1205 hldev
->config
.lro_frm_len
) {
1206 xge_debug_ring(XGE_TRACE
, "Max LRO frame len exceeded:"
1207 "max length %d ", hldev
->config
.lro_frm_len
);
1208 hldev
->stats
.sw_dev_info_stats
.lro_frm_len_exceed_cnt
++;
1209 return XGE_HAL_FAIL
;
1212 if (lro
->sg_num
== hldev
->config
.lro_sg_size
) {
1213 xge_debug_ring(XGE_TRACE
, "Max sg count exceeded:"
1214 "max sg %d ", hldev
->config
.lro_sg_size
);
1215 hldev
->stats
.sw_dev_info_stats
.lro_sg_exceed_cnt
++;
1216 return XGE_HAL_FAIL
;
1223 * __hal_collapse_ip_hdr: Collapses ip header.
1227 * @hldev: Hal context.
1229 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
1230 __hal_collapse_ip_hdr ( iplro_t
*ip
,
1233 xge_hal_device_t
*hldev
)
1236 lro
->total_length
+= __hal_tcp_seg_len(ip
, tcp
);
1238 /* May be we have to handle time stamps or more options */
1245 * __hal_collapse_tcp_hdr: Collapses tcp header.
1249 * @hldev: Hal context.
1251 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
1252 __hal_collapse_tcp_hdr ( iplro_t
*ip
,
1255 xge_hal_device_t
*hldev
)
1257 lro
->tcp_next_seq_num
+= __hal_tcp_seg_len(ip
, tcp
);
1263 * __hal_append_lro: Appends new frame to existing LRO session.
1265 * @tcp: IN tcp header, OUT tcp payload.
1266 * @seg_len: tcp payload length.
1268 * @hldev: Hal context.
1270 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
1271 __hal_append_lro(iplro_t
*ip
,
1275 xge_hal_device_t
*hldev
)
1277 (void) __hal_collapse_ip_hdr(ip
, *tcp
, lro
, hldev
);
1278 (void) __hal_collapse_tcp_hdr(ip
, *tcp
, lro
, hldev
);
1279 // Update mbuf chain will be done in ll driver.
1280 // xge_hal_accumulate_large_rx on success of appending new frame to
1281 // lro will return to ll driver tcpdata pointer, and tcp payload length.
1282 // along with return code lro frame appended.
1285 *seg_len
= __hal_tcp_seg_len(ip
, *tcp
);
1286 *tcp
= (tcplro_t
*)((char *)*tcp
+ (((*tcp
)->doff_res
)>>2));
1293 * __xge_hal_accumulate_large_rx: LRO a given frame
1295 * @ring: rx ring number
1296 * @eth_hdr: ethernet header.
1297 * @ip_hdr: ip header (optional)
1299 * @seglen: packet length.
1300 * @p_lro: lro pointer.
1301 * @ext_info: descriptor info, see xge_hal_dtr_info_t{}.
1302 * @hldev: HAL device.
1303 * @lro_end3: for lro_end3 output
1305 * LRO the newly received frame, i.e. attach it (if possible) to the
1306 * already accumulated (i.e., already LRO-ed) received frames (if any),
1307 * to form one super-sized frame for the subsequent processing
1310 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
1311 xge_hal_lro_process_rx(int ring
, u8
*eth_hdr
, u8
*ip_hdr
, tcplro_t
**tcp
,
1312 u32
*seglen
, lro_t
**p_lro
,
1313 xge_hal_dtr_info_t
*ext_info
, xge_hal_device_t
*hldev
,
1316 iplro_t
*ip
= (iplro_t
*)ip_hdr
;
1317 xge_hal_status_e ret
;
1320 xge_debug_ring(XGE_TRACE
, "Entered accumu lro. ");
1321 if (XGE_HAL_OK
!= __hal_lro_capable(eth_hdr
, &ip
, (tcplro_t
**)tcp
,
1323 return XGE_HAL_INF_LRO_UNCAPABLE
;
1326 * This function shall get matching LRO or else
1327 * create one and return it
1329 ret
= __hal_get_lro_session(eth_hdr
, ip
, (tcplro_t
*)*tcp
,
1330 p_lro
, ext_info
, hldev
, &hldev
->lro_desc
[ring
],
1332 xge_debug_ring(XGE_TRACE
, "ret from get_lro:%d ",ret
);
1334 if (XGE_HAL_INF_LRO_CONT
== ret
) {
1335 if (XGE_HAL_OK
== __hal_lro_under_optimal_thresh(ip
,
1336 (tcplro_t
*)*tcp
, lro
, hldev
)) {
1337 (void) __hal_append_lro(ip
,(tcplro_t
**) tcp
, seglen
,
1339 hldev
->stats
.sw_dev_info_stats
.tot_frms_lroised
++;
1341 if (lro
->sg_num
>= hldev
->config
.lro_sg_size
) {
1342 hldev
->stats
.sw_dev_info_stats
.lro_sg_exceed_cnt
++;
1343 ret
= XGE_HAL_INF_LRO_END_1
;
1346 } else ret
= XGE_HAL_INF_LRO_END_2
;
1350 * Since its time to flush,
1351 * update ip header so that it can be sent up
1353 if ((ret
== XGE_HAL_INF_LRO_END_1
) ||
1354 (ret
== XGE_HAL_INF_LRO_END_2
) ||
1355 (ret
== XGE_HAL_INF_LRO_END_3
)) {
1356 lro
->ip_hdr
->tot_len
= xge_os_htons((*p_lro
)->total_length
);
1357 lro
->ip_hdr
->check
= xge_os_htons(0);
1358 lro
->ip_hdr
->check
= XGE_LL_IP_FAST_CSUM(((u8
*)(lro
->ip_hdr
)),
1359 (lro
->ip_hdr
->version_ihl
& 0x0F));
1360 lro
->tcp_hdr
->ack_seq
= lro
->tcp_ack_num
;
1367 * xge_hal_accumulate_large_rx: LRO a given frame
1369 * @buffer: Ethernet frame.
1371 * @seglen: packet length.
1372 * @p_lro: lro pointer.
1373 * @ext_info: descriptor info, see xge_hal_dtr_info_t{}.
1374 * @hldev: HAL device.
1375 * @lro_end3: for lro_end3 output
1377 * LRO the newly received frame, i.e. attach it (if possible) to the
1378 * already accumulated (i.e., already LRO-ed) received frames (if any),
1379 * to form one super-sized frame for the subsequent processing
1382 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
1383 xge_hal_accumulate_large_rx(u8
*buffer
, tcplro_t
**tcp
, u32
*seglen
,
1384 lro_t
**p_lro
, xge_hal_dtr_info_t
*ext_info
, xge_hal_device_t
*hldev
,
1388 return xge_hal_lro_process_rx(ring
, buffer
, NULL
, tcp
, seglen
, p_lro
,
1389 ext_info
, hldev
, lro_end3
);
1393 * xge_hal_lro_close_session: Close LRO session
1394 * @lro: LRO Session.
1395 * @hldev: HAL Context.
1397 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL
void
1398 xge_hal_lro_close_session (lro_t
*lro
)
1404 * xge_hal_lro_next_session: Returns next LRO session in the list or NULL
1406 * @hldev: HAL Context.
1407 * @ring: rx ring number.
1409 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL lro_t
*
1410 xge_hal_lro_next_session (xge_hal_device_t
*hldev
, int ring
)
1412 xge_hal_lro_desc_t
*ring_lro
= &hldev
->lro_desc
[ring
];
1414 int start_idx
= ring_lro
->lro_next_idx
;
1416 for(i
= start_idx
; i
< XGE_HAL_LRO_MAX_BUCKETS
; i
++) {
1417 lro_t
*lro
= &ring_lro
->lro_pool
[i
];
1422 lro
->ip_hdr
->tot_len
= xge_os_htons(lro
->total_length
);
1423 lro
->ip_hdr
->check
= xge_os_htons(0);
1424 lro
->ip_hdr
->check
= XGE_LL_IP_FAST_CSUM(((u8
*)(lro
->ip_hdr
)),
1425 (lro
->ip_hdr
->version_ihl
& 0x0F));
1426 ring_lro
->lro_next_idx
= i
+ 1;
1430 ring_lro
->lro_next_idx
= 0;
1435 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL lro_t
*
1436 xge_hal_lro_get_next_session(xge_hal_device_t
*hldev
)
1438 int ring
= 0; /* assume default ring=0 */
1439 return xge_hal_lro_next_session(hldev
, ring
);