Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / sfc_netfront / vi_init.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  Initialisation of VIs.
29  *   \date  2007/06/08
30  */
31
32 #include "ef_vi_internal.h"
33
34 #define EF_VI_STATE_BYTES(rxq_sz, txq_sz)                       \
35         (sizeof(ef_vi_state) + (rxq_sz) * sizeof(uint16_t)      \
36          + (txq_sz) * sizeof(uint16_t))
37
38 int ef_vi_calc_state_bytes(int rxq_sz, int txq_sz)
39 {
40         ef_assert(rxq_sz == 0 || EF_VI_IS_POW2(rxq_sz));
41         ef_assert(txq_sz == 0 || EF_VI_IS_POW2(txq_sz));
42
43         return EF_VI_STATE_BYTES(rxq_sz, txq_sz);
44 }
45
46
47 int ef_vi_state_bytes(ef_vi* vi)
48 {
49         int rxq_sz = 0, txq_sz = 0;
50         if( ef_vi_receive_capacity(vi) )
51                 rxq_sz = ef_vi_receive_capacity(vi) + 1;
52         if( ef_vi_transmit_capacity(vi) )
53                 txq_sz = ef_vi_transmit_capacity(vi) + 1;
54
55         ef_assert(rxq_sz == 0 || EF_VI_IS_POW2(rxq_sz));
56         ef_assert(txq_sz == 0 || EF_VI_IS_POW2(txq_sz));
57
58         return EF_VI_STATE_BYTES(rxq_sz, txq_sz);
59 }
60
61
62 void ef_eventq_state_init(ef_vi* evq)
63 {
64         int j;
65
66         for (j = 0; j<EFAB_DMAQS_PER_EVQ_MAX; j++) {
67                 ef_rx_dup_state_t *rx_dup_state =
68                         &evq->evq_state->rx_dup_state[j];
69                 rx_dup_state->bad_sop = 0;
70                 rx_dup_state->rx_last_desc_ptr = -1;
71                 rx_dup_state->frag_num = 0;
72         }
73
74         evq->evq_state->evq_ptr = 0;
75 }
76
77
78 void ef_vi_state_init(ef_vi* vi)
79 {
80         ef_vi_state* state = vi->ep_state;
81         unsigned i;
82
83         state->txq.added = state->txq.removed = 0;
84         state->rxq.added = state->rxq.removed = 0;
85
86         if( vi->vi_rxq.mask )
87                 for( i = 0; i <= vi->vi_rxq.mask; ++i )
88                         vi->vi_rxq.ids[i] = (uint16_t) -1;
89         if( vi->vi_txq.mask )
90                 for( i = 0; i <= vi->vi_txq.mask; ++i )
91                         vi->vi_txq.ids[i] = (uint16_t) -1;
92 }
93
94
95 void ef_vi_init_mapping_evq(void* data_area, struct ef_vi_nic_type nic_type,
96                             int instance, unsigned evq_bytes, void* base,
97                             void* timer_reg)
98 {
99         struct vi_mappings* vm = (struct vi_mappings*) data_area;
100
101         vm->signature = VI_MAPPING_SIGNATURE;
102         vm->vi_instance = instance;
103         vm->nic_type = nic_type;
104         vm->evq_bytes = evq_bytes;
105         vm->evq_base = base;
106         vm->evq_timer_reg = timer_reg;
107 }
108
109
110 void ef_vi_init(ef_vi* vi, void* vvis, ef_vi_state* state,
111                 ef_eventq_state* evq_state, enum ef_vi_flags vi_flags)
112 {
113         struct vi_mappings* vm = (struct vi_mappings*) vvis;
114
115         vi->vi_i = vm->vi_instance;
116         vi->ep_state = state;
117         vi->vi_flags = vi_flags;
118
119         switch( vm->nic_type.arch ) {
120         case EF_VI_ARCH_FALCON:
121                 falcon_vi_init(vi, vvis);
122                 break;
123         default:
124                 /* ?? TODO: We should return an error code. */
125                 ef_assert(0);
126                 break;
127         }
128
129         if( vm->evq_bytes ) {
130                 vi->evq_state = evq_state;
131                 vi->evq_mask = vm->evq_bytes - 1u;
132                 vi->evq_base = vm->evq_base;
133                 vi->evq_timer_reg = vm->evq_timer_reg;
134         }
135
136         EF_VI_MAGIC_SET(vi, EF_VI);
137 }
138
139
140 /* Initialise [data_area] with information required to initialise an ef_vi.
141  * In the following, an unused param should be set to NULL. Note the case
142  * marked (*) of [iobuf_mmap] for falcon/driver; for the normal driver this
143  * must be NULL.
144  *
145  * \param  data_area     [in,out] required, must ref at least VI_MAPPING_SIZE 
146  *                                bytes
147  * \param  io_mmap       [in] ef1,    required
148  *                            falcon, required
149  * \param  iobuf_mmap    [in] ef1,    unused
150  *                            falcon, required
151  */
152 void ef_vi_init_mapping_vi(void* data_area, struct ef_vi_nic_type nic_type,
153                            unsigned rxq_capacity, unsigned txq_capacity,
154                            int instance, void* io_mmap,
155                            void* iobuf_mmap_rx, void* iobuf_mmap_tx,
156                            enum ef_vi_flags vi_flags)
157 {
158         struct vi_mappings* vm = (struct vi_mappings*) data_area;
159         int rx_desc_bytes, rxq_bytes;
160
161         ef_assert(rxq_capacity > 0 || txq_capacity > 0);
162         ef_assert(vm);
163         ef_assert(io_mmap);
164         ef_assert(iobuf_mmap_rx || iobuf_mmap_tx);
165
166         vm->signature = VI_MAPPING_SIGNATURE;
167         vm->vi_instance = instance;
168         vm->nic_type = nic_type;
169
170         rx_desc_bytes = (vi_flags & EF_VI_RX_PHYS_ADDR) ? 8 : 4;
171         rxq_bytes = rxq_capacity * rx_desc_bytes;
172         rxq_bytes = (rxq_bytes + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
173
174         if( iobuf_mmap_rx == iobuf_mmap_tx )
175                 iobuf_mmap_tx = (char*) iobuf_mmap_rx + rxq_bytes;
176
177         vm->rx_queue_capacity = rxq_capacity;
178         vm->rx_dma_falcon = iobuf_mmap_rx;
179         vm->rx_bell       = (char*) io_mmap + (RX_DESC_UPD_REG_KER_OFST & 4095);
180         vm->tx_queue_capacity = txq_capacity;
181         vm->tx_dma_falcon = iobuf_mmap_tx;
182         vm->tx_bell       = (char*) io_mmap + (TX_DESC_UPD_REG_KER_OFST & 4095);
183 }