- Update Xen patches to 3.3-rc5 and c/s 1157.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / sfc_netfront / falcon_vi.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, stg
28  *  \brief  Falcon-specific VI
29  *   \date  2006/11/30
30  */
31
32 #include "ef_vi_internal.h"
33
34
35 #define EFVI_FALCON_DMA_TX_FRAG         1
36
37
38 /* TX descriptor for both physical and virtual packet transfers */
39 typedef union {
40         uint32_t        dword[2];
41 } ef_vi_falcon_dma_tx_buf_desc;
42 typedef ef_vi_falcon_dma_tx_buf_desc ef_vi_falcon_dma_tx_phys_desc;
43
44
45 /* RX descriptor for physical addressed transfers */
46 typedef union {
47         uint32_t        dword[2];
48 } ef_vi_falcon_dma_rx_phys_desc;
49
50
51 /* RX descriptor for virtual packet transfers */
52 typedef struct {
53         uint32_t        dword[1];
54 } ef_vi_falcon_dma_rx_buf_desc;
55
56 /* Buffer table index */
57 typedef uint32_t                ef_vi_buffer_addr_t;
58
59 ef_vi_inline int64_t dma_addr_to_u46(int64_t src_dma_addr)
60 {
61         return (src_dma_addr & __FALCON_MASK(46, int64_t));
62 }
63
64 /*! Setup a physical address based descriptor with a specified length */
65 ef_vi_inline void
66 __falcon_dma_rx_calc_ip_phys(ef_vi_dma_addr_t dest_pa, 
67                              ef_vi_falcon_dma_rx_phys_desc *desc,
68                              int bytes)
69 {
70         int region = 0;                 /* TODO fixme */
71         int64_t dest    = dma_addr_to_u46(dest_pa); /* lower 46 bits */
72
73         DWCHCK(__DW2(RX_KER_BUF_SIZE_LBN),  RX_KER_BUF_SIZE_WIDTH);
74         DWCHCK(__DW2(RX_KER_BUF_REGION_LBN),RX_KER_BUF_REGION_WIDTH);
75
76         LWCHK(RX_KER_BUF_ADR_LBN, RX_KER_BUF_ADR_WIDTH);
77
78         RANGECHCK(bytes,  RX_KER_BUF_SIZE_WIDTH);
79         RANGECHCK(region, RX_KER_BUF_REGION_WIDTH);
80
81         ef_assert(desc);
82
83         desc->dword[1] = ((bytes << __DW2(RX_KER_BUF_SIZE_LBN)) |
84                           (region << __DW2(RX_KER_BUF_REGION_LBN)) |
85                           (HIGH(dest,
86                                 RX_KER_BUF_ADR_LBN, 
87                                 RX_KER_BUF_ADR_WIDTH)));
88
89         desc->dword[0] = LOW(dest, 
90                              RX_KER_BUF_ADR_LBN, 
91                              RX_KER_BUF_ADR_WIDTH);
92 }
93
94 /*! Setup a virtual buffer descriptor for an IPMODE transfer */
95 ef_vi_inline void
96 __falcon_dma_tx_calc_ip_buf(unsigned buf_id, unsigned buf_ofs, unsigned bytes,
97                             int port, int frag, 
98                             ef_vi_falcon_dma_tx_buf_desc *desc)
99 {
100         DWCHCK(__DW2(TX_USR_PORT_LBN), TX_USR_PORT_WIDTH);
101         DWCHCK(__DW2(TX_USR_CONT_LBN), TX_USR_CONT_WIDTH);
102         DWCHCK(__DW2(TX_USR_BYTE_CNT_LBN), TX_USR_BYTE_CNT_WIDTH);
103         LWCHK(RX_KER_BUF_ADR_LBN, RX_KER_BUF_ADR_WIDTH);
104         DWCHCK(TX_USR_BYTE_OFS_LBN, TX_USR_BYTE_OFS_WIDTH);
105
106         RANGECHCK(bytes,   TX_USR_BYTE_CNT_WIDTH);
107         RANGECHCK(port,    TX_USR_PORT_WIDTH);
108         RANGECHCK(frag,    TX_USR_CONT_WIDTH);
109         RANGECHCK(buf_id,  TX_USR_BUF_ID_WIDTH);
110         RANGECHCK(buf_ofs, TX_USR_BYTE_OFS_WIDTH);
111
112         ef_assert(desc);
113
114         desc->dword[1] = ((port   <<  __DW2(TX_USR_PORT_LBN))      | 
115                           (frag   <<  __DW2(TX_USR_CONT_LBN))      | 
116                           (bytes  <<  __DW2(TX_USR_BYTE_CNT_LBN))  |
117                           (HIGH(buf_id, 
118                                 TX_USR_BUF_ID_LBN,
119                                 TX_USR_BUF_ID_WIDTH)));
120
121         desc->dword[0] =  ((LOW(buf_id,
122                                 TX_USR_BUF_ID_LBN,
123                                 (TX_USR_BUF_ID_WIDTH))) |
124                            (buf_ofs << TX_USR_BYTE_OFS_LBN));
125 }
126
127 ef_vi_inline void
128 falcon_dma_tx_calc_ip_buf_4k(unsigned buf_vaddr, unsigned bytes,
129                              int port, int frag, 
130                              ef_vi_falcon_dma_tx_buf_desc *desc)
131 {
132         /* TODO FIXME [buf_vaddr] consists of the buffer index in the
133         ** high bits, and an offset in the low bits. Assumptions
134         ** permate the code that these can be rolled into one 32bit
135         ** value, so this is currently preserved for Falcon. But we
136         ** should change to support 8K pages
137         */
138         unsigned buf_id =  EFVI_FALCON_BUFFER_4K_PAGE(buf_vaddr);
139         unsigned buf_ofs = EFVI_FALCON_BUFFER_4K_OFF(buf_vaddr);
140
141         __falcon_dma_tx_calc_ip_buf( buf_id, buf_ofs, bytes, port, frag, desc);
142 }
143
144 ef_vi_inline void
145 falcon_dma_tx_calc_ip_buf(unsigned buf_vaddr, unsigned bytes, int port, 
146                           int frag, ef_vi_falcon_dma_tx_buf_desc *desc)
147 {
148         falcon_dma_tx_calc_ip_buf_4k(buf_vaddr, bytes, port, frag, desc);
149 }
150
151 /*! Setup a virtual buffer based descriptor */
152 ef_vi_inline void
153 __falcon_dma_rx_calc_ip_buf(unsigned buf_id, unsigned buf_ofs, 
154                             ef_vi_falcon_dma_rx_buf_desc *desc)
155
156         /* check alignment of buffer offset and pack */
157         ef_assert((buf_ofs & 0x1) == 0);
158
159         buf_ofs >>= 1;
160
161         DWCHCK(RX_USR_2BYTE_OFS_LBN, RX_USR_2BYTE_OFS_WIDTH);
162         DWCHCK(RX_USR_BUF_ID_LBN, RX_USR_BUF_ID_WIDTH);
163
164         RANGECHCK(buf_ofs, RX_USR_2BYTE_OFS_WIDTH);
165         RANGECHCK(buf_id,  RX_USR_BUF_ID_WIDTH);
166
167         ef_assert(desc);
168
169         desc->dword[0] = ((buf_ofs << RX_USR_2BYTE_OFS_LBN) | 
170                           (buf_id  << RX_USR_BUF_ID_LBN));
171 }
172
173 ef_vi_inline void
174 falcon_dma_rx_calc_ip_buf_4k(unsigned buf_vaddr, 
175                              ef_vi_falcon_dma_rx_buf_desc *desc)
176
177         /* TODO FIXME [buf_vaddr] consists of the buffer index in the
178         ** high bits, and an offset in the low bits. Assumptions
179         ** permeate the code that these can be rolled into one 32bit
180         ** value, so this is currently preserved for Falcon. But we
181         ** should change to support 8K pages
182         */
183         unsigned buf_id =  EFVI_FALCON_BUFFER_4K_PAGE(buf_vaddr);
184         unsigned buf_ofs = EFVI_FALCON_BUFFER_4K_OFF(buf_vaddr);
185
186         __falcon_dma_rx_calc_ip_buf(buf_id, buf_ofs, desc);
187 }
188
189 ef_vi_inline void
190 falcon_dma_rx_calc_ip_buf(unsigned buf_vaddr, 
191                           ef_vi_falcon_dma_rx_buf_desc *desc)
192
193         falcon_dma_rx_calc_ip_buf_4k(buf_vaddr, desc);
194 }
195
196
197 ef_vi_inline ef_vi_dma_addr_t ef_physaddr(ef_addr efaddr)
198 {
199         return (ef_vi_dma_addr_t) efaddr;
200 }
201
202
203 /*! Convert between an ef_addr and a buffer table index
204 **  Assert that this was not a physical address
205 */
206 ef_vi_inline ef_vi_buffer_addr_t ef_bufaddr(ef_addr efaddr)
207 {
208         ef_assert(efaddr < ((uint64_t)1 << 32) );
209
210         return (ef_vi_buffer_addr_t) efaddr;
211 }
212
213
214 /*! Setup an physical address based descriptor for an IPMODE transfer */
215 ef_vi_inline void
216 falcon_dma_tx_calc_ip_phys(ef_vi_dma_addr_t src_dma_addr, unsigned bytes, 
217                            int port, int frag,
218                            ef_vi_falcon_dma_tx_phys_desc *desc)
219 {
220
221         int region = 0; /* FIXME */
222         int64_t src    = dma_addr_to_u46(src_dma_addr); /* lower 46 bits */
223
224         DWCHCK(__DW2(TX_KER_PORT_LBN),      TX_KER_PORT_WIDTH);
225         DWCHCK(__DW2(TX_KER_CONT_LBN),      TX_KER_CONT_WIDTH);
226         DWCHCK(__DW2(TX_KER_BYTE_CNT_LBN),  TX_KER_BYTE_CNT_WIDTH);
227         DWCHCK(__DW2(TX_KER_BUF_REGION_LBN),TX_KER_BUF_REGION_WIDTH);
228
229         LWCHK(TX_KER_BUF_ADR_LBN, TX_KER_BUF_ADR_WIDTH);
230
231         RANGECHCK(port,   TX_KER_PORT_WIDTH);
232         RANGECHCK(frag,   TX_KER_CONT_WIDTH);
233         RANGECHCK(bytes,  TX_KER_BYTE_CNT_WIDTH);
234         RANGECHCK(region, TX_KER_BUF_REGION_WIDTH);
235
236         desc->dword[1] = ((port   <<  __DW2(TX_KER_PORT_LBN))      | 
237                           (frag   <<  __DW2(TX_KER_CONT_LBN))      | 
238                           (bytes  <<  __DW2(TX_KER_BYTE_CNT_LBN))  | 
239                           (region << __DW2(TX_KER_BUF_REGION_LBN)) |
240                           (HIGH(src,
241                                 TX_KER_BUF_ADR_LBN, 
242                                 TX_KER_BUF_ADR_WIDTH)));
243
244         ef_assert_equal(TX_KER_BUF_ADR_LBN, 0);
245         desc->dword[0] = (uint32_t) src_dma_addr;
246 }
247
248
249 void falcon_vi_init(ef_vi* vi, void* vvis)
250 {
251         struct vi_mappings *vm = (struct vi_mappings*)vvis;
252         uint16_t* ids;
253
254         ef_assert(vi);
255         ef_assert(vvis);
256         ef_assert_equal(vm->signature, VI_MAPPING_SIGNATURE);
257         ef_assert_equal(vm->nic_type.arch, EF_VI_ARCH_FALCON);
258
259         /* Initialise masks to zero, so that ef_vi_state_init() will
260         ** not do any harm when we don't have DMA queues. */
261         vi->vi_rxq.mask = vi->vi_txq.mask = 0;
262
263         /* Used for BUG5391_WORKAROUND. */
264         vi->vi_txq.misalign_mask = 0;
265
266         /* Initialise doorbell addresses to a distinctive small value
267         ** which will cause a segfault, to trap doorbell pushes to VIs
268         ** without DMA queues. */
269         vi->vi_rxq.doorbell = vi->vi_txq.doorbell = (ef_vi_ioaddr_t)0xdb;
270
271         ids = (uint16_t*) (vi->ep_state + 1);
272
273         if( vm->tx_queue_capacity ) {
274                 vi->vi_txq.mask = vm->tx_queue_capacity - 1;
275                 vi->vi_txq.doorbell = vm->tx_bell + 12;
276                 vi->vi_txq.descriptors = vm->tx_dma_falcon;
277                 vi->vi_txq.ids = ids;
278                 ids += vi->vi_txq.mask + 1;
279                 /* Check that the id fifo fits in the space allocated. */
280                 ef_assert_le((char*) (vi->vi_txq.ids + vm->tx_queue_capacity),
281                              (char*) vi->ep_state
282                              + ef_vi_calc_state_bytes(vm->rx_queue_capacity,
283                                                       vm->tx_queue_capacity));
284         }
285         if( vm->rx_queue_capacity ) {
286                 vi->vi_rxq.mask = vm->rx_queue_capacity - 1;
287                 vi->vi_rxq.doorbell = vm->rx_bell + 12;
288                 vi->vi_rxq.descriptors = vm->rx_dma_falcon;
289                 vi->vi_rxq.ids = ids;
290                 /* Check that the id fifo fits in the space allocated. */
291                 ef_assert_le((char*) (vi->vi_rxq.ids + vm->rx_queue_capacity),
292                              (char*) vi->ep_state
293                              + ef_vi_calc_state_bytes(vm->rx_queue_capacity,
294                                                       vm->tx_queue_capacity));
295         }
296
297         if( vm->nic_type.variant == 'A' ) {
298                 vi->vi_txq.misalign_mask = 15;    /* BUG5391_WORKAROUND */
299                 vi->vi_flags |= EF_VI_BUG5692_WORKAROUND;
300         }
301 }
302
303
304 int ef_vi_transmitv_init(ef_vi* vi, const ef_iovec* iov, int iov_len,
305                          ef_request_id dma_id)
306 {
307         ef_vi_txq* q = &vi->vi_txq;
308         ef_vi_txq_state* qs = &vi->ep_state->txq;
309         ef_vi_falcon_dma_tx_buf_desc* dp;
310         unsigned len, dma_len, di;
311         unsigned added_save = qs->added;
312         ef_addr dma_addr;
313         unsigned last_len = 0;
314
315         ef_assert(iov_len > 0);
316         ef_assert(iov);
317         ef_assert_equal((dma_id & EF_REQUEST_ID_MASK), dma_id);
318         ef_assert_nequal(dma_id, 0xffff);
319
320         dma_addr = iov->iov_base;
321         len = iov->iov_len;
322
323         if( vi->vi_flags & EF_VI_ISCSI_TX_DDIG ) {
324                 /* Last 4 bytes of placeholder for digest must be
325                  * removed for h/w */
326                 ef_assert(len > 4);
327                 last_len = iov[iov_len - 1].iov_len;
328                 if( last_len <= 4 ) {
329                         ef_assert(iov_len > 1);
330                         --iov_len;
331                         last_len = iov[iov_len - 1].iov_len - (4 - last_len);
332                 }
333                 else {
334                         last_len = iov[iov_len - 1].iov_len - 4;
335                 }
336                 if( iov_len == 1 )
337                         len = last_len;
338         }
339
340         while( 1 ) {
341                 if( qs->added - qs->removed >= q->mask ) {
342                         qs->added = added_save;
343                         return -EAGAIN;
344                 }
345
346                 dma_len = (~((unsigned) dma_addr) & 0xfff) + 1;
347                 if( dma_len > len )  dma_len = len;
348                 { /* BUG5391_WORKAROUND */
349                         unsigned misalign = 
350                                 (unsigned) dma_addr & q->misalign_mask;
351                         if( misalign && dma_len + misalign > 512 )
352                                 dma_len = 512 - misalign;
353                 }
354
355                 di = qs->added++ & q->mask;
356                 dp = (ef_vi_falcon_dma_tx_buf_desc*) q->descriptors + di;
357                 if( vi->vi_flags & EF_VI_TX_PHYS_ADDR )
358                         falcon_dma_tx_calc_ip_phys
359                                 (ef_physaddr(dma_addr), dma_len, /*port*/ 0,
360                                  (iov_len == 1 && dma_len == len) ? 0 :
361                                  EFVI_FALCON_DMA_TX_FRAG, dp);
362                 else
363                         falcon_dma_tx_calc_ip_buf
364                                 (ef_bufaddr(dma_addr), dma_len, /*port*/ 0,
365                                  (iov_len == 1 && dma_len == len) ? 0 :
366                                  EFVI_FALCON_DMA_TX_FRAG, dp);
367
368                 dma_addr += dma_len;
369                 len -= dma_len;
370
371                 if( len == 0 ) {
372                         if( --iov_len == 0 )  break;
373                         ++iov;
374                         dma_addr = iov->iov_base;
375                         len = iov->iov_len;
376                         if( (vi->vi_flags & EF_VI_ISCSI_TX_DDIG) &&
377                             (iov_len == 1) )
378                                 len = last_len;
379                 }
380         }
381
382         q->ids[di] = (uint16_t) dma_id;
383         return 0;
384 }
385
386
387 void ef_vi_transmit_push(ef_vi* vi)
388 {
389         ef_vi_wiob();
390         writel((vi->ep_state->txq.added & vi->vi_txq.mask) <<
391                 __DW4(TX_DESC_WPTR_LBN),
392                 vi->vi_txq.doorbell);
393 }
394
395
396 /*! The value of initial_rx_bytes is used to set RX_KER_BUF_SIZE in an initial
397 **  receive descriptor here if physical addressing is being used. A value of
398 **  zero represents 16384 bytes.  This is okay, because caller must provide a
399 **  buffer than is > MTU, and mac should filter anything bigger than that.
400 */
401 int ef_vi_receive_init(ef_vi* vi, ef_addr addr, ef_request_id dma_id,
402                        int initial_rx_bytes)
403 {
404         ef_vi_rxq* q = &vi->vi_rxq;
405         ef_vi_rxq_state* qs = &vi->ep_state->rxq;
406         unsigned di;
407
408         if( ef_vi_receive_space(vi) ) {
409                 di = qs->added++ & q->mask;
410                 ef_assert_equal(q->ids[di], 0xffff);
411                 q->ids[di] = (uint16_t) dma_id;
412
413                 if( ! (vi->vi_flags & EF_VI_RX_PHYS_ADDR) ) {
414                         ef_vi_falcon_dma_rx_buf_desc* dp;
415                         dp = (ef_vi_falcon_dma_rx_buf_desc*) 
416                                 q->descriptors + di;
417                         falcon_dma_rx_calc_ip_buf(ef_bufaddr(addr), dp);
418                 }
419                 else {
420                         ef_vi_falcon_dma_rx_phys_desc* dp;
421                         dp = (ef_vi_falcon_dma_rx_phys_desc*) 
422                                 q->descriptors + di;
423                         __falcon_dma_rx_calc_ip_phys(addr, dp,
424                                                      initial_rx_bytes);
425                 }
426
427                 return 0;
428         }
429
430         return -EAGAIN;
431 }
432
433
434 int ef_vi_receive_post(ef_vi* vi, ef_addr addr, ef_request_id dma_id)
435 {
436   int rc = ef_vi_receive_init(vi, addr, dma_id, 0);
437   if( rc == 0 )  ef_vi_receive_push(vi);
438   return rc;
439 }
440
441
442 void ef_vi_receive_push(ef_vi* vi)
443 {
444         ef_vi_wiob();
445         writel ((vi->ep_state->rxq.added & vi->vi_rxq.mask) <<
446                 __DW4(RX_DESC_WPTR_LBN),
447                 vi->vi_rxq.doorbell);
448 }
449
450
451 ef_request_id ef_vi_receive_done(const ef_vi* vi, const ef_event* ef_ev)
452 {
453         const ef_vi_qword* ev = EF_GET_HW_EV_PTR(*ef_ev);
454         unsigned di = ev->u32[0] & vi->vi_rxq.mask;
455         ef_request_id rq_id;
456
457         ef_assert(EF_EVENT_TYPE(*ef_ev) == EF_EVENT_TYPE_RX ||
458                   EF_EVENT_TYPE(*ef_ev) == EF_EVENT_TYPE_RX_DISCARD);
459
460         /* Detect spurious / duplicate RX events.  We may need to modify this
461         ** code so that we are robust if they happen. */
462         ef_assert_equal(di, vi->ep_state->rxq.removed & vi->vi_rxq.mask);
463
464         /* We only support 1 port: so events should be in order. */
465         ef_assert(vi->vi_rxq.ids[di] != 0xffff);
466
467         rq_id = vi->vi_rxq.ids[di];
468         vi->vi_rxq.ids[di] = 0xffff;
469         ++vi->ep_state->rxq.removed;
470         return rq_id;
471 }
472
473 /*! \cidoxg_end */