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