Fix native build on non x86_64 systems
[vpp.git] / vnet / vnet / devices / nic / ixge.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 /*
17  *   WARNING!
18  *   This driver is not intended for production use and it is unsupported.
19  *   It is provided for educational use only.
20  *   Please use supported DPDK driver instead.
21  */
22
23 #if __x86_64__
24 #include <vppinfra/vector.h>
25
26 #ifndef CLIB_HAVE_VEC128
27 #warning HACK: ixge driver wont really work, missing u32x4
28 typedef unsigned long long u32x4;
29 #endif
30
31 #include <vlib/vlib.h>
32 #include <vlib/unix/unix.h>
33 #include <vlib/pci/pci.h>
34 #include <vnet/vnet.h>
35 #include <vnet/devices/nic/ixge.h>
36 #include <vnet/ethernet/ethernet.h>
37
38 #define IXGE_ALWAYS_POLL 0
39
40 #define EVENT_SET_FLAGS 0
41 #define IXGE_HWBP_RACE_ELOG 0
42
43 #define PCI_VENDOR_ID_INTEL 0x8086
44
45 /* 10 GIG E (XGE) PHY IEEE 802.3 clause 45 definitions. */
46 #define XGE_PHY_DEV_TYPE_PMA_PMD 1
47 #define XGE_PHY_DEV_TYPE_PHY_XS 4
48 #define XGE_PHY_ID1 0x2
49 #define XGE_PHY_ID2 0x3
50 #define XGE_PHY_CONTROL 0x0
51 #define XGE_PHY_CONTROL_RESET (1 << 15)
52
53 ixge_main_t ixge_main;
54 static vlib_node_registration_t ixge_input_node;
55 static vlib_node_registration_t ixge_process_node;
56
57 static void ixge_semaphore_get (ixge_device_t * xd)
58 {
59   ixge_main_t * xm = &ixge_main;
60   vlib_main_t * vm = xm->vlib_main;
61   ixge_regs_t * r = xd->regs;
62   u32 i;
63
64   i = 0;
65   while (! (r->software_semaphore & (1 << 0)))
66     {
67       if (i > 0)
68         vlib_process_suspend (vm, 100e-6);
69       i++;
70     }
71   do {
72     r->software_semaphore |= 1 << 1;
73   } while (! (r->software_semaphore & (1 << 1)));
74 }
75
76 static void ixge_semaphore_release (ixge_device_t * xd)
77 {
78   ixge_regs_t * r = xd->regs;
79   r->software_semaphore &= ~3;
80 }
81
82 static void ixge_software_firmware_sync (ixge_device_t * xd, u32 sw_mask)
83 {
84   ixge_main_t * xm = &ixge_main;
85   vlib_main_t * vm = xm->vlib_main;
86   ixge_regs_t * r = xd->regs;
87   u32 fw_mask = sw_mask << 5;
88   u32 m, done = 0;
89
90   while (! done)
91     {
92       ixge_semaphore_get (xd);
93       m = r->software_firmware_sync;
94       done = (m & fw_mask) == 0;
95       if (done)
96         r->software_firmware_sync = m | sw_mask;
97       ixge_semaphore_release (xd);
98       if (! done)
99         vlib_process_suspend (vm, 10e-3);
100     }
101 }
102
103 static void ixge_software_firmware_sync_release (ixge_device_t * xd, u32 sw_mask)
104 {
105   ixge_regs_t * r = xd->regs;
106   ixge_semaphore_get (xd);
107   r->software_firmware_sync &= ~sw_mask;
108   ixge_semaphore_release (xd);
109 }
110
111 u32 ixge_read_write_phy_reg (ixge_device_t * xd, u32 dev_type, u32 reg_index, u32 v, u32 is_read)
112 {
113   ixge_regs_t * r = xd->regs;
114   const u32 busy_bit = 1 << 30;
115   u32 x;
116
117   ASSERT (xd->phy_index < 2);
118   ixge_software_firmware_sync (xd, 1 << (1 + xd->phy_index));
119
120   ASSERT (reg_index < (1 << 16));
121   ASSERT (dev_type < (1 << 5));
122   if (! is_read)
123     r->xge_mac.phy_data = v;
124
125   /* Address cycle. */
126   x = reg_index | (dev_type << 16) | (xd->phys[xd->phy_index].mdio_address << 21);
127   r->xge_mac.phy_command = x | busy_bit;
128   /* Busy wait timed to take 28e-6 secs.  No suspend. */
129   while (r->xge_mac.phy_command & busy_bit)
130     ;
131
132   r->xge_mac.phy_command = x | ((is_read ? 2 : 1) << 26) | busy_bit;
133   while (r->xge_mac.phy_command & busy_bit)
134     ;
135
136   if (is_read)
137     v = r->xge_mac.phy_data >> 16;
138
139   ixge_software_firmware_sync_release (xd, 1 << (1 + xd->phy_index));
140
141   return v;
142 }
143
144 static u32 ixge_read_phy_reg (ixge_device_t * xd, u32 dev_type, u32 reg_index)
145 { return ixge_read_write_phy_reg (xd, dev_type, reg_index, 0, /* is_read */ 1); }
146
147 static void ixge_write_phy_reg (ixge_device_t * xd, u32 dev_type, u32 reg_index, u32 v)
148 { (void) ixge_read_write_phy_reg (xd, dev_type, reg_index, v, /* is_read */ 0); }
149
150 static void ixge_i2c_put_bits (i2c_bus_t * b, int scl, int sda)
151 {
152   ixge_main_t * xm = &ixge_main;
153   ixge_device_t * xd = vec_elt_at_index (xm->devices, b->private_data);
154   u32 v;
155
156   v = 0;
157   v |= (sda != 0) << 3;
158   v |= (scl != 0) << 1;
159   xd->regs->i2c_control = v;
160 }
161
162 static void ixge_i2c_get_bits (i2c_bus_t * b, int * scl, int * sda)
163 {
164   ixge_main_t * xm = &ixge_main;
165   ixge_device_t * xd = vec_elt_at_index (xm->devices, b->private_data);
166   u32 v;
167
168   v = xd->regs->i2c_control;
169   *sda = (v & (1 << 2)) != 0;
170   *scl = (v & (1 << 0)) != 0;
171 }
172
173 static u16 ixge_read_eeprom (ixge_device_t * xd, u32 address)
174 {
175   ixge_regs_t * r = xd->regs;
176   u32 v;
177   r->eeprom_read = ((/* start bit */ (1 << 0)) | (address << 2));
178   /* Wait for done bit. */
179   while (! ((v = r->eeprom_read) & (1 << 1)))
180     ;
181   return v >> 16;
182 }
183
184 static void
185 ixge_sfp_enable_disable_laser (ixge_device_t * xd, uword enable)
186 {
187   u32 tx_disable_bit = 1 << 3;
188   if (enable)
189     xd->regs->sdp_control &= ~tx_disable_bit;
190   else
191     xd->regs->sdp_control |= tx_disable_bit;
192 }
193
194 static void
195 ixge_sfp_enable_disable_10g (ixge_device_t * xd, uword enable)
196 {
197   u32 is_10g_bit = 1 << 5;
198   if (enable)
199     xd->regs->sdp_control |= is_10g_bit;
200   else
201     xd->regs->sdp_control &= ~is_10g_bit;
202 }
203
204 static clib_error_t *
205 ixge_sfp_phy_init_from_eeprom (ixge_device_t * xd, u16 sfp_type)
206 {
207   u16 a, id, reg_values_addr = 0;
208
209   a = ixge_read_eeprom (xd, 0x2b);
210   if (a == 0 || a == 0xffff)
211     return clib_error_create ("no init sequence in eeprom");
212
213   while (1)
214     {
215       id = ixge_read_eeprom (xd, ++a);
216       if (id == 0xffff)
217         break;
218       reg_values_addr = ixge_read_eeprom (xd, ++a);
219       if (id == sfp_type)
220         break;
221     }
222   if (id != sfp_type)
223     return clib_error_create ("failed to find id 0x%x", sfp_type);
224
225   ixge_software_firmware_sync (xd, 1 << 3);
226   while (1)
227     {
228       u16 v = ixge_read_eeprom (xd, ++reg_values_addr);
229       if (v == 0xffff)
230         break;
231       xd->regs->core_analog_config = v;
232     }
233   ixge_software_firmware_sync_release (xd, 1 << 3);
234
235   /* Make sure laser is off.  We'll turn on the laser when
236      the interface is brought up. */
237   ixge_sfp_enable_disable_laser (xd, /* enable */ 0);
238   ixge_sfp_enable_disable_10g (xd, /* is_10g */ 1);
239
240   return 0;
241 }
242
243 static void
244 ixge_sfp_device_up_down (ixge_device_t * xd, uword is_up)
245 {
246   u32 v;
247
248   if (is_up)
249     {
250       /* pma/pmd 10g serial SFI. */
251       xd->regs->xge_mac.auto_negotiation_control2 &= ~(3 << 16);
252       xd->regs->xge_mac.auto_negotiation_control2 |= 2 << 16;
253
254       v = xd->regs->xge_mac.auto_negotiation_control;
255       v &= ~(7 << 13);
256       v |= (0 << 13);
257       /* Restart autoneg. */
258       v |= (1 << 12);
259       xd->regs->xge_mac.auto_negotiation_control = v;
260
261       while (! (xd->regs->xge_mac.link_partner_ability[0] & 0xf0000))
262         ;
263
264       v = xd->regs->xge_mac.auto_negotiation_control;
265
266       /* link mode 10g sfi serdes */
267       v &= ~(7 << 13);
268       v |= (3 << 13);
269
270       /* Restart autoneg. */
271       v |= (1 << 12);
272       xd->regs->xge_mac.auto_negotiation_control = v;
273
274       xd->regs->xge_mac.link_status;
275     }
276
277   ixge_sfp_enable_disable_laser (xd, /* enable */ is_up);
278
279   /* Give time for link partner to notice that we're up. */
280   if (is_up &&
281       vlib_in_process_context(vlib_get_main())) {
282     vlib_process_suspend (vlib_get_main(), 300e-3);
283   }
284 }
285
286 always_inline ixge_dma_regs_t *
287 get_dma_regs (ixge_device_t * xd, vlib_rx_or_tx_t rt, u32 qi)
288 {
289   ixge_regs_t * r = xd->regs;
290   ASSERT (qi < 128);
291   if (rt == VLIB_RX)
292     return qi < 64 ? &r->rx_dma0[qi] : &r->rx_dma1[qi - 64];
293   else
294     return &r->tx_dma[qi];
295 }
296
297 static clib_error_t *
298 ixge_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
299 {
300   vnet_hw_interface_t * hif = vnet_get_hw_interface (vnm, hw_if_index);
301   uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
302   ixge_main_t * xm = &ixge_main;
303   ixge_device_t * xd = vec_elt_at_index (xm->devices, hif->dev_instance);
304   ixge_dma_regs_t * dr = get_dma_regs (xd, VLIB_RX, 0);
305
306   if (is_up)
307     {
308       xd->regs->rx_enable |= 1;
309       xd->regs->tx_dma_control |= 1;
310       dr->control |= 1 << 25;
311       while (! (dr->control & (1 << 25)))
312         ;
313     }
314   else
315     {
316       xd->regs->rx_enable &= ~1;
317       xd->regs->tx_dma_control &= ~1;
318     }
319
320   ixge_sfp_device_up_down (xd, is_up);
321
322   return /* no error */ 0;
323 }
324
325 static void ixge_sfp_phy_init (ixge_device_t * xd)
326 {
327   ixge_phy_t * phy = xd->phys + xd->phy_index;
328   i2c_bus_t * ib = &xd->i2c_bus;
329
330   ib->private_data = xd->device_index;
331   ib->put_bits = ixge_i2c_put_bits;
332   ib->get_bits = ixge_i2c_get_bits;
333   vlib_i2c_init (ib);
334
335   vlib_i2c_read_eeprom (ib, 0x50, 0, 128, (u8 *) &xd->sfp_eeprom);
336
337   if ( vlib_i2c_bus_timed_out(ib)  || ! sfp_eeprom_is_valid (&xd->sfp_eeprom))
338     xd->sfp_eeprom.id = SFP_ID_unknown;
339   else
340     {
341       /* FIXME 5 => SR/LR eeprom ID. */
342       clib_error_t * e = ixge_sfp_phy_init_from_eeprom (xd, 5 + xd->pci_function);
343       if (e)
344         clib_error_report (e);
345     }
346
347   phy->mdio_address = ~0;
348 }
349
350 static void ixge_phy_init (ixge_device_t * xd)
351 {
352   ixge_main_t * xm = &ixge_main;
353   vlib_main_t * vm = xm->vlib_main;
354   ixge_phy_t * phy = xd->phys + xd->phy_index;
355
356   switch (xd->device_id)
357     {
358     case IXGE_82599_sfp:
359     case IXGE_82599_sfp_em:
360     case IXGE_82599_sfp_fcoe:
361       /* others? */
362       return ixge_sfp_phy_init (xd);
363
364     default:
365       break;
366     }
367
368   /* Probe address of phy. */
369   {
370     u32 i, v;
371
372     phy->mdio_address = ~0;
373     for (i = 0; i < 32; i++)
374       {
375         phy->mdio_address = i;
376         v = ixge_read_phy_reg (xd, XGE_PHY_DEV_TYPE_PMA_PMD, XGE_PHY_ID1);
377         if (v != 0xffff && v != 0)
378           break;
379       }
380
381     /* No PHY found? */
382     if (i >= 32)
383       return;
384   }
385
386   phy->id = ((ixge_read_phy_reg (xd, XGE_PHY_DEV_TYPE_PMA_PMD, XGE_PHY_ID1) << 16)
387              | ixge_read_phy_reg (xd, XGE_PHY_DEV_TYPE_PMA_PMD, XGE_PHY_ID2));
388
389   {
390     ELOG_TYPE_DECLARE (e) = {
391       .function = (char *) __FUNCTION__,
392       .format = "ixge %d, phy id 0x%d mdio address %d",
393       .format_args = "i4i4i4",
394     };
395     struct { u32 instance, id, address; } * ed;
396     ed = ELOG_DATA (&vm->elog_main, e);
397     ed->instance = xd->device_index;
398     ed->id = phy->id;
399     ed->address = phy->mdio_address;
400   }
401
402   /* Reset phy. */
403   ixge_write_phy_reg (xd, XGE_PHY_DEV_TYPE_PHY_XS, XGE_PHY_CONTROL, XGE_PHY_CONTROL_RESET);
404
405   /* Wait for self-clearning reset bit to clear. */
406   do {
407     vlib_process_suspend (vm, 1e-3);
408   } while (ixge_read_phy_reg (xd, XGE_PHY_DEV_TYPE_PHY_XS, XGE_PHY_CONTROL) & XGE_PHY_CONTROL_RESET);
409 }
410
411 static u8 * format_ixge_rx_from_hw_descriptor (u8 * s, va_list * va)
412 {
413   ixge_rx_from_hw_descriptor_t * d = va_arg (*va, ixge_rx_from_hw_descriptor_t *);
414   u32 s0 = d->status[0], s2 = d->status[2];
415   u32 is_ip4, is_ip6, is_ip, is_tcp, is_udp;
416   uword indent = format_get_indent (s);
417
418   s = format (s, "%s-owned",
419               (s2 & IXGE_RX_DESCRIPTOR_STATUS2_IS_OWNED_BY_SOFTWARE) ? "sw" : "hw");
420   s = format (s, ", length this descriptor %d, l3 offset %d",
421               d->n_packet_bytes_this_descriptor,
422               IXGE_RX_DESCRIPTOR_STATUS0_L3_OFFSET (s0));
423   if (s2 & IXGE_RX_DESCRIPTOR_STATUS2_IS_END_OF_PACKET)
424     s = format (s, ", end-of-packet");
425
426   s = format (s, "\n%U", format_white_space, indent);
427
428   if (s2 & IXGE_RX_DESCRIPTOR_STATUS2_ETHERNET_ERROR)
429     s = format (s, "layer2 error");
430
431   if (s0 & IXGE_RX_DESCRIPTOR_STATUS0_IS_LAYER2)
432     {
433       s = format (s, "layer 2 type %d", (s0 & 0x1f));
434       return s;
435     }
436
437   if (s2 & IXGE_RX_DESCRIPTOR_STATUS2_IS_VLAN)
438     s = format (s, "vlan header 0x%x\n%U", d->vlan_tag,
439                 format_white_space, indent);
440
441   if ((is_ip4 = (s0 & IXGE_RX_DESCRIPTOR_STATUS0_IS_IP4)))
442     {
443       s = format (s, "ip4%s",
444                   (s0 & IXGE_RX_DESCRIPTOR_STATUS0_IS_IP4_EXT) ? " options" : "");
445       if (s2 & IXGE_RX_DESCRIPTOR_STATUS2_IS_IP4_CHECKSUMMED)
446         s = format (s, " checksum %s",
447                     (s2 & IXGE_RX_DESCRIPTOR_STATUS2_IP4_CHECKSUM_ERROR) ? "bad" : "ok");
448     }
449   if ((is_ip6 = (s0 & IXGE_RX_DESCRIPTOR_STATUS0_IS_IP6)))
450     s = format (s, "ip6%s",
451                 (s0 & IXGE_RX_DESCRIPTOR_STATUS0_IS_IP6_EXT) ? " extended" : "");
452   is_tcp = is_udp = 0;
453   if ((is_ip = (is_ip4 | is_ip6)))
454     {
455       is_tcp = (s0 & IXGE_RX_DESCRIPTOR_STATUS0_IS_TCP) != 0;
456       is_udp = (s0 & IXGE_RX_DESCRIPTOR_STATUS0_IS_UDP) != 0;
457       if (is_tcp)
458         s = format (s, ", tcp");
459       if (is_udp)
460         s = format (s, ", udp");
461     }
462
463   if (s2 & IXGE_RX_DESCRIPTOR_STATUS2_IS_TCP_CHECKSUMMED)
464     s = format (s, ", tcp checksum %s",
465                 (s2 & IXGE_RX_DESCRIPTOR_STATUS2_TCP_CHECKSUM_ERROR) ? "bad" : "ok");
466   if (s2 & IXGE_RX_DESCRIPTOR_STATUS2_IS_UDP_CHECKSUMMED)
467     s = format (s, ", udp checksum %s",
468                 (s2 & IXGE_RX_DESCRIPTOR_STATUS2_UDP_CHECKSUM_ERROR) ? "bad" : "ok");
469
470   return s;
471 }
472
473 static u8 * format_ixge_tx_descriptor (u8 * s, va_list * va)
474 {
475   ixge_tx_descriptor_t * d = va_arg (*va, ixge_tx_descriptor_t *);
476   u32 s0 = d->status0, s1 = d->status1;
477   uword indent = format_get_indent (s);
478   u32 v;
479
480   s = format (s, "buffer 0x%Lx, %d packet bytes, %d bytes this buffer",
481               d->buffer_address,
482               s1 >> 14, d->n_bytes_this_buffer);
483
484   s = format (s, "\n%U", format_white_space, indent);
485
486   if ((v = (s0 >> 0) & 3))
487     s = format (s, "reserved 0x%x, ", v);
488
489   if ((v = (s0 >> 2) & 3))
490     s = format (s, "mac 0x%x, ", v);
491
492   if ((v = (s0 >> 4) & 0xf) != 3)
493     s = format (s, "type 0x%x, ", v);
494
495   s = format (s, "%s%s%s%s%s%s%s%s",
496               (s0 & (1 << 8)) ? "eop, " : "",
497               (s0 & (1 << 9)) ? "insert-fcs, " : "",
498               (s0 & (1 << 10)) ? "reserved26, " : "",
499               (s0 & (1 << 11)) ? "report-status, " : "",
500               (s0 & (1 << 12)) ? "reserved28, " : "",
501               (s0 & (1 << 13)) ? "is-advanced, " : "",
502               (s0 & (1 << 14)) ? "vlan-enable, " : "",
503               (s0 & (1 << 15)) ? "tx-segmentation, " : "");
504
505   if ((v = s1 & 0xf) != 0)
506     s = format (s, "status 0x%x, ", v);
507
508   if ((v = (s1 >> 4) & 0xf))
509     s = format (s, "context 0x%x, ", v);
510
511   if ((v = (s1 >> 8) & 0x3f))
512     s = format (s, "options 0x%x, ", v);
513
514   return s;
515 }
516
517 typedef struct {
518   ixge_descriptor_t before, after;
519
520   u32 buffer_index;
521
522   u16 device_index;
523
524   u8 queue_index;
525
526   u8 is_start_of_packet;
527
528   /* Copy of VLIB buffer; packet data stored in pre_data. */
529   vlib_buffer_t buffer;
530 } ixge_rx_dma_trace_t;
531
532 static u8 * format_ixge_rx_dma_trace (u8 * s, va_list * va)
533 {
534   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
535   vlib_node_t * node = va_arg (*va, vlib_node_t *);
536   vnet_main_t * vnm = vnet_get_main();
537   ixge_rx_dma_trace_t * t = va_arg (*va, ixge_rx_dma_trace_t *);
538   ixge_main_t * xm = &ixge_main;
539   ixge_device_t * xd = vec_elt_at_index (xm->devices, t->device_index);
540   format_function_t * f;
541   uword indent = format_get_indent (s);
542
543   {
544     vnet_sw_interface_t * sw = vnet_get_sw_interface (vnm, xd->vlib_sw_if_index);
545     s = format (s, "%U rx queue %d",
546                 format_vnet_sw_interface_name, vnm, sw,
547                 t->queue_index);
548   }
549
550   s = format (s, "\n%Ubefore: %U",
551               format_white_space, indent,
552               format_ixge_rx_from_hw_descriptor, &t->before);
553   s = format (s, "\n%Uafter : head/tail address 0x%Lx/0x%Lx",
554               format_white_space, indent,
555               t->after.rx_to_hw.head_address,
556               t->after.rx_to_hw.tail_address);
557
558   s = format (s, "\n%Ubuffer 0x%x: %U",
559               format_white_space, indent,
560               t->buffer_index,
561               format_vlib_buffer, &t->buffer);
562
563   s = format (s, "\n%U",
564               format_white_space, indent);
565
566   f = node->format_buffer;
567   if (! f || ! t->is_start_of_packet)
568     f = format_hex_bytes;
569   s = format (s, "%U", f, t->buffer.pre_data, sizeof (t->buffer.pre_data));
570
571   return s;
572 }
573
574 #define foreach_ixge_error                                      \
575   _ (none, "no error")                                          \
576   _ (tx_full_drops, "tx ring full drops")                       \
577   _ (ip4_checksum_error, "ip4 checksum errors")                 \
578   _ (rx_alloc_fail, "rx buf alloc from free list failed")       \
579   _ (rx_alloc_no_physmem, "rx buf alloc failed no physmem")
580
581 typedef enum {
582 #define _(f,s) IXGE_ERROR_##f,
583   foreach_ixge_error
584 #undef _
585   IXGE_N_ERROR,
586 } ixge_error_t;
587
588 always_inline void
589 ixge_rx_next_and_error_from_status_x1 (ixge_device_t *xd,
590                                        u32 s00, u32 s02,
591                                        u8 * next0, u8 * error0, u32 * flags0)
592 {
593   u8 is0_ip4, is0_ip6, n0, e0;
594   u32 f0;
595
596   e0 = IXGE_ERROR_none;
597   n0 = IXGE_RX_NEXT_ETHERNET_INPUT;
598
599   is0_ip4 = s02 & IXGE_RX_DESCRIPTOR_STATUS2_IS_IP4_CHECKSUMMED;
600   n0 = is0_ip4 ? IXGE_RX_NEXT_IP4_INPUT : n0;
601
602   e0 = (is0_ip4 && (s02 & IXGE_RX_DESCRIPTOR_STATUS2_IP4_CHECKSUM_ERROR)
603         ? IXGE_ERROR_ip4_checksum_error
604         : e0);
605
606   is0_ip6 = s00 & IXGE_RX_DESCRIPTOR_STATUS0_IS_IP6;
607   n0 = is0_ip6 ? IXGE_RX_NEXT_IP6_INPUT : n0;
608
609   n0 = (xd->per_interface_next_index != ~0) ?
610     xd->per_interface_next_index : n0;
611
612   /* Check for error. */
613   n0 = e0 != IXGE_ERROR_none ? IXGE_RX_NEXT_DROP : n0;
614
615   f0 = ((s02 & (IXGE_RX_DESCRIPTOR_STATUS2_IS_TCP_CHECKSUMMED
616                 | IXGE_RX_DESCRIPTOR_STATUS2_IS_UDP_CHECKSUMMED))
617         ? IP_BUFFER_L4_CHECKSUM_COMPUTED
618         : 0);
619
620   f0 |= ((s02 & (IXGE_RX_DESCRIPTOR_STATUS2_TCP_CHECKSUM_ERROR
621                  | IXGE_RX_DESCRIPTOR_STATUS2_UDP_CHECKSUM_ERROR))
622          ? 0
623          : IP_BUFFER_L4_CHECKSUM_CORRECT);
624
625   *error0 = e0;
626   *next0 = n0;
627   *flags0 = f0;
628 }
629
630 always_inline void
631 ixge_rx_next_and_error_from_status_x2 (ixge_device_t *xd,
632                                        u32 s00, u32 s02,
633                                        u32 s10, u32 s12,
634                                        u8 * next0, u8 * error0, u32 * flags0,
635                                        u8 * next1, u8 * error1, u32 * flags1)
636 {
637   u8 is0_ip4, is0_ip6, n0, e0;
638   u8 is1_ip4, is1_ip6, n1, e1;
639   u32 f0, f1;
640
641   e0 = e1 = IXGE_ERROR_none;
642   n0 = n1 = IXGE_RX_NEXT_IP4_INPUT;
643
644   is0_ip4 = s02 & IXGE_RX_DESCRIPTOR_STATUS2_IS_IP4_CHECKSUMMED;
645   is1_ip4 = s12 & IXGE_RX_DESCRIPTOR_STATUS2_IS_IP4_CHECKSUMMED;
646
647   n0 = is0_ip4 ? IXGE_RX_NEXT_IP4_INPUT : n0;
648   n1 = is1_ip4 ? IXGE_RX_NEXT_IP4_INPUT : n1;
649
650   e0 = (is0_ip4 && (s02 & IXGE_RX_DESCRIPTOR_STATUS2_IP4_CHECKSUM_ERROR)
651         ? IXGE_ERROR_ip4_checksum_error
652         : e0);
653   e1 = (is1_ip4 && (s12 & IXGE_RX_DESCRIPTOR_STATUS2_IP4_CHECKSUM_ERROR)
654             ? IXGE_ERROR_ip4_checksum_error
655         : e1);
656
657   is0_ip6 = s00 & IXGE_RX_DESCRIPTOR_STATUS0_IS_IP6;
658   is1_ip6 = s10 & IXGE_RX_DESCRIPTOR_STATUS0_IS_IP6;
659
660   n0 = is0_ip6 ? IXGE_RX_NEXT_IP6_INPUT : n0;
661   n1 = is1_ip6 ? IXGE_RX_NEXT_IP6_INPUT : n1;
662
663   n0 = (xd->per_interface_next_index != ~0) ?
664     xd->per_interface_next_index : n0;
665   n1 = (xd->per_interface_next_index != ~0) ?
666     xd->per_interface_next_index : n1;
667
668   /* Check for error. */
669   n0 = e0 != IXGE_ERROR_none ? IXGE_RX_NEXT_DROP : n0;
670   n1 = e1 != IXGE_ERROR_none ? IXGE_RX_NEXT_DROP : n1;
671
672   *error0 = e0;
673   *error1 = e1;
674
675   *next0 = n0;
676   *next1 = n1;
677
678   f0 = ((s02 & (IXGE_RX_DESCRIPTOR_STATUS2_IS_TCP_CHECKSUMMED
679                 | IXGE_RX_DESCRIPTOR_STATUS2_IS_UDP_CHECKSUMMED))
680         ? IP_BUFFER_L4_CHECKSUM_COMPUTED
681         : 0);
682   f1 = ((s12 & (IXGE_RX_DESCRIPTOR_STATUS2_IS_TCP_CHECKSUMMED
683                 | IXGE_RX_DESCRIPTOR_STATUS2_IS_UDP_CHECKSUMMED))
684         ? IP_BUFFER_L4_CHECKSUM_COMPUTED
685         : 0);
686
687   f0 |= ((s02 & (IXGE_RX_DESCRIPTOR_STATUS2_TCP_CHECKSUM_ERROR
688                  | IXGE_RX_DESCRIPTOR_STATUS2_UDP_CHECKSUM_ERROR))
689          ? 0
690          : IP_BUFFER_L4_CHECKSUM_CORRECT);
691   f1 |= ((s12 & (IXGE_RX_DESCRIPTOR_STATUS2_TCP_CHECKSUM_ERROR
692                  | IXGE_RX_DESCRIPTOR_STATUS2_UDP_CHECKSUM_ERROR))
693          ? 0
694          : IP_BUFFER_L4_CHECKSUM_CORRECT);
695
696   *flags0 = f0;
697   *flags1 = f1;
698 }
699
700 static void
701 ixge_rx_trace (ixge_main_t * xm,
702                ixge_device_t * xd,
703                ixge_dma_queue_t * dq,
704                ixge_descriptor_t * before_descriptors,
705                u32 * before_buffers,
706                ixge_descriptor_t * after_descriptors,
707                uword n_descriptors)
708 {
709   vlib_main_t * vm = xm->vlib_main;
710   vlib_node_runtime_t * node = dq->rx.node;
711   ixge_rx_from_hw_descriptor_t * bd;
712   ixge_rx_to_hw_descriptor_t * ad;
713   u32 * b, n_left, is_sop, next_index_sop;
714
715   n_left = n_descriptors;
716   b = before_buffers;
717   bd = &before_descriptors->rx_from_hw;
718   ad = &after_descriptors->rx_to_hw;
719   is_sop = dq->rx.is_start_of_packet;
720   next_index_sop = dq->rx.saved_start_of_packet_next_index;
721
722   while (n_left >= 2)
723     {
724       u32 bi0, bi1, flags0, flags1;
725       vlib_buffer_t * b0, * b1;
726       ixge_rx_dma_trace_t * t0, * t1;
727       u8 next0, error0, next1, error1;
728
729       bi0 = b[0];
730       bi1 = b[1];
731       n_left -= 2;
732
733       b0 = vlib_get_buffer (vm, bi0);
734       b1 = vlib_get_buffer (vm, bi1);
735
736       ixge_rx_next_and_error_from_status_x2 (xd,
737                                              bd[0].status[0], bd[0].status[2],
738                                              bd[1].status[0], bd[1].status[2],
739                                              &next0, &error0, &flags0,
740                                              &next1, &error1, &flags1);
741
742       next_index_sop = is_sop ? next0 : next_index_sop;
743       vlib_trace_buffer (vm, node, next_index_sop, b0, /* follow_chain */ 0);
744       t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
745       t0->is_start_of_packet = is_sop;
746       is_sop = (b0->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
747
748       next_index_sop = is_sop ? next1 : next_index_sop;
749       vlib_trace_buffer (vm, node, next_index_sop, b1, /* follow_chain */ 0);
750       t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
751       t1->is_start_of_packet = is_sop;
752       is_sop = (b1->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
753
754       t0->queue_index = dq->queue_index;
755       t1->queue_index = dq->queue_index;
756       t0->device_index = xd->device_index;
757       t1->device_index = xd->device_index;
758       t0->before.rx_from_hw = bd[0];
759       t1->before.rx_from_hw = bd[1];
760       t0->after.rx_to_hw = ad[0];
761       t1->after.rx_to_hw = ad[1];
762       t0->buffer_index = bi0;
763       t1->buffer_index = bi1;
764       memcpy (&t0->buffer, b0, sizeof (b0[0]) - sizeof (b0->pre_data));
765       memcpy (&t1->buffer, b1, sizeof (b1[0]) - sizeof (b0->pre_data));
766       memcpy (t0->buffer.pre_data, b0->data + b0->current_data,
767               sizeof (t0->buffer.pre_data));
768       memcpy (t1->buffer.pre_data, b1->data + b1->current_data,
769               sizeof (t1->buffer.pre_data));
770
771       b += 2;
772       bd += 2;
773       ad += 2;
774     }
775
776   while (n_left >= 1)
777     {
778       u32 bi0, flags0;
779       vlib_buffer_t * b0;
780       ixge_rx_dma_trace_t * t0;
781       u8 next0, error0;
782
783       bi0 = b[0];
784       n_left -= 1;
785
786       b0 = vlib_get_buffer (vm, bi0);
787
788       ixge_rx_next_and_error_from_status_x1 (xd,
789                                              bd[0].status[0], bd[0].status[2],
790                                              &next0, &error0, &flags0);
791
792       next_index_sop = is_sop ? next0 : next_index_sop;
793       vlib_trace_buffer (vm, node, next_index_sop, b0, /* follow_chain */ 0);
794       t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
795       t0->is_start_of_packet = is_sop;
796       is_sop = (b0->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
797
798       t0->queue_index = dq->queue_index;
799       t0->device_index = xd->device_index;
800       t0->before.rx_from_hw = bd[0];
801       t0->after.rx_to_hw = ad[0];
802       t0->buffer_index = bi0;
803       memcpy (&t0->buffer, b0, sizeof (b0[0]) - sizeof (b0->pre_data));
804       memcpy (t0->buffer.pre_data, b0->data + b0->current_data,
805               sizeof (t0->buffer.pre_data));
806
807       b += 1;
808       bd += 1;
809       ad += 1;
810     }
811 }
812
813 typedef struct {
814   ixge_tx_descriptor_t descriptor;
815
816   u32 buffer_index;
817
818   u16 device_index;
819
820   u8 queue_index;
821
822   u8 is_start_of_packet;
823
824   /* Copy of VLIB buffer; packet data stored in pre_data. */
825   vlib_buffer_t buffer;
826 } ixge_tx_dma_trace_t;
827
828 static u8 * format_ixge_tx_dma_trace (u8 * s, va_list * va)
829 {
830   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
831   CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
832   ixge_tx_dma_trace_t * t = va_arg (*va, ixge_tx_dma_trace_t *);
833   vnet_main_t * vnm = vnet_get_main();
834   ixge_main_t * xm = &ixge_main;
835   ixge_device_t * xd = vec_elt_at_index (xm->devices, t->device_index);
836   format_function_t * f;
837   uword indent = format_get_indent (s);
838
839   {
840     vnet_sw_interface_t * sw = vnet_get_sw_interface (vnm, xd->vlib_sw_if_index);
841     s = format (s, "%U tx queue %d",
842                 format_vnet_sw_interface_name, vnm, sw,
843                 t->queue_index);
844   }
845
846   s = format (s, "\n%Udescriptor: %U",
847               format_white_space, indent,
848               format_ixge_tx_descriptor, &t->descriptor);
849
850   s = format (s, "\n%Ubuffer 0x%x: %U",
851               format_white_space, indent,
852               t->buffer_index,
853               format_vlib_buffer, &t->buffer);
854
855   s = format (s, "\n%U",
856               format_white_space, indent);
857
858   f = format_ethernet_header_with_length;
859   if (! f || ! t->is_start_of_packet)
860     f = format_hex_bytes;
861   s = format (s, "%U", f, t->buffer.pre_data, sizeof (t->buffer.pre_data));
862
863   return s;
864 }
865
866 typedef struct {
867   vlib_node_runtime_t * node;
868
869   u32 is_start_of_packet;
870
871   u32 n_bytes_in_packet;
872
873   ixge_tx_descriptor_t * start_of_packet_descriptor;
874 } ixge_tx_state_t;
875
876 static void
877 ixge_tx_trace (ixge_main_t * xm,
878                ixge_device_t * xd,
879                ixge_dma_queue_t * dq,
880                ixge_tx_state_t * tx_state,
881                ixge_tx_descriptor_t * descriptors,
882                u32 * buffers,
883                uword n_descriptors)
884 {
885   vlib_main_t * vm = xm->vlib_main;
886   vlib_node_runtime_t * node = tx_state->node;
887   ixge_tx_descriptor_t * d;
888   u32 * b, n_left, is_sop;
889
890   n_left = n_descriptors;
891   b = buffers;
892   d = descriptors;
893   is_sop = tx_state->is_start_of_packet;
894
895   while (n_left >= 2)
896     {
897       u32 bi0, bi1;
898       vlib_buffer_t * b0, * b1;
899       ixge_tx_dma_trace_t * t0, * t1;
900
901       bi0 = b[0];
902       bi1 = b[1];
903       n_left -= 2;
904
905       b0 = vlib_get_buffer (vm, bi0);
906       b1 = vlib_get_buffer (vm, bi1);
907
908       t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
909       t0->is_start_of_packet = is_sop;
910       is_sop = (b0->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
911
912       t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
913       t1->is_start_of_packet = is_sop;
914       is_sop = (b1->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
915
916       t0->queue_index = dq->queue_index;
917       t1->queue_index = dq->queue_index;
918       t0->device_index = xd->device_index;
919       t1->device_index = xd->device_index;
920       t0->descriptor = d[0];
921       t1->descriptor = d[1];
922       t0->buffer_index = bi0;
923       t1->buffer_index = bi1;
924       memcpy (&t0->buffer, b0, sizeof (b0[0]) - sizeof (b0->pre_data));
925       memcpy (&t1->buffer, b1, sizeof (b1[0]) - sizeof (b0->pre_data));
926       memcpy (t0->buffer.pre_data, b0->data + b0->current_data,
927               sizeof (t0->buffer.pre_data));
928       memcpy (t1->buffer.pre_data, b1->data + b1->current_data,
929               sizeof (t1->buffer.pre_data));
930
931       b += 2;
932       d += 2;
933     }
934
935   while (n_left >= 1)
936     {
937       u32 bi0;
938       vlib_buffer_t * b0;
939       ixge_tx_dma_trace_t * t0;
940
941       bi0 = b[0];
942       n_left -= 1;
943
944       b0 = vlib_get_buffer (vm, bi0);
945
946       t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
947       t0->is_start_of_packet = is_sop;
948       is_sop = (b0->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
949
950       t0->queue_index = dq->queue_index;
951       t0->device_index = xd->device_index;
952       t0->descriptor = d[0];
953       t0->buffer_index = bi0;
954       memcpy (&t0->buffer, b0, sizeof (b0[0]) - sizeof (b0->pre_data));
955       memcpy (t0->buffer.pre_data, b0->data + b0->current_data,
956               sizeof (t0->buffer.pre_data));
957
958       b += 1;
959       d += 1;
960     }
961 }
962
963 always_inline uword
964 ixge_ring_sub (ixge_dma_queue_t * q, u32 i0, u32 i1)
965 {
966   i32 d = i1 - i0;
967   ASSERT (i0 < q->n_descriptors);
968   ASSERT (i1 < q->n_descriptors);
969   return d < 0 ? q->n_descriptors + d : d;
970 }
971
972 always_inline uword
973 ixge_ring_add (ixge_dma_queue_t * q, u32 i0, u32 i1)
974 {
975   u32 d = i0 + i1;
976   ASSERT (i0 < q->n_descriptors);
977   ASSERT (i1 < q->n_descriptors);
978   d -= d >= q->n_descriptors ? q->n_descriptors : 0;
979   return d;
980 }
981
982 always_inline uword
983 ixge_tx_descriptor_matches_template (ixge_main_t * xm, ixge_tx_descriptor_t * d)
984 {
985   u32 cmp;
986
987   cmp = ((d->status0 & xm->tx_descriptor_template_mask.status0)
988          ^ xm->tx_descriptor_template.status0);
989   if (cmp)
990     return 0;
991   cmp = ((d->status1 & xm->tx_descriptor_template_mask.status1)
992          ^ xm->tx_descriptor_template.status1);
993   if (cmp)
994     return 0;
995
996   return 1;
997 }
998
999 static uword
1000 ixge_tx_no_wrap (ixge_main_t * xm,
1001                  ixge_device_t * xd,
1002                  ixge_dma_queue_t * dq,
1003                  u32 * buffers,
1004                  u32 start_descriptor_index,
1005                  u32 n_descriptors,
1006                  ixge_tx_state_t * tx_state)
1007 {
1008   vlib_main_t * vm = xm->vlib_main;
1009   ixge_tx_descriptor_t * d, * d_sop;
1010   u32 n_left = n_descriptors;
1011   u32 * to_free = vec_end (xm->tx_buffers_pending_free);
1012   u32 * to_tx = vec_elt_at_index (dq->descriptor_buffer_indices, start_descriptor_index);
1013   u32 is_sop = tx_state->is_start_of_packet;
1014   u32 len_sop = tx_state->n_bytes_in_packet;
1015   u16 template_status = xm->tx_descriptor_template.status0;
1016   u32 descriptor_prefetch_rotor = 0;
1017
1018   ASSERT (start_descriptor_index + n_descriptors <= dq->n_descriptors);
1019   d = &dq->descriptors[start_descriptor_index].tx;
1020   d_sop = is_sop ? d : tx_state->start_of_packet_descriptor;
1021
1022   while (n_left >= 4)
1023     {
1024       vlib_buffer_t * b0, * b1;
1025       u32 bi0, fi0, len0;
1026       u32 bi1, fi1, len1;
1027       u8 is_eop0, is_eop1;
1028
1029       /* Prefetch next iteration. */
1030       vlib_prefetch_buffer_with_index (vm, buffers[2], LOAD);
1031       vlib_prefetch_buffer_with_index (vm, buffers[3], LOAD);
1032
1033       if ((descriptor_prefetch_rotor & 0x3) == 0)
1034         CLIB_PREFETCH (d + 4, CLIB_CACHE_LINE_BYTES, STORE);
1035
1036       descriptor_prefetch_rotor += 2;
1037
1038       bi0 = buffers[0];
1039       bi1 = buffers[1];
1040
1041       to_free[0] = fi0 = to_tx[0];
1042       to_tx[0] = bi0;
1043       to_free += fi0 != 0;
1044
1045       to_free[0] = fi1 = to_tx[1];
1046       to_tx[1] = bi1;
1047       to_free += fi1 != 0;
1048
1049       buffers += 2;
1050       n_left -= 2;
1051       to_tx += 2;
1052
1053       b0 = vlib_get_buffer (vm, bi0);
1054       b1 = vlib_get_buffer (vm, bi1);
1055
1056       is_eop0 = (b0->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
1057       is_eop1 = (b1->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
1058
1059       len0 = b0->current_length;
1060       len1 = b1->current_length;
1061
1062       ASSERT (ixge_tx_descriptor_matches_template (xm, d + 0));
1063       ASSERT (ixge_tx_descriptor_matches_template (xm, d + 1));
1064
1065       d[0].buffer_address = vlib_get_buffer_data_physical_address (vm, bi0) + b0->current_data;
1066       d[1].buffer_address = vlib_get_buffer_data_physical_address (vm, bi1) + b1->current_data;
1067
1068       d[0].n_bytes_this_buffer = len0;
1069       d[1].n_bytes_this_buffer = len1;
1070
1071       d[0].status0 = template_status | (is_eop0 << IXGE_TX_DESCRIPTOR_STATUS0_LOG2_IS_END_OF_PACKET);
1072       d[1].status0 = template_status | (is_eop1 << IXGE_TX_DESCRIPTOR_STATUS0_LOG2_IS_END_OF_PACKET);
1073
1074       len_sop = (is_sop ? 0 : len_sop) + len0;
1075       d_sop[0].status1 = IXGE_TX_DESCRIPTOR_STATUS1_N_BYTES_IN_PACKET (len_sop);
1076       d += 1;
1077       d_sop = is_eop0 ? d : d_sop;
1078
1079       is_sop = is_eop0;
1080
1081       len_sop = (is_sop ? 0 : len_sop) + len1;
1082       d_sop[0].status1 = IXGE_TX_DESCRIPTOR_STATUS1_N_BYTES_IN_PACKET (len_sop);
1083       d += 1;
1084       d_sop = is_eop1 ? d : d_sop;
1085
1086       is_sop = is_eop1;
1087     }
1088
1089   while (n_left > 0)
1090     {
1091       vlib_buffer_t * b0;
1092       u32 bi0, fi0, len0;
1093       u8 is_eop0;
1094
1095       bi0 = buffers[0];
1096
1097       to_free[0] = fi0 = to_tx[0];
1098       to_tx[0] = bi0;
1099       to_free += fi0 != 0;
1100
1101       buffers += 1;
1102       n_left -= 1;
1103       to_tx += 1;
1104
1105       b0 = vlib_get_buffer (vm, bi0);
1106
1107       is_eop0 = (b0->flags & VLIB_BUFFER_NEXT_PRESENT) == 0;
1108
1109       len0 = b0->current_length;
1110
1111       ASSERT (ixge_tx_descriptor_matches_template (xm, d + 0));
1112
1113       d[0].buffer_address = vlib_get_buffer_data_physical_address (vm, bi0) + b0->current_data;
1114
1115       d[0].n_bytes_this_buffer = len0;
1116
1117       d[0].status0 = template_status | (is_eop0 << IXGE_TX_DESCRIPTOR_STATUS0_LOG2_IS_END_OF_PACKET);
1118
1119       len_sop = (is_sop ? 0 : len_sop) + len0;
1120       d_sop[0].status1 = IXGE_TX_DESCRIPTOR_STATUS1_N_BYTES_IN_PACKET (len_sop);
1121       d += 1;
1122       d_sop = is_eop0 ? d : d_sop;
1123
1124       is_sop = is_eop0;
1125     }
1126
1127   if (tx_state->node->flags & VLIB_NODE_FLAG_TRACE)
1128     {
1129       to_tx = vec_elt_at_index (dq->descriptor_buffer_indices, start_descriptor_index);
1130       ixge_tx_trace (xm, xd, dq, tx_state,
1131                      &dq->descriptors[start_descriptor_index].tx,
1132                      to_tx,
1133                      n_descriptors);
1134     }
1135
1136   _vec_len (xm->tx_buffers_pending_free) = to_free - xm->tx_buffers_pending_free;
1137
1138   /* When we are done d_sop can point to end of ring.  Wrap it if so. */
1139   {
1140     ixge_tx_descriptor_t * d_start = &dq->descriptors[0].tx;
1141
1142     ASSERT (d_sop - d_start <= dq->n_descriptors);
1143     d_sop = d_sop - d_start == dq->n_descriptors ? d_start : d_sop;
1144   }
1145
1146   tx_state->is_start_of_packet = is_sop;
1147   tx_state->start_of_packet_descriptor = d_sop;
1148   tx_state->n_bytes_in_packet = len_sop;
1149
1150   return n_descriptors;
1151 }
1152
1153 static uword
1154 ixge_interface_tx (vlib_main_t * vm,
1155                    vlib_node_runtime_t * node,
1156                    vlib_frame_t * f)
1157 {
1158   ixge_main_t * xm = &ixge_main;
1159   vnet_interface_output_runtime_t * rd = (void *) node->runtime_data;
1160   ixge_device_t * xd = vec_elt_at_index (xm->devices, rd->dev_instance);
1161   ixge_dma_queue_t * dq;
1162   u32 * from, n_left_tx, n_descriptors_to_tx, n_tail_drop;
1163   u32 queue_index = 0;          /* fixme parameter */
1164   ixge_tx_state_t tx_state;
1165
1166   tx_state.node = node;
1167   tx_state.is_start_of_packet = 1;
1168   tx_state.start_of_packet_descriptor = 0;
1169   tx_state.n_bytes_in_packet = 0;
1170
1171   from = vlib_frame_vector_args (f);
1172
1173   dq = vec_elt_at_index (xd->dma_queues[VLIB_TX], queue_index);
1174
1175   dq->head_index = dq->tx.head_index_write_back[0];
1176
1177   /* Since head == tail means ring is empty we can send up to dq->n_descriptors - 1. */
1178   n_left_tx = dq->n_descriptors - 1;
1179   n_left_tx -= ixge_ring_sub (dq, dq->head_index, dq->tail_index);
1180
1181   _vec_len (xm->tx_buffers_pending_free) = 0;
1182
1183   n_descriptors_to_tx = f->n_vectors;
1184   n_tail_drop = 0;
1185   if (PREDICT_FALSE (n_descriptors_to_tx > n_left_tx))
1186     {
1187       i32 i, n_ok, i_eop, i_sop;
1188
1189       i_sop = i_eop = ~0;
1190       for (i = n_left_tx - 1; i >= 0; i--)
1191         {
1192           vlib_buffer_t * b = vlib_get_buffer (vm, from[i]);
1193           if (! (b->flags & VLIB_BUFFER_NEXT_PRESENT))
1194             {
1195               if (i_sop != ~0 && i_eop != ~0)
1196                 break;
1197               i_eop = i;
1198               i_sop = i + 1;
1199             }
1200         }
1201       if (i == 0)
1202         n_ok = 0;
1203       else
1204         n_ok = i_eop + 1;
1205
1206       {
1207         ELOG_TYPE_DECLARE (e) = {
1208           .function = (char *) __FUNCTION__,
1209           .format = "ixge %d, ring full to tx %d head %d tail %d",
1210           .format_args = "i2i2i2i2",
1211         };
1212         struct { u16 instance, to_tx, head, tail; } * ed;
1213         ed = ELOG_DATA (&vm->elog_main, e);
1214         ed->instance = xd->device_index;
1215         ed->to_tx = n_descriptors_to_tx;
1216         ed->head = dq->head_index;
1217         ed->tail = dq->tail_index;
1218       }
1219
1220       if (n_ok < n_descriptors_to_tx)
1221         {
1222           n_tail_drop = n_descriptors_to_tx - n_ok;
1223           vec_add (xm->tx_buffers_pending_free, from + n_ok, n_tail_drop);
1224           vlib_error_count (vm, ixge_input_node.index, IXGE_ERROR_tx_full_drops, n_tail_drop);
1225         }
1226
1227       n_descriptors_to_tx = n_ok;
1228     }
1229
1230   dq->tx.n_buffers_on_ring += n_descriptors_to_tx;
1231
1232   /* Process from tail to end of descriptor ring. */
1233   if (n_descriptors_to_tx > 0 && dq->tail_index < dq->n_descriptors)
1234     {
1235       u32 n = clib_min (dq->n_descriptors - dq->tail_index, n_descriptors_to_tx);
1236       n = ixge_tx_no_wrap (xm, xd, dq, from, dq->tail_index, n, &tx_state);
1237       from += n;
1238       n_descriptors_to_tx -= n;
1239       dq->tail_index += n;
1240       ASSERT (dq->tail_index <= dq->n_descriptors);
1241       if (dq->tail_index == dq->n_descriptors)
1242         dq->tail_index = 0;
1243     }
1244
1245   if (n_descriptors_to_tx > 0)
1246     {
1247       u32 n = ixge_tx_no_wrap (xm, xd, dq, from, 0, n_descriptors_to_tx, &tx_state);
1248       from += n;
1249       ASSERT (n == n_descriptors_to_tx);
1250       dq->tail_index += n;
1251       ASSERT (dq->tail_index <= dq->n_descriptors);
1252       if (dq->tail_index == dq->n_descriptors)
1253         dq->tail_index = 0;
1254     }
1255
1256   /* We should only get full packets. */
1257   ASSERT (tx_state.is_start_of_packet);
1258
1259   /* Report status when last descriptor is done. */
1260   {
1261     u32 i = dq->tail_index == 0 ? dq->n_descriptors - 1 : dq->tail_index - 1;
1262     ixge_tx_descriptor_t * d = &dq->descriptors[i].tx;
1263     d->status0 |= IXGE_TX_DESCRIPTOR_STATUS0_REPORT_STATUS;
1264   }
1265
1266   /* Give new descriptors to hardware. */
1267   {
1268     ixge_dma_regs_t * dr = get_dma_regs (xd, VLIB_TX, queue_index);
1269
1270     CLIB_MEMORY_BARRIER ();
1271
1272     dr->tail_index = dq->tail_index;
1273   }
1274
1275   /* Free any buffers that are done. */
1276   {
1277     u32 n = _vec_len (xm->tx_buffers_pending_free);
1278     if (n > 0)
1279       {
1280         vlib_buffer_free_no_next (vm, xm->tx_buffers_pending_free, n);
1281         _vec_len (xm->tx_buffers_pending_free) = 0;
1282         ASSERT (dq->tx.n_buffers_on_ring >= n);
1283         dq->tx.n_buffers_on_ring -= (n - n_tail_drop);
1284       }
1285   }
1286
1287   return f->n_vectors;
1288 }
1289
1290 static uword
1291 ixge_rx_queue_no_wrap (ixge_main_t * xm,
1292                        ixge_device_t * xd,
1293                        ixge_dma_queue_t * dq,
1294                        u32 start_descriptor_index,
1295                        u32 n_descriptors)
1296 {
1297   vlib_main_t * vm = xm->vlib_main;
1298   vlib_node_runtime_t * node = dq->rx.node;
1299   ixge_descriptor_t * d;
1300   static ixge_descriptor_t * d_trace_save;
1301   static u32 * d_trace_buffers;
1302   u32 n_descriptors_left = n_descriptors;
1303   u32 * to_rx = vec_elt_at_index (dq->descriptor_buffer_indices, start_descriptor_index);
1304   u32 * to_add;
1305   u32 bi_sop = dq->rx.saved_start_of_packet_buffer_index;
1306   u32 bi_last = dq->rx.saved_last_buffer_index;
1307   u32 next_index_sop = dq->rx.saved_start_of_packet_next_index;
1308   u32 is_sop = dq->rx.is_start_of_packet;
1309   u32 next_index, n_left_to_next, * to_next;
1310   u32 n_packets = 0;
1311   u32 n_bytes = 0;
1312   u32 n_trace = vlib_get_trace_count (vm, node);
1313   vlib_buffer_t * b_last, b_dummy;
1314
1315   ASSERT (start_descriptor_index + n_descriptors <= dq->n_descriptors);
1316   d = &dq->descriptors[start_descriptor_index];
1317
1318   b_last = bi_last != ~0 ? vlib_get_buffer (vm, bi_last) : &b_dummy;
1319   next_index = dq->rx.next_index;
1320
1321   if (n_trace > 0)
1322     {
1323       u32 n = clib_min (n_trace, n_descriptors);
1324       if (d_trace_save)
1325         {
1326           _vec_len (d_trace_save) = 0;
1327           _vec_len (d_trace_buffers) = 0;
1328         }
1329       vec_add (d_trace_save, (ixge_descriptor_t *) d, n);
1330       vec_add (d_trace_buffers, to_rx, n);
1331     }
1332
1333   {
1334     uword l = vec_len (xm->rx_buffers_to_add);
1335
1336     if (l < n_descriptors_left)
1337       {
1338         u32 n_to_alloc = 2 * dq->n_descriptors - l;
1339         u32 n_allocated;
1340
1341         vec_resize (xm->rx_buffers_to_add, n_to_alloc);
1342
1343         _vec_len (xm->rx_buffers_to_add) = l;
1344         n_allocated = vlib_buffer_alloc_from_free_list
1345           (vm, xm->rx_buffers_to_add + l, n_to_alloc,
1346            xm->vlib_buffer_free_list_index);
1347         _vec_len (xm->rx_buffers_to_add) += n_allocated;
1348
1349         /* Handle transient allocation failure */
1350         if (PREDICT_FALSE(l + n_allocated <= n_descriptors_left))
1351           {
1352             if (n_allocated == 0)
1353               vlib_error_count (vm, ixge_input_node.index,
1354                                 IXGE_ERROR_rx_alloc_no_physmem, 1);
1355             else
1356               vlib_error_count (vm, ixge_input_node.index,
1357                                 IXGE_ERROR_rx_alloc_fail, 1);
1358
1359             n_descriptors_left = l + n_allocated;
1360           }
1361         n_descriptors = n_descriptors_left;
1362       }
1363
1364     /* Add buffers from end of vector going backwards. */
1365     to_add = vec_end (xm->rx_buffers_to_add) - 1;
1366   }
1367
1368   while (n_descriptors_left > 0)
1369     {
1370       vlib_get_next_frame (vm, node, next_index,
1371                            to_next, n_left_to_next);
1372
1373       while (n_descriptors_left >= 4 && n_left_to_next >= 2)
1374         {
1375           vlib_buffer_t * b0, * b1;
1376           u32 bi0, fi0, len0, l3_offset0, s20, s00, flags0;
1377           u32 bi1, fi1, len1, l3_offset1, s21, s01, flags1;
1378           u8 is_eop0, error0, next0;
1379           u8 is_eop1, error1, next1;
1380           ixge_descriptor_t d0, d1;
1381
1382           vlib_prefetch_buffer_with_index (vm, to_rx[2], STORE);
1383           vlib_prefetch_buffer_with_index (vm, to_rx[3], STORE);
1384
1385           CLIB_PREFETCH (d + 2, 32, STORE);
1386
1387           d0.as_u32x4 = d[0].as_u32x4;
1388           d1.as_u32x4 = d[1].as_u32x4;
1389
1390           s20 = d0.rx_from_hw.status[2];
1391           s21 = d1.rx_from_hw.status[2];
1392
1393           s00 = d0.rx_from_hw.status[0];
1394           s01 = d1.rx_from_hw.status[0];
1395
1396           if (! ((s20 & s21) & IXGE_RX_DESCRIPTOR_STATUS2_IS_OWNED_BY_SOFTWARE))
1397             goto found_hw_owned_descriptor_x2;
1398
1399           bi0 = to_rx[0];
1400           bi1 = to_rx[1];
1401
1402           ASSERT (to_add - 1 >= xm->rx_buffers_to_add);
1403           fi0 = to_add[0];
1404           fi1 = to_add[-1];
1405
1406           to_rx[0] = fi0;
1407           to_rx[1] = fi1;
1408           to_rx += 2;
1409           to_add -= 2;
1410
1411           ASSERT (VLIB_BUFFER_KNOWN_ALLOCATED == vlib_buffer_is_known (vm, bi0));
1412           ASSERT (VLIB_BUFFER_KNOWN_ALLOCATED == vlib_buffer_is_known (vm, bi1));
1413           ASSERT (VLIB_BUFFER_KNOWN_ALLOCATED == vlib_buffer_is_known (vm, fi0));
1414           ASSERT (VLIB_BUFFER_KNOWN_ALLOCATED == vlib_buffer_is_known (vm, fi1));
1415
1416           b0 = vlib_get_buffer (vm, bi0);
1417           b1 = vlib_get_buffer (vm, bi1);
1418
1419           /*
1420            * Turn this on if you run into
1421            * "bad monkey" contexts, and you want to know exactly
1422            * which nodes they've visited... See main.c...
1423            */
1424           VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b0);
1425           VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b1);
1426
1427           CLIB_PREFETCH (b0->data, CLIB_CACHE_LINE_BYTES, LOAD);
1428           CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES, LOAD);
1429
1430           is_eop0 = (s20 & IXGE_RX_DESCRIPTOR_STATUS2_IS_END_OF_PACKET) != 0;
1431           is_eop1 = (s21 & IXGE_RX_DESCRIPTOR_STATUS2_IS_END_OF_PACKET) != 0;
1432
1433           ixge_rx_next_and_error_from_status_x2 (xd, s00, s20, s01, s21,
1434                                                  &next0, &error0, &flags0,
1435                                                  &next1, &error1, &flags1);
1436
1437           next0 = is_sop ? next0 : next_index_sop;
1438           next1 = is_eop0 ? next1 : next0;
1439           next_index_sop = next1;
1440
1441           b0->flags |= flags0 | (!is_eop0 << VLIB_BUFFER_LOG2_NEXT_PRESENT);
1442           b1->flags |= flags1 | (!is_eop1 << VLIB_BUFFER_LOG2_NEXT_PRESENT);
1443
1444           vnet_buffer (b0)->sw_if_index[VLIB_RX] = xd->vlib_sw_if_index;
1445           vnet_buffer (b1)->sw_if_index[VLIB_RX] = xd->vlib_sw_if_index;
1446           vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32)~0;
1447           vnet_buffer (b1)->sw_if_index[VLIB_TX] = (u32)~0;
1448
1449           b0->error = node->errors[error0];
1450           b1->error = node->errors[error1];
1451
1452           len0 = d0.rx_from_hw.n_packet_bytes_this_descriptor;
1453           len1 = d1.rx_from_hw.n_packet_bytes_this_descriptor;
1454           n_bytes += len0 + len1;
1455           n_packets += is_eop0 + is_eop1;
1456
1457           /* Give new buffers to hardware. */
1458           d0.rx_to_hw.tail_address =
1459               vlib_get_buffer_data_physical_address (vm, fi0);
1460           d1.rx_to_hw.tail_address =
1461               vlib_get_buffer_data_physical_address (vm, fi1);
1462           d0.rx_to_hw.head_address = d[0].rx_to_hw.tail_address;
1463           d1.rx_to_hw.head_address = d[1].rx_to_hw.tail_address;
1464           d[0].as_u32x4 = d0.as_u32x4;
1465           d[1].as_u32x4 = d1.as_u32x4;
1466
1467           d += 2;
1468           n_descriptors_left -= 2;
1469
1470           /* Point to either l2 or l3 header depending on next. */
1471           l3_offset0 = (is_sop && (next0 != IXGE_RX_NEXT_ETHERNET_INPUT))
1472               ? IXGE_RX_DESCRIPTOR_STATUS0_L3_OFFSET (s00)
1473               : 0;
1474           l3_offset1 = (is_eop0 && (next1 != IXGE_RX_NEXT_ETHERNET_INPUT))
1475               ? IXGE_RX_DESCRIPTOR_STATUS0_L3_OFFSET (s01)
1476               : 0;
1477
1478           b0->current_length = len0 - l3_offset0;
1479           b1->current_length = len1 - l3_offset1;
1480           b0->current_data = l3_offset0;
1481           b1->current_data = l3_offset1;
1482
1483           b_last->next_buffer = is_sop ? ~0 : bi0;
1484           b0->next_buffer = is_eop0 ? ~0 : bi1;
1485           bi_last = bi1;
1486           b_last = b1;
1487
1488           if (CLIB_DEBUG > 0)
1489             {
1490               u32 bi_sop0 = is_sop ? bi0 : bi_sop;
1491               u32 bi_sop1 = is_eop0 ? bi1 : bi_sop0;
1492
1493               if (is_eop0)
1494                 {
1495                   u8 * msg = vlib_validate_buffer (vm, bi_sop0, /* follow_buffer_next */ 1);
1496                   ASSERT (! msg);
1497                 }
1498               if (is_eop1)
1499                 {
1500                   u8 * msg = vlib_validate_buffer (vm, bi_sop1, /* follow_buffer_next */ 1);
1501                   ASSERT (! msg);
1502                 }
1503             }
1504           if (0) /* "Dave" version */
1505             {
1506               u32 bi_sop0 = is_sop ? bi0 : bi_sop;
1507               u32 bi_sop1 = is_eop0 ? bi1 : bi_sop0;
1508
1509               if (is_eop0)
1510                 {
1511                   to_next[0] = bi_sop0;
1512                   to_next++;
1513                   n_left_to_next--;
1514
1515                   vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
1516                                                    to_next, n_left_to_next,
1517                                                    bi_sop0, next0);
1518                 }
1519               if (is_eop1)
1520                 {
1521                   to_next[0] = bi_sop1;
1522                   to_next++;
1523                   n_left_to_next--;
1524
1525                   vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
1526                                                    to_next, n_left_to_next,
1527                                                    bi_sop1, next1);
1528                 }
1529               is_sop = is_eop1;
1530               bi_sop = bi_sop1;
1531             }
1532           if (1) /* "Eliot" version */
1533             {
1534               /* Speculatively enqueue to cached next. */
1535               u8 saved_is_sop = is_sop;
1536               u32 bi_sop_save = bi_sop;
1537
1538               bi_sop = saved_is_sop ? bi0 : bi_sop;
1539               to_next[0] = bi_sop;
1540               to_next += is_eop0;
1541               n_left_to_next -= is_eop0;
1542
1543               bi_sop = is_eop0 ? bi1 : bi_sop;
1544               to_next[0] = bi_sop;
1545               to_next += is_eop1;
1546               n_left_to_next -= is_eop1;
1547
1548               is_sop = is_eop1;
1549
1550               if (PREDICT_FALSE (! (next0 == next_index && next1 == next_index)))
1551                 {
1552                   /* Undo speculation. */
1553                   to_next -= is_eop0 + is_eop1;
1554                   n_left_to_next += is_eop0 + is_eop1;
1555
1556                   /* Re-do both descriptors being careful about where we enqueue. */
1557                   bi_sop = saved_is_sop ? bi0 : bi_sop_save;
1558                   if (is_eop0)
1559                     {
1560                       if (next0 != next_index)
1561                         vlib_set_next_frame_buffer (vm, node, next0, bi_sop);
1562                       else
1563                         {
1564                           to_next[0] = bi_sop;
1565                           to_next += 1;
1566                           n_left_to_next -= 1;
1567                         }
1568                     }
1569
1570                   bi_sop = is_eop0 ? bi1 : bi_sop;
1571                   if (is_eop1)
1572                     {
1573                       if (next1 != next_index)
1574                         vlib_set_next_frame_buffer (vm, node, next1, bi_sop);
1575                       else
1576                         {
1577                           to_next[0] = bi_sop;
1578                           to_next += 1;
1579                           n_left_to_next -= 1;
1580                         }
1581                     }
1582
1583                   /* Switch cached next index when next for both packets is the same. */
1584                   if (is_eop0 && is_eop1 && next0 == next1)
1585                     {
1586                       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1587                       next_index = next0;
1588                       vlib_get_next_frame (vm, node, next_index,
1589                                            to_next, n_left_to_next);
1590                     }
1591                 }
1592             }
1593         }
1594
1595     /* Bail out of dual loop and proceed with single loop. */
1596     found_hw_owned_descriptor_x2:
1597
1598       while (n_descriptors_left > 0 && n_left_to_next > 0)
1599         {
1600           vlib_buffer_t * b0;
1601           u32 bi0, fi0, len0, l3_offset0, s20, s00, flags0;
1602           u8 is_eop0, error0, next0;
1603           ixge_descriptor_t d0;
1604
1605           d0.as_u32x4 = d[0].as_u32x4;
1606
1607           s20 = d0.rx_from_hw.status[2];
1608           s00 = d0.rx_from_hw.status[0];
1609
1610           if (! (s20 & IXGE_RX_DESCRIPTOR_STATUS2_IS_OWNED_BY_SOFTWARE))
1611             goto found_hw_owned_descriptor_x1;
1612
1613           bi0 = to_rx[0];
1614           ASSERT (to_add >= xm->rx_buffers_to_add);
1615           fi0 = to_add[0];
1616
1617           to_rx[0] = fi0;
1618           to_rx += 1;
1619           to_add -= 1;
1620
1621           ASSERT (VLIB_BUFFER_KNOWN_ALLOCATED == vlib_buffer_is_known (vm, bi0));
1622           ASSERT (VLIB_BUFFER_KNOWN_ALLOCATED == vlib_buffer_is_known (vm, fi0));
1623
1624           b0 = vlib_get_buffer (vm, bi0);
1625
1626           /*
1627            * Turn this on if you run into
1628            * "bad monkey" contexts, and you want to know exactly
1629            * which nodes they've visited...
1630            */
1631           VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b0);
1632
1633           is_eop0 = (s20 & IXGE_RX_DESCRIPTOR_STATUS2_IS_END_OF_PACKET) != 0;
1634           ixge_rx_next_and_error_from_status_x1
1635             (xd, s00, s20, &next0, &error0, &flags0);
1636
1637           next0 = is_sop ? next0 : next_index_sop;
1638           next_index_sop = next0;
1639
1640           b0->flags |= flags0 | (!is_eop0 << VLIB_BUFFER_LOG2_NEXT_PRESENT);
1641
1642           vnet_buffer (b0)->sw_if_index[VLIB_RX] = xd->vlib_sw_if_index;
1643           vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32)~0;
1644
1645           b0->error = node->errors[error0];
1646
1647           len0 = d0.rx_from_hw.n_packet_bytes_this_descriptor;
1648           n_bytes += len0;
1649           n_packets += is_eop0;
1650
1651           /* Give new buffer to hardware. */
1652           d0.rx_to_hw.tail_address =
1653               vlib_get_buffer_data_physical_address (vm, fi0);
1654           d0.rx_to_hw.head_address = d0.rx_to_hw.tail_address;
1655           d[0].as_u32x4 = d0.as_u32x4;
1656
1657           d += 1;
1658           n_descriptors_left -= 1;
1659
1660           /* Point to either l2 or l3 header depending on next. */
1661           l3_offset0 = (is_sop && (next0 != IXGE_RX_NEXT_ETHERNET_INPUT))
1662               ? IXGE_RX_DESCRIPTOR_STATUS0_L3_OFFSET (s00)
1663               : 0;
1664           b0->current_length = len0 - l3_offset0;
1665           b0->current_data = l3_offset0;
1666
1667           b_last->next_buffer = is_sop ? ~0 : bi0;
1668           bi_last = bi0;
1669           b_last = b0;
1670
1671           bi_sop = is_sop ? bi0 : bi_sop;
1672
1673           if (CLIB_DEBUG > 0 && is_eop0)
1674             {
1675               u8 * msg = vlib_validate_buffer (vm, bi_sop, /* follow_buffer_next */ 1);
1676               ASSERT (! msg);
1677             }
1678
1679           if (0) /* "Dave" version */
1680             {
1681               if (is_eop0)
1682                 {
1683                   to_next[0] = bi_sop;
1684                   to_next++;
1685                   n_left_to_next--;
1686
1687                   vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
1688                                                    to_next, n_left_to_next,
1689                                                    bi_sop, next0);
1690                 }
1691             }
1692           if (1) /* "Eliot" version */
1693             {
1694               if (PREDICT_TRUE (next0 == next_index))
1695                 {
1696                   to_next[0] = bi_sop;
1697                   to_next += is_eop0;
1698                   n_left_to_next -= is_eop0;
1699                 }
1700               else
1701                 {
1702                   if (next0 != next_index && is_eop0)
1703                     vlib_set_next_frame_buffer (vm, node, next0, bi_sop);
1704
1705                   vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1706                   next_index = next0;
1707                   vlib_get_next_frame (vm, node, next_index,
1708                                        to_next, n_left_to_next);
1709                 }
1710             }
1711           is_sop = is_eop0;
1712         }
1713       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1714     }
1715
1716  found_hw_owned_descriptor_x1:
1717   if (n_descriptors_left > 0)
1718     vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1719
1720   _vec_len (xm->rx_buffers_to_add) = (to_add + 1) - xm->rx_buffers_to_add;
1721
1722   {
1723     u32 n_done = n_descriptors - n_descriptors_left;
1724
1725     if (n_trace > 0 && n_done > 0)
1726       {
1727         u32 n = clib_min (n_trace, n_done);
1728         ixge_rx_trace (xm, xd, dq,
1729                        d_trace_save,
1730                        d_trace_buffers,
1731                        &dq->descriptors[start_descriptor_index],
1732                        n);
1733         vlib_set_trace_count (vm, node, n_trace - n);
1734       }
1735     if (d_trace_save)
1736       {
1737         _vec_len (d_trace_save) = 0;
1738         _vec_len (d_trace_buffers) = 0;
1739       }
1740
1741     /* Don't keep a reference to b_last if we don't have to.
1742        Otherwise we can over-write a next_buffer pointer after already haven
1743        enqueued a packet. */
1744     if (is_sop)
1745       {
1746         b_last->next_buffer = ~0;
1747         bi_last = ~0;
1748       }
1749
1750     dq->rx.n_descriptors_done_this_call = n_done;
1751     dq->rx.n_descriptors_done_total += n_done;
1752     dq->rx.is_start_of_packet = is_sop;
1753     dq->rx.saved_start_of_packet_buffer_index = bi_sop;
1754     dq->rx.saved_last_buffer_index = bi_last;
1755     dq->rx.saved_start_of_packet_next_index = next_index_sop;
1756     dq->rx.next_index = next_index;
1757     dq->rx.n_bytes += n_bytes;
1758
1759     return n_packets;
1760   }
1761 }
1762
1763 static uword
1764 ixge_rx_queue (ixge_main_t * xm,
1765                ixge_device_t * xd,
1766                vlib_node_runtime_t * node,
1767                u32 queue_index)
1768 {
1769   ixge_dma_queue_t * dq = vec_elt_at_index (xd->dma_queues[VLIB_RX], queue_index);
1770   ixge_dma_regs_t * dr = get_dma_regs (xd, VLIB_RX, dq->queue_index);
1771   uword n_packets = 0;
1772   u32 hw_head_index, sw_head_index;
1773
1774   /* One time initialization. */
1775   if (! dq->rx.node)
1776     {
1777       dq->rx.node = node;
1778       dq->rx.is_start_of_packet = 1;
1779       dq->rx.saved_start_of_packet_buffer_index = ~0;
1780       dq->rx.saved_last_buffer_index = ~0;
1781     }
1782
1783   dq->rx.next_index = node->cached_next_index;
1784
1785   dq->rx.n_descriptors_done_total = 0;
1786   dq->rx.n_descriptors_done_this_call = 0;
1787   dq->rx.n_bytes = 0;
1788
1789   /* Fetch head from hardware and compare to where we think we are. */
1790   hw_head_index = dr->head_index;
1791   sw_head_index = dq->head_index;
1792
1793   if (hw_head_index == sw_head_index)
1794     goto done;
1795
1796   if (hw_head_index < sw_head_index)
1797     {
1798       u32 n_tried = dq->n_descriptors - sw_head_index;
1799       n_packets += ixge_rx_queue_no_wrap (xm, xd, dq, sw_head_index, n_tried);
1800       sw_head_index = ixge_ring_add (dq, sw_head_index, dq->rx.n_descriptors_done_this_call);
1801
1802       if (dq->rx.n_descriptors_done_this_call != n_tried)
1803         goto done;
1804     }
1805   if (hw_head_index >= sw_head_index)
1806     {
1807       u32 n_tried = hw_head_index - sw_head_index;
1808       n_packets += ixge_rx_queue_no_wrap (xm, xd, dq, sw_head_index, n_tried);
1809       sw_head_index = ixge_ring_add (dq, sw_head_index, dq->rx.n_descriptors_done_this_call);
1810     }
1811
1812  done:
1813   dq->head_index = sw_head_index;
1814   dq->tail_index = ixge_ring_add (dq, dq->tail_index, dq->rx.n_descriptors_done_total);
1815
1816   /* Give tail back to hardware. */
1817   CLIB_MEMORY_BARRIER ();
1818
1819   dr->tail_index = dq->tail_index;
1820
1821   vlib_increment_combined_counter (vnet_main.interface_main.combined_sw_if_counters
1822                                    + VNET_INTERFACE_COUNTER_RX,
1823                                    0 /* cpu_index */,
1824                                    xd->vlib_sw_if_index,
1825                                    n_packets,
1826                                    dq->rx.n_bytes);
1827
1828   return n_packets;
1829 }
1830
1831 static void ixge_interrupt (ixge_main_t * xm, ixge_device_t * xd, u32 i)
1832 {
1833   vlib_main_t * vm = xm->vlib_main;
1834   ixge_regs_t * r = xd->regs;
1835
1836   if (i != 20)
1837     {
1838       ELOG_TYPE_DECLARE (e) = {
1839         .function = (char *) __FUNCTION__,
1840         .format = "ixge %d, %s",
1841         .format_args = "i1t1",
1842         .n_enum_strings = 16,
1843         .enum_strings = {
1844           "flow director",
1845           "rx miss",
1846           "pci exception",
1847           "mailbox",
1848           "link status change",
1849           "linksec key exchange",
1850           "manageability event",
1851           "reserved23",
1852           "sdp0",
1853           "sdp1",
1854           "sdp2",
1855           "sdp3",
1856           "ecc",
1857           "descriptor handler error",
1858           "tcp timer",
1859           "other",
1860         },
1861       };
1862       struct { u8 instance; u8 index; } * ed;
1863       ed = ELOG_DATA (&vm->elog_main, e);
1864       ed->instance = xd->device_index;
1865       ed->index = i - 16;
1866     }
1867   else
1868     {
1869       u32 v = r->xge_mac.link_status;
1870       uword is_up = (v & (1 << 30)) != 0;
1871
1872       ELOG_TYPE_DECLARE (e) = {
1873         .function = (char *) __FUNCTION__,
1874         .format = "ixge %d, link status change 0x%x",
1875         .format_args = "i4i4",
1876       };
1877       struct { u32 instance, link_status; } * ed;
1878       ed = ELOG_DATA (&vm->elog_main, e);
1879       ed->instance = xd->device_index;
1880       ed->link_status = v;
1881       xd->link_status_at_last_link_change = v;
1882
1883       vlib_process_signal_event (vm, ixge_process_node.index,
1884                                  EVENT_SET_FLAGS,
1885                                  ((is_up<<31) | xd->vlib_hw_if_index));
1886     }
1887 }
1888
1889 always_inline u32
1890 clean_block (u32 * b, u32 * t, u32 n_left)
1891 {
1892   u32 * t0 = t;
1893
1894   while (n_left >= 4)
1895     {
1896       u32 bi0, bi1, bi2, bi3;
1897
1898       t[0] = bi0 = b[0];
1899       b[0] = 0;
1900       t += bi0 != 0;
1901
1902       t[0] = bi1 = b[1];
1903       b[1] = 0;
1904       t += bi1 != 0;
1905
1906       t[0] = bi2 = b[2];
1907       b[2] = 0;
1908       t += bi2 != 0;
1909
1910       t[0] = bi3 = b[3];
1911       b[3] = 0;
1912       t += bi3 != 0;
1913
1914       b += 4;
1915       n_left -= 4;
1916     }
1917
1918   while (n_left > 0)
1919     {
1920       u32 bi0;
1921
1922       t[0] = bi0 = b[0];
1923       b[0] = 0;
1924       t += bi0 != 0;
1925       b += 1;
1926       n_left -= 1;
1927     }
1928
1929   return t - t0;
1930 }
1931
1932 static void
1933 ixge_tx_queue (ixge_main_t * xm, ixge_device_t * xd, u32 queue_index)
1934 {
1935   vlib_main_t * vm = xm->vlib_main;
1936   ixge_dma_queue_t * dq = vec_elt_at_index (xd->dma_queues[VLIB_TX], queue_index);
1937   u32 n_clean, * b, * t, * t0;
1938   i32 n_hw_owned_descriptors;
1939   i32 first_to_clean, last_to_clean;
1940   u64 hwbp_race = 0;
1941
1942   /* Handle case where head write back pointer update
1943    * arrives after the interrupt during high PCI bus loads.
1944    */
1945   while ((dq->head_index == dq->tx.head_index_write_back[0]) &&
1946          dq->tx.n_buffers_on_ring && (dq->head_index != dq->tail_index))
1947     {
1948       hwbp_race++;
1949       if (IXGE_HWBP_RACE_ELOG && (hwbp_race == 1))
1950         {
1951           ELOG_TYPE_DECLARE (e) = {
1952             .function = (char *) __FUNCTION__,
1953             .format = "ixge %d tx head index race: head %4d, tail %4d, buffs %4d",
1954             .format_args = "i4i4i4i4",
1955           };
1956           struct { u32 instance, head_index, tail_index, n_buffers_on_ring; } * ed;
1957           ed = ELOG_DATA (&vm->elog_main, e);
1958           ed->instance = xd->device_index;
1959           ed->head_index = dq->head_index;
1960           ed->tail_index = dq->tail_index;
1961           ed->n_buffers_on_ring = dq->tx.n_buffers_on_ring;
1962         }
1963     }
1964
1965   dq->head_index = dq->tx.head_index_write_back[0];
1966   n_hw_owned_descriptors = ixge_ring_sub (dq, dq->head_index, dq->tail_index);
1967   ASSERT(dq->tx.n_buffers_on_ring >= n_hw_owned_descriptors);
1968   n_clean = dq->tx.n_buffers_on_ring - n_hw_owned_descriptors;
1969
1970   if (IXGE_HWBP_RACE_ELOG && hwbp_race)
1971     {
1972           ELOG_TYPE_DECLARE (e) = {
1973             .function = (char *) __FUNCTION__,
1974             .format = "ixge %d tx head index race: head %4d, hw_owned %4d, n_clean %4d, retries %d",
1975             .format_args = "i4i4i4i4i4",
1976           };
1977           struct { u32 instance, head_index, n_hw_owned_descriptors, n_clean, retries; } * ed;
1978           ed = ELOG_DATA (&vm->elog_main, e);
1979           ed->instance = xd->device_index;
1980           ed->head_index = dq->head_index;
1981           ed->n_hw_owned_descriptors = n_hw_owned_descriptors;
1982           ed->n_clean = n_clean;
1983           ed->retries = hwbp_race;
1984     }
1985
1986   /*
1987    * This function used to wait until hardware owned zero descriptors.
1988    * At high PPS rates, that doesn't happen until the TX ring is
1989    * completely full of descriptors which need to be cleaned up.
1990    * That, in turn, causes TX ring-full drops and/or long RX service
1991    * interruptions.
1992    */
1993   if (n_clean == 0)
1994     return;
1995
1996   /* Clean the n_clean descriptors prior to the reported hardware head */
1997   last_to_clean = dq->head_index - 1;
1998   last_to_clean = (last_to_clean < 0) ? last_to_clean + dq->n_descriptors :
1999       last_to_clean;
2000
2001   first_to_clean = (last_to_clean) - (n_clean - 1);
2002   first_to_clean = (first_to_clean < 0) ? first_to_clean + dq->n_descriptors :
2003       first_to_clean;
2004
2005   vec_resize (xm->tx_buffers_pending_free, dq->n_descriptors - 1);
2006   t0 = t = xm->tx_buffers_pending_free;
2007   b = dq->descriptor_buffer_indices + first_to_clean;
2008
2009   /* Wrap case: clean from first to end, then start to last */
2010   if (first_to_clean > last_to_clean)
2011     {
2012       t += clean_block (b, t, (dq->n_descriptors - 1) - first_to_clean);
2013       first_to_clean = 0;
2014       b = dq->descriptor_buffer_indices;
2015     }
2016
2017   /* Typical case: clean from first to last */
2018   if (first_to_clean <= last_to_clean)
2019       t += clean_block (b, t, (last_to_clean - first_to_clean) + 1);
2020
2021   if (t > t0)
2022     {
2023       u32 n = t - t0;
2024       vlib_buffer_free_no_next (vm, t0, n);
2025       ASSERT (dq->tx.n_buffers_on_ring >= n);
2026       dq->tx.n_buffers_on_ring -= n;
2027       _vec_len (xm->tx_buffers_pending_free) = 0;
2028     }
2029 }
2030
2031 /* RX queue interrupts 0 thru 7; TX 8 thru 15. */
2032 always_inline uword ixge_interrupt_is_rx_queue (uword i)
2033 { return i < 8; }
2034
2035 always_inline uword ixge_interrupt_is_tx_queue (uword i)
2036 { return i >= 8 && i < 16; }
2037
2038 always_inline uword ixge_tx_queue_to_interrupt (uword i)
2039 { return 8 + i; }
2040
2041 always_inline uword ixge_rx_queue_to_interrupt (uword i)
2042 { return 0 + i; }
2043
2044 always_inline uword ixge_interrupt_rx_queue (uword i)
2045 {
2046   ASSERT (ixge_interrupt_is_rx_queue (i));
2047   return i - 0;
2048 }
2049
2050 always_inline uword ixge_interrupt_tx_queue (uword i)
2051 {
2052   ASSERT (ixge_interrupt_is_tx_queue (i));
2053   return i - 8;
2054 }
2055
2056 static uword
2057 ixge_device_input (ixge_main_t * xm,
2058                    ixge_device_t * xd,
2059                    vlib_node_runtime_t * node)
2060 {
2061   ixge_regs_t * r = xd->regs;
2062   u32 i, s;
2063   uword n_rx_packets = 0;
2064
2065   s = r->interrupt.status_write_1_to_set;
2066   if (s)
2067     r->interrupt.status_write_1_to_clear = s;
2068
2069   foreach_set_bit (i, s, ({
2070     if (ixge_interrupt_is_rx_queue (i))
2071       n_rx_packets += ixge_rx_queue (xm, xd, node, ixge_interrupt_rx_queue (i));
2072
2073     else if (ixge_interrupt_is_tx_queue (i))
2074       ixge_tx_queue (xm, xd, ixge_interrupt_tx_queue (i));
2075
2076     else
2077       ixge_interrupt (xm, xd, i);
2078   }));
2079
2080   return n_rx_packets;
2081 }
2082
2083 static uword
2084 ixge_input (vlib_main_t * vm,
2085             vlib_node_runtime_t * node,
2086             vlib_frame_t * f)
2087 {
2088   ixge_main_t * xm = &ixge_main;
2089   ixge_device_t * xd;
2090   uword n_rx_packets = 0;
2091
2092   if (node->state == VLIB_NODE_STATE_INTERRUPT)
2093     {
2094       uword i;
2095
2096       /* Loop over devices with interrupts. */
2097       foreach_set_bit (i, node->runtime_data[0], ({
2098         xd = vec_elt_at_index (xm->devices, i);
2099         n_rx_packets += ixge_device_input (xm, xd, node);
2100
2101         /* Re-enable interrupts since we're going to stay in interrupt mode. */
2102         if (! (node->flags & VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE))
2103           xd->regs->interrupt.enable_write_1_to_set = ~0;
2104       }));
2105
2106       /* Clear mask of devices with pending interrupts. */
2107       node->runtime_data[0] = 0;
2108     }
2109   else
2110     {
2111       /* Poll all devices for input/interrupts. */
2112       vec_foreach (xd, xm->devices)
2113         {
2114           n_rx_packets += ixge_device_input (xm, xd, node);
2115
2116           /* Re-enable interrupts when switching out of polling mode. */
2117           if (node->flags &
2118               VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE)
2119             xd->regs->interrupt.enable_write_1_to_set = ~0;
2120         }
2121     }
2122
2123   return n_rx_packets;
2124 }
2125
2126 static char * ixge_error_strings[] = {
2127 #define _(n,s) s,
2128     foreach_ixge_error
2129 #undef _
2130 };
2131
2132 VLIB_REGISTER_NODE (ixge_input_node, static) = {
2133   .function = ixge_input,
2134   .type = VLIB_NODE_TYPE_INPUT,
2135   .name = "ixge-input",
2136
2137   /* Will be enabled if/when hardware is detected. */
2138   .state = VLIB_NODE_STATE_DISABLED,
2139
2140   .format_buffer = format_ethernet_header_with_length,
2141   .format_trace = format_ixge_rx_dma_trace,
2142
2143   .n_errors = IXGE_N_ERROR,
2144   .error_strings = ixge_error_strings,
2145
2146   .n_next_nodes = IXGE_RX_N_NEXT,
2147   .next_nodes = {
2148     [IXGE_RX_NEXT_DROP] = "error-drop",
2149     [IXGE_RX_NEXT_ETHERNET_INPUT] = "ethernet-input",
2150     [IXGE_RX_NEXT_IP4_INPUT] = "ip4-input",
2151     [IXGE_RX_NEXT_IP6_INPUT] = "ip6-input",
2152   },
2153 };
2154
2155 VLIB_NODE_FUNCTION_MULTIARCH_CLONE (ixge_input)
2156 CLIB_MULTIARCH_SELECT_FN (ixge_input)
2157
2158 static u8 * format_ixge_device_name (u8 * s, va_list * args)
2159 {
2160   u32 i = va_arg (*args, u32);
2161   ixge_main_t * xm = &ixge_main;
2162   ixge_device_t * xd = vec_elt_at_index (xm->devices, i);
2163   return format (s, "TenGigabitEthernet%U",
2164                  format_vlib_pci_handle, &xd->pci_device.bus_address);
2165 }
2166
2167 #define IXGE_COUNTER_IS_64_BIT (1 << 0)
2168 #define IXGE_COUNTER_NOT_CLEAR_ON_READ (1 << 1)
2169
2170 static u8 ixge_counter_flags[] = {
2171 #define _(a,f) 0,
2172 #define _64(a,f) IXGE_COUNTER_IS_64_BIT,
2173   foreach_ixge_counter
2174 #undef _
2175 #undef _64
2176 };
2177
2178 static void ixge_update_counters (ixge_device_t * xd)
2179 {
2180   /* Byte offset for counter registers. */
2181   static u32 reg_offsets[] = {
2182 #define _(a,f) (a) / sizeof (u32),
2183 #define _64(a,f) _(a,f)
2184     foreach_ixge_counter
2185 #undef _
2186 #undef _64
2187   };
2188   volatile u32 * r = (volatile u32 *) xd->regs;
2189   int i;
2190
2191   for (i = 0; i < ARRAY_LEN (xd->counters); i++)
2192     {
2193       u32 o = reg_offsets[i];
2194       xd->counters[i] += r[o];
2195       if (ixge_counter_flags[i] & IXGE_COUNTER_NOT_CLEAR_ON_READ)
2196         r[o] = 0;
2197       if (ixge_counter_flags[i] & IXGE_COUNTER_IS_64_BIT)
2198         xd->counters[i] += (u64) r[o+1] << (u64) 32;
2199     }
2200 }
2201
2202 static u8 * format_ixge_device_id (u8 * s, va_list * args)
2203 {
2204   u32 device_id = va_arg (*args, u32);
2205   char * t = 0;
2206   switch (device_id)
2207     {
2208 #define _(f,n) case n: t = #f; break;
2209       foreach_ixge_pci_device_id;
2210 #undef _
2211     default:
2212       t = 0;
2213       break;
2214     }
2215   if (t == 0)
2216     s = format (s, "unknown 0x%x", device_id);
2217   else
2218     s = format (s, "%s", t);
2219   return s;
2220 }
2221
2222 static u8 * format_ixge_link_status (u8 * s, va_list * args)
2223 {
2224   ixge_device_t * xd = va_arg (*args, ixge_device_t *);
2225   u32 v = xd->link_status_at_last_link_change;
2226
2227   s = format (s, "%s", (v & (1 << 30)) ? "up" : "down");
2228
2229   {
2230     char * modes[] = {
2231       "1g", "10g parallel", "10g serial", "autoneg",
2232     };
2233     char * speeds[] = {
2234       "unknown", "100m", "1g", "10g",
2235     };
2236     s = format (s, ", mode %s, speed %s",
2237                 modes[(v >> 26) & 3],
2238                 speeds[(v >> 28) & 3]);
2239   }
2240
2241   return s;
2242 }
2243
2244 static u8 * format_ixge_device (u8 * s, va_list * args)
2245 {
2246   u32 dev_instance = va_arg (*args, u32);
2247   CLIB_UNUSED (int verbose) = va_arg (*args, int);
2248   ixge_main_t * xm = &ixge_main;
2249   ixge_device_t * xd = vec_elt_at_index (xm->devices, dev_instance);
2250   ixge_phy_t * phy = xd->phys + xd->phy_index;
2251   uword indent = format_get_indent (s);
2252
2253   ixge_update_counters (xd);
2254   xd->link_status_at_last_link_change = xd->regs->xge_mac.link_status;
2255
2256   s = format (s, "Intel 8259X: id %U\n%Ulink %U",
2257               format_ixge_device_id, xd->device_id,
2258               format_white_space, indent + 2,
2259               format_ixge_link_status, xd);
2260
2261   {
2262
2263     s = format (s, "\n%UPCIe %U", format_white_space, indent + 2,
2264                 format_vlib_pci_link_speed, &xd->pci_device);
2265   }
2266
2267   s = format (s, "\n%U", format_white_space, indent + 2);
2268   if (phy->mdio_address != ~0)
2269     s = format (s, "PHY address %d, id 0x%x", phy->mdio_address, phy->id);
2270   else if (xd->sfp_eeprom.id == SFP_ID_sfp)
2271     s = format (s, "SFP %U", format_sfp_eeprom, &xd->sfp_eeprom);
2272   else
2273     s = format (s, "PHY not found");
2274
2275   /* FIXME */
2276   {
2277     ixge_dma_queue_t * dq = vec_elt_at_index (xd->dma_queues[VLIB_RX], 0);
2278     ixge_dma_regs_t * dr = get_dma_regs (xd, VLIB_RX, 0);
2279     u32 hw_head_index = dr->head_index;
2280     u32 sw_head_index = dq->head_index;
2281     u32 nitems;
2282
2283     nitems = ixge_ring_sub (dq, hw_head_index, sw_head_index);
2284     s = format (s, "\n%U%d unprocessed, %d total buffers on rx queue 0 ring",
2285                 format_white_space, indent + 2, nitems, dq->n_descriptors);
2286
2287     s = format (s, "\n%U%d buffers in driver rx cache",
2288                 format_white_space, indent + 2, vec_len(xm->rx_buffers_to_add));
2289
2290     s = format (s, "\n%U%d buffers on tx queue 0 ring",
2291                 format_white_space, indent + 2,
2292                 xd->dma_queues[VLIB_TX][0].tx.n_buffers_on_ring);
2293   }
2294   {
2295     u32 i;
2296     u64 v;
2297     static char * names[] = {
2298 #define _(a,f) #f,
2299 #define _64(a,f) _(a,f)
2300     foreach_ixge_counter
2301 #undef _
2302 #undef _64
2303     };
2304
2305     for (i = 0; i < ARRAY_LEN (names); i++)
2306       {
2307         v = xd->counters[i] - xd->counters_last_clear[i];
2308         if (v != 0)
2309           s = format (s, "\n%U%-40U%16Ld",
2310                       format_white_space, indent + 2,
2311                       format_c_identifier, names[i],
2312                       v);
2313       }
2314   }
2315
2316   return s;
2317 }
2318
2319 static void ixge_clear_hw_interface_counters (u32 instance)
2320 {
2321   ixge_main_t * xm = &ixge_main;
2322   ixge_device_t * xd = vec_elt_at_index (xm->devices, instance);
2323   ixge_update_counters (xd);
2324   memcpy (xd->counters_last_clear, xd->counters, sizeof (xd->counters));
2325 }
2326
2327 /*
2328  * Dynamically redirect all pkts from a specific interface
2329  * to the specified node
2330  */
2331 static void ixge_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
2332                                           u32 node_index)
2333 {
2334   ixge_main_t * xm = &ixge_main;
2335   vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
2336   ixge_device_t * xd = vec_elt_at_index (xm->devices, hw->dev_instance);
2337
2338   /* Shut off redirection */
2339   if (node_index == ~0)
2340     {
2341       xd->per_interface_next_index = node_index;
2342       return;
2343     }
2344
2345   xd->per_interface_next_index =
2346     vlib_node_add_next (xm->vlib_main, ixge_input_node.index, node_index);
2347 }
2348
2349
2350 VNET_DEVICE_CLASS (ixge_device_class) = {
2351   .name = "ixge",
2352   .tx_function = ixge_interface_tx,
2353   .format_device_name = format_ixge_device_name,
2354   .format_device = format_ixge_device,
2355   .format_tx_trace = format_ixge_tx_dma_trace,
2356   .clear_counters = ixge_clear_hw_interface_counters,
2357   .admin_up_down_function = ixge_interface_admin_up_down,
2358   .rx_redirect_to_node = ixge_set_interface_next_node,
2359 };
2360
2361 #define IXGE_N_BYTES_IN_RX_BUFFER  (2048)  // DAW-HACK: Set Rx buffer size so all packets < ETH_MTU_SIZE fit in the buffer (i.e. sop & eop for all descriptors).
2362
2363 static clib_error_t *
2364 ixge_dma_init (ixge_device_t * xd, vlib_rx_or_tx_t rt, u32 queue_index)
2365 {
2366   ixge_main_t * xm = &ixge_main;
2367   vlib_main_t * vm = xm->vlib_main;
2368   ixge_dma_queue_t * dq;
2369   clib_error_t * error = 0;
2370
2371   vec_validate (xd->dma_queues[rt], queue_index);
2372   dq = vec_elt_at_index (xd->dma_queues[rt], queue_index);
2373
2374   if (! xm->n_descriptors_per_cache_line)
2375     xm->n_descriptors_per_cache_line = CLIB_CACHE_LINE_BYTES / sizeof (dq->descriptors[0]);
2376
2377   if (! xm->n_bytes_in_rx_buffer)
2378     xm->n_bytes_in_rx_buffer = IXGE_N_BYTES_IN_RX_BUFFER;
2379   xm->n_bytes_in_rx_buffer = round_pow2 (xm->n_bytes_in_rx_buffer, 1024);
2380   if (! xm->vlib_buffer_free_list_index)
2381     {
2382       xm->vlib_buffer_free_list_index = vlib_buffer_get_or_create_free_list (vm, xm->n_bytes_in_rx_buffer, "ixge rx");
2383       ASSERT (xm->vlib_buffer_free_list_index != 0);
2384     }
2385
2386   if (! xm->n_descriptors[rt])
2387     xm->n_descriptors[rt] = 4 * VLIB_FRAME_SIZE;
2388
2389   dq->queue_index = queue_index;
2390   dq->n_descriptors = round_pow2 (xm->n_descriptors[rt], xm->n_descriptors_per_cache_line);
2391   dq->head_index = dq->tail_index = 0;
2392
2393   dq->descriptors = vlib_physmem_alloc_aligned (vm, &error,
2394                                                 dq->n_descriptors * sizeof (dq->descriptors[0]),
2395                                                 128 /* per chip spec */);
2396   if (error)
2397     return error;
2398
2399   memset (dq->descriptors, 0, dq->n_descriptors * sizeof (dq->descriptors[0]));
2400   vec_resize (dq->descriptor_buffer_indices, dq->n_descriptors);
2401
2402   if (rt == VLIB_RX)
2403     {
2404       u32 n_alloc, i;
2405
2406       n_alloc = vlib_buffer_alloc_from_free_list
2407         (vm, dq->descriptor_buffer_indices, vec_len (dq->descriptor_buffer_indices),
2408          xm->vlib_buffer_free_list_index);
2409       ASSERT (n_alloc == vec_len (dq->descriptor_buffer_indices));
2410       for (i = 0; i < n_alloc; i++)
2411         {
2412           vlib_buffer_t * b = vlib_get_buffer (vm, dq->descriptor_buffer_indices[i]);
2413           dq->descriptors[i].rx_to_hw.tail_address = vlib_physmem_virtual_to_physical (vm, b->data);
2414         }
2415     }
2416   else
2417     {
2418       u32 i;
2419
2420       dq->tx.head_index_write_back = vlib_physmem_alloc (vm, &error, CLIB_CACHE_LINE_BYTES);
2421
2422       for (i = 0; i < dq->n_descriptors; i++)
2423         dq->descriptors[i].tx = xm->tx_descriptor_template;
2424
2425       vec_validate (xm->tx_buffers_pending_free, dq->n_descriptors - 1);
2426     }
2427
2428   {
2429     ixge_dma_regs_t * dr = get_dma_regs (xd, rt, queue_index);
2430     u64 a;
2431
2432     a = vlib_physmem_virtual_to_physical (vm, dq->descriptors);
2433     dr->descriptor_address[0] = a & 0xFFFFFFFF;
2434     dr->descriptor_address[1] = a >> (u64) 32;
2435     dr->n_descriptor_bytes = dq->n_descriptors * sizeof (dq->descriptors[0]);
2436     dq->head_index = dq->tail_index = 0;
2437
2438     if (rt == VLIB_RX)
2439       {
2440         ASSERT ((xm->n_bytes_in_rx_buffer / 1024) < 32);
2441         dr->rx_split_control =
2442           (/* buffer size */ ((xm->n_bytes_in_rx_buffer / 1024) << 0)
2443            | (/* lo free descriptor threshold (units of 64 descriptors) */
2444               (1 << 22))
2445            | (/* descriptor type: advanced one buffer */
2446               (1 << 25))
2447            | (/* drop if no descriptors available */
2448               (1 << 28)));
2449
2450         /* Give hardware all but last 16 cache lines' worth of descriptors. */
2451         dq->tail_index = dq->n_descriptors -
2452           16*xm->n_descriptors_per_cache_line;
2453       }
2454     else
2455       {
2456         /* Make sure its initialized before hardware can get to it. */
2457         dq->tx.head_index_write_back[0] = dq->head_index;
2458
2459         a = vlib_physmem_virtual_to_physical (vm, dq->tx.head_index_write_back);
2460         dr->tx.head_index_write_back_address[0] = /* enable bit */ 1 | a;
2461         dr->tx.head_index_write_back_address[1] = (u64) a >> (u64) 32;
2462       }
2463
2464     /* DMA on 82599 does not work with [13] rx data write relaxed ordering
2465        and [12] undocumented set. */
2466     if (rt == VLIB_RX)
2467       dr->dca_control &= ~((1 << 13) | (1 << 12));
2468
2469     CLIB_MEMORY_BARRIER ();
2470
2471     if (rt == VLIB_TX)
2472       {
2473         xd->regs->tx_dma_control |= (1 << 0);
2474         dr->control |= ((32 << 0) /* prefetch threshold */
2475                         | (64 << 8) /* host threshold */
2476                         | (0 << 16) /* writeback threshold*/);
2477       }
2478
2479     /* Enable this queue and wait for hardware to initialize
2480        before adding to tail. */
2481     if (rt == VLIB_TX)
2482       {
2483         dr->control |= 1 << 25;
2484         while (! (dr->control & (1 << 25)))
2485           ;
2486       }
2487
2488     /* Set head/tail indices and enable DMA. */
2489     dr->head_index = dq->head_index;
2490     dr->tail_index = dq->tail_index;
2491   }
2492
2493   return error;
2494 }
2495
2496 static u32 ixge_flag_change (vnet_main_t * vnm,
2497                              vnet_hw_interface_t * hw,
2498                              u32 flags)
2499 {
2500   ixge_device_t * xd;
2501   ixge_regs_t * r;
2502   u32 old;
2503   ixge_main_t * xm = &ixge_main;
2504
2505   xd = vec_elt_at_index (xm->devices, hw->dev_instance);
2506   r = xd->regs;
2507
2508   old = r->filter_control;
2509
2510   if (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL)
2511     r->filter_control = old |(1 << 9) /* unicast promiscuous */;
2512   else
2513     r->filter_control = old & ~(1 << 9);
2514
2515   return old;
2516 }
2517
2518 static void ixge_device_init (ixge_main_t * xm)
2519 {
2520   vnet_main_t * vnm = vnet_get_main();
2521   ixge_device_t * xd;
2522
2523   /* Reset chip(s). */
2524   vec_foreach (xd, xm->devices)
2525     {
2526       ixge_regs_t * r = xd->regs;
2527       const u32 reset_bit = (1 << 26) | (1 << 3);
2528
2529       r->control |= reset_bit;
2530
2531       /* No need to suspend.  Timed to take ~1e-6 secs */
2532       while (r->control & reset_bit)
2533         ;
2534
2535       /* Software loaded. */
2536       r->extended_control |= (1 << 28);
2537
2538       ixge_phy_init (xd);
2539
2540       /* Register ethernet interface. */
2541       {
2542         u8 addr8[6];
2543         u32 i, addr32[2];
2544         clib_error_t * error;
2545
2546         addr32[0] = r->rx_ethernet_address0[0][0];
2547         addr32[1] = r->rx_ethernet_address0[0][1];
2548         for (i = 0; i < 6; i++)
2549           addr8[i] = addr32[i / 4] >> ((i % 4) * 8);
2550
2551         error = ethernet_register_interface
2552           (vnm,
2553            ixge_device_class.index,
2554            xd->device_index,
2555            /* ethernet address */ addr8,
2556            &xd->vlib_hw_if_index,
2557            ixge_flag_change);
2558         if (error)
2559           clib_error_report (error);
2560       }
2561
2562       {
2563         vnet_sw_interface_t * sw = vnet_get_hw_sw_interface (vnm, xd->vlib_hw_if_index);
2564         xd->vlib_sw_if_index = sw->sw_if_index;
2565       }
2566
2567       ixge_dma_init (xd, VLIB_RX, /* queue_index */ 0);
2568
2569       xm->n_descriptors[VLIB_TX] = 20 * VLIB_FRAME_SIZE;
2570
2571       ixge_dma_init (xd, VLIB_TX, /* queue_index */ 0);
2572
2573       /* RX/TX queue 0 gets mapped to interrupt bits 0 & 8. */
2574       r->interrupt.queue_mapping[0] =
2575         ((/* valid bit */ (1 << 7) |
2576           ixge_rx_queue_to_interrupt (0)) << 0);
2577
2578       r->interrupt.queue_mapping[0] |=
2579         ((/* valid bit */ (1 << 7) |
2580           ixge_tx_queue_to_interrupt (0)) << 8);
2581
2582       /* No use in getting too many interrupts.
2583          Limit them to one every 3/4 ring size at line rate
2584          min sized packets.
2585          No need for this since kernel/vlib main loop provides adequate interrupt
2586          limiting scheme. */
2587       if (0)
2588         {
2589           f64 line_rate_max_pps = 10e9 / (8 * (64 + /* interframe padding */ 20));
2590           ixge_throttle_queue_interrupt (r, 0, .75 * xm->n_descriptors[VLIB_RX] / line_rate_max_pps);
2591         }
2592
2593       /* Accept all multicast and broadcast packets. Should really add them
2594          to the dst_ethernet_address register array. */
2595       r->filter_control |= (1 << 10) | (1 << 8);
2596
2597       /* Enable frames up to size in mac frame size register. */
2598       r->xge_mac.control |= 1 << 2;
2599       r->xge_mac.rx_max_frame_size = (9216 + 14) << 16;
2600
2601       /* Enable all interrupts. */
2602       if (! IXGE_ALWAYS_POLL)
2603         r->interrupt.enable_write_1_to_set = ~0;
2604     }
2605 }
2606
2607 static uword
2608 ixge_process (vlib_main_t * vm,
2609               vlib_node_runtime_t * rt,
2610               vlib_frame_t * f)
2611 {
2612   vnet_main_t * vnm = vnet_get_main();
2613   ixge_main_t * xm = &ixge_main;
2614   ixge_device_t * xd;
2615   uword event_type, * event_data = 0;
2616   f64 timeout, link_debounce_deadline;
2617
2618   ixge_device_init (xm);
2619
2620   /* Clear all counters. */
2621   vec_foreach (xd, xm->devices)
2622     {
2623       ixge_update_counters (xd);
2624       memset (xd->counters, 0, sizeof (xd->counters));
2625     }
2626
2627   timeout = 30.0;
2628   link_debounce_deadline = 1e70;
2629
2630   while (1)
2631     {
2632       /* 36 bit stat counters could overflow in ~50 secs.
2633          We poll every 30 secs to be conservative. */
2634       vlib_process_wait_for_event_or_clock (vm, timeout);
2635
2636       event_type = vlib_process_get_events (vm, &event_data);
2637
2638       switch (event_type) {
2639       case EVENT_SET_FLAGS:
2640         /* 1 ms */
2641         link_debounce_deadline = vlib_time_now(vm) + 1e-3;
2642         timeout = 1e-3;
2643         break;
2644
2645       case ~0:
2646         /* No events found: timer expired. */
2647         if (vlib_time_now(vm) > link_debounce_deadline)
2648           {
2649             vec_foreach (xd, xm->devices)
2650               {
2651                 ixge_regs_t * r = xd->regs;
2652                 u32 v = r->xge_mac.link_status;
2653                 uword is_up = (v & (1 << 30)) != 0;
2654
2655                 vnet_hw_interface_set_flags
2656                   (vnm, xd->vlib_hw_if_index,
2657                    is_up ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
2658               }
2659             link_debounce_deadline = 1e70;
2660             timeout = 30.0;
2661           }
2662         break;
2663
2664       default:
2665         ASSERT (0);
2666       }
2667
2668       if (event_data)
2669         _vec_len (event_data) = 0;
2670
2671       /* Query stats every 30 secs. */
2672       {
2673         f64 now = vlib_time_now (vm);
2674         if (now - xm->time_last_stats_update > 30)
2675           {
2676             xm->time_last_stats_update = now;
2677             vec_foreach (xd, xm->devices)
2678               ixge_update_counters (xd);
2679           }
2680       }
2681     }
2682
2683   return 0;
2684 }
2685
2686 static vlib_node_registration_t ixge_process_node = {
2687     .function = ixge_process,
2688     .type = VLIB_NODE_TYPE_PROCESS,
2689     .name = "ixge-process",
2690 };
2691
2692 clib_error_t * ixge_init (vlib_main_t * vm)
2693 {
2694   ixge_main_t * xm = &ixge_main;
2695   clib_error_t * error;
2696
2697   xm->vlib_main = vm;
2698   memset (&xm->tx_descriptor_template, 0, sizeof (xm->tx_descriptor_template));
2699   memset (&xm->tx_descriptor_template_mask, 0, sizeof (xm->tx_descriptor_template_mask));
2700   xm->tx_descriptor_template.status0 =
2701     (IXGE_TX_DESCRIPTOR_STATUS0_ADVANCED
2702      | IXGE_TX_DESCRIPTOR_STATUS0_IS_ADVANCED
2703      | IXGE_TX_DESCRIPTOR_STATUS0_INSERT_FCS);
2704   xm->tx_descriptor_template_mask.status0 = 0xffff;
2705   xm->tx_descriptor_template_mask.status1 = 0x00003fff;
2706
2707   xm->tx_descriptor_template_mask.status0 &=
2708     ~(IXGE_TX_DESCRIPTOR_STATUS0_IS_END_OF_PACKET
2709       | IXGE_TX_DESCRIPTOR_STATUS0_REPORT_STATUS);
2710   xm->tx_descriptor_template_mask.status1 &=
2711     ~(IXGE_TX_DESCRIPTOR_STATUS1_DONE);
2712
2713   error = vlib_call_init_function (vm, pci_bus_init);
2714
2715   return error;
2716 }
2717
2718 VLIB_INIT_FUNCTION (ixge_init);
2719
2720
2721 static void
2722 ixge_pci_intr_handler(vlib_pci_device_t * dev)
2723 {
2724   ixge_main_t * xm = &ixge_main;
2725   vlib_main_t * vm = xm->vlib_main;
2726
2727   vlib_node_set_interrupt_pending (vm, ixge_input_node.index);
2728
2729   /* Let node know which device is interrupting. */
2730   {
2731     vlib_node_runtime_t * rt = vlib_node_get_runtime (vm, ixge_input_node.index);
2732     rt->runtime_data[0] |= 1 << dev->private_data;
2733   }
2734 }
2735
2736 static clib_error_t *
2737 ixge_pci_init (vlib_main_t * vm, vlib_pci_device_t * dev)
2738 {
2739   ixge_main_t * xm = &ixge_main;
2740   clib_error_t * error;
2741   void * r;
2742   ixge_device_t * xd;
2743
2744   /* Device found: make sure we have dma memory. */
2745   if (unix_physmem_is_fake (vm))
2746     return clib_error_return (0, "no physical memory available");
2747
2748   error = vlib_pci_map_resource (dev, 0, &r);
2749   if (error)
2750     return error;
2751
2752   vec_add2 (xm->devices, xd, 1);
2753
2754   if (vec_len (xm->devices) == 1)
2755     {
2756       ixge_input_node.function = ixge_input_multiarch_select();
2757     }
2758
2759   xd->pci_device = dev[0];
2760   xd->device_id = xd->pci_device.config0.header.device_id;
2761   xd->regs = r;
2762   xd->device_index = xd - xm->devices;
2763   xd->pci_function = dev->bus_address.function;
2764   xd->per_interface_next_index = ~0;
2765
2766
2767   /* Chip found so enable node. */
2768   {
2769     vlib_node_set_state (vm, ixge_input_node.index,
2770                          (IXGE_ALWAYS_POLL
2771                           ? VLIB_NODE_STATE_POLLING
2772                           : VLIB_NODE_STATE_INTERRUPT));
2773
2774     dev->private_data = xd->device_index;
2775   }
2776
2777   if (vec_len (xm->devices) == 1)
2778     {
2779       vlib_register_node (vm, &ixge_process_node);
2780       xm->process_node_index = ixge_process_node.index;
2781     }
2782
2783   error = vlib_pci_bus_master_enable(dev);
2784
2785   if (error)
2786     return error;
2787
2788   return vlib_pci_intr_enable(dev);
2789 }
2790
2791 PCI_REGISTER_DEVICE (ixge_pci_device_registration,static) = {
2792   .init_function = ixge_pci_init,
2793   .interrupt_handler = ixge_pci_intr_handler,
2794   .supported_devices = {
2795 #define _(t,i) { .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = i, },
2796     foreach_ixge_pci_device_id
2797 #undef _
2798     { 0 },
2799   },
2800 };
2801
2802 void ixge_set_next_node (ixge_rx_next_t next, char *name)
2803 {
2804   vlib_node_registration_t *r = &ixge_input_node;
2805
2806   switch (next)
2807     {
2808     case IXGE_RX_NEXT_IP4_INPUT:
2809     case IXGE_RX_NEXT_IP6_INPUT:
2810     case IXGE_RX_NEXT_ETHERNET_INPUT:
2811       r->next_nodes[next] = name;
2812       break;
2813
2814     default:
2815       clib_warning ("%s: illegal next %d\n", __FUNCTION__, next);
2816       break;
2817     }
2818 }
2819 #endif