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
7 * Maintained by Solarflare Communications
8 * <linux-xen-drivers@solarflare.com>
9 * <onload-dev@solarflare.com>
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.
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.
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 ****************************************************************************
28 * \brief Initialisation of VIs.
32 #include "ef_vi_internal.h"
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))
38 int ef_vi_calc_state_bytes(int rxq_sz, int txq_sz)
40 ef_assert(rxq_sz == 0 || EF_VI_IS_POW2(rxq_sz));
41 ef_assert(txq_sz == 0 || EF_VI_IS_POW2(txq_sz));
43 return EF_VI_STATE_BYTES(rxq_sz, txq_sz);
47 int ef_vi_state_bytes(ef_vi* vi)
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;
55 ef_assert(rxq_sz == 0 || EF_VI_IS_POW2(rxq_sz));
56 ef_assert(txq_sz == 0 || EF_VI_IS_POW2(txq_sz));
58 return EF_VI_STATE_BYTES(rxq_sz, txq_sz);
62 void ef_eventq_state_init(ef_vi* evq)
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;
74 evq->evq_state->evq_ptr = 0;
78 void ef_vi_state_init(ef_vi* vi)
80 ef_vi_state* state = vi->ep_state;
83 state->txq.added = state->txq.removed = 0;
84 state->rxq.added = state->rxq.removed = 0;
87 for( i = 0; i <= vi->vi_rxq.mask; ++i )
88 vi->vi_rxq.ids[i] = (uint16_t) -1;
90 for( i = 0; i <= vi->vi_txq.mask; ++i )
91 vi->vi_txq.ids[i] = (uint16_t) -1;
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,
99 struct vi_mappings* vm = (struct vi_mappings*) data_area;
101 vm->signature = VI_MAPPING_SIGNATURE;
102 vm->vi_instance = instance;
103 vm->nic_type = nic_type;
104 vm->evq_bytes = evq_bytes;
106 vm->evq_timer_reg = timer_reg;
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)
113 struct vi_mappings* vm = (struct vi_mappings*) vvis;
115 vi->vi_i = vm->vi_instance;
116 vi->ep_state = state;
117 vi->vi_flags = vi_flags;
119 switch( vm->nic_type.arch ) {
120 case EF_VI_ARCH_FALCON:
121 falcon_vi_init(vi, vvis);
124 /* ?? TODO: We should return an error code. */
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;
136 EF_VI_MAGIC_SET(vi, EF_VI);
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
145 * \param data_area [in,out] required, must ref at least VI_MAPPING_SIZE
147 * \param io_mmap [in] ef1, required
149 * \param iobuf_mmap [in] ef1, unused
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)
158 struct vi_mappings* vm = (struct vi_mappings*) data_area;
159 int rx_desc_bytes, rxq_bytes;
161 ef_assert(rxq_capacity > 0 || txq_capacity > 0);
164 ef_assert(iobuf_mmap_rx || iobuf_mmap_tx);
166 vm->signature = VI_MAPPING_SIGNATURE;
167 vm->vi_instance = instance;
168 vm->nic_type = nic_type;
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);
174 if( iobuf_mmap_rx == iobuf_mmap_tx )
175 iobuf_mmap_tx = (char*) iobuf_mmap_rx + rxq_bytes;
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);