- Update Xen patches to 3.3-rc5 and c/s 1157.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / sfc_netfront / pt_tx.c
1 /****************************************************************************
2  * Copyright 2002-2005: Level 5 Networks Inc.
3  * Copyright 2005-2008: Solarflare Communications Inc,
4  *                      9501 Jeronimo Road, Suite 250,
5  *                      Irvine, CA 92618, USA
6  *
7  * Maintained by Solarflare Communications
8  *  <linux-xen-drivers@solarflare.com>
9  *  <onload-dev@solarflare.com>
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 as published
13  * by the Free Software Foundation, incorporated herein by reference.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23  ****************************************************************************
24  */
25
26 /*
27  * \author  djr
28  *  \brief  Packet-mode transmit interface.
29  *   \date  2003/04/02
30  */
31
32 /*! \cidoxg_lib_ef */
33 #include "ef_vi_internal.h"
34
35
36 int ef_vi_transmit_init(ef_vi* vi, ef_addr base, int len, ef_request_id dma_id)
37 {
38         ef_iovec iov = { base, len };
39         return ef_vi_transmitv_init(vi, &iov, 1, dma_id);
40 }
41
42
43 int ef_vi_transmit(ef_vi* vi, ef_addr base, int len, ef_request_id dma_id)
44 {
45         ef_iovec iov = { base, len };
46         int rc = ef_vi_transmitv_init(vi, &iov, 1, dma_id);
47         if( rc == 0 )  ef_vi_transmit_push(vi);
48         return rc;
49 }
50
51
52 int ef_vi_transmitv(ef_vi* vi, const ef_iovec* iov, int iov_len,
53                     ef_request_id dma_id)
54 {
55         int rc = ef_vi_transmitv_init(vi, iov, iov_len, dma_id);
56         if( rc == 0 )  ef_vi_transmit_push(vi);
57         return rc;
58 }
59
60
61 int ef_vi_transmit_unbundle(ef_vi* vi, const ef_event* __ev,
62                             ef_request_id* ids)
63 {
64         ef_request_id* ids_in = ids;
65         ef_vi_txq* q = &vi->vi_txq;
66         ef_vi_txq_state* qs = &vi->ep_state->txq;
67         const ef_vi_qword* ev = EF_GET_HW_EV_PTR(*__ev);
68         unsigned i, stop = (ev->u32[0] + 1) & q->mask;
69
70         ef_assert(EF_EVENT_TYPE(*__ev) == EF_EVENT_TYPE_TX ||
71                   EF_EVENT_TYPE(*__ev) == EF_EVENT_TYPE_TX_ERROR);
72
73         /* Shouldn't be batching more than 64 descriptors, and should not go
74         ** backwards. */
75         ef_assert_le((((ev->u32[0] + 1) - qs->removed) & q->mask), 64);
76         /* Should not complete more than we've posted. */
77         ef_assert_le((((ev->u32[0] + 1) - qs->removed) & q->mask),
78                      qs->added - qs->removed);
79
80         for( i = qs->removed & q->mask; i != stop; i = ++qs->removed & q->mask )
81                 if( q->ids[i] != 0xffff ) {
82                         *ids++ = q->ids[i];
83                         q->ids[i] = 0xffff;
84                 }
85
86         ef_assert_le(ids - ids_in, EF_VI_TRANSMIT_BATCH);
87
88         return (int) (ids - ids_in);
89 }
90
91 /*! \cidoxg_end */