]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/oce/oce_if.c
Fix insufficient oce(4) ioctl(2) privilege checking.
[FreeBSD/FreeBSD.git] / sys / dev / oce / oce_if.c
1 /*-
2  * Copyright (C) 2013 Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the Emulex Corporation nor the names of its
16  *    contributors may be used to endorse or promote products derived from
17  *    this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  * Contact Information:
32  * freebsd-drivers@emulex.com
33  *
34  * Emulex
35  * 3333 Susan Street
36  * Costa Mesa, CA 92626
37  */
38
39 /* $FreeBSD$ */
40
41 #include "opt_inet6.h"
42 #include "opt_inet.h"
43
44 #include "oce_if.h"
45 #include "oce_user.h"
46
47 #define is_tso_pkt(m) (m->m_pkthdr.csum_flags & CSUM_TSO)
48
49 /* UE Status Low CSR */
50 static char *ue_status_low_desc[] = {
51         "CEV",
52         "CTX",
53         "DBUF",
54         "ERX",
55         "Host",
56         "MPU",
57         "NDMA",
58         "PTC ",
59         "RDMA ",
60         "RXF ",
61         "RXIPS ",
62         "RXULP0 ",
63         "RXULP1 ",
64         "RXULP2 ",
65         "TIM ",
66         "TPOST ",
67         "TPRE ",
68         "TXIPS ",
69         "TXULP0 ",
70         "TXULP1 ",
71         "UC ",
72         "WDMA ",
73         "TXULP2 ",
74         "HOST1 ",
75         "P0_OB_LINK ",
76         "P1_OB_LINK ",
77         "HOST_GPIO ",
78         "MBOX ",
79         "AXGMAC0",
80         "AXGMAC1",
81         "JTAG",
82         "MPU_INTPEND"
83 };
84
85 /* UE Status High CSR */
86 static char *ue_status_hi_desc[] = {
87         "LPCMEMHOST",
88         "MGMT_MAC",
89         "PCS0ONLINE",
90         "MPU_IRAM",
91         "PCS1ONLINE",
92         "PCTL0",
93         "PCTL1",
94         "PMEM",
95         "RR",
96         "TXPB",
97         "RXPP",
98         "XAUI",
99         "TXP",
100         "ARM",
101         "IPC",
102         "HOST2",
103         "HOST3",
104         "HOST4",
105         "HOST5",
106         "HOST6",
107         "HOST7",
108         "HOST8",
109         "HOST9",
110         "NETC",
111         "Unknown",
112         "Unknown",
113         "Unknown",
114         "Unknown",
115         "Unknown",
116         "Unknown",
117         "Unknown",
118         "Unknown"
119 };
120
121 struct oce_common_cqe_info{
122         uint8_t vtp:1;
123         uint8_t l4_cksum_pass:1;
124         uint8_t ip_cksum_pass:1;
125         uint8_t ipv6_frame:1;
126         uint8_t qnq:1;
127         uint8_t rsvd:3;
128         uint8_t num_frags;
129         uint16_t pkt_size;
130         uint16_t vtag;
131 };
132
133
134 /* Driver entry points prototypes */
135 static int  oce_probe(device_t dev);
136 static int  oce_attach(device_t dev);
137 static int  oce_detach(device_t dev);
138 static int  oce_shutdown(device_t dev);
139 static int  oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data);
140 static void oce_init(void *xsc);
141 static int  oce_multiq_start(struct ifnet *ifp, struct mbuf *m);
142 static void oce_multiq_flush(struct ifnet *ifp);
143
144 /* Driver interrupt routines protypes */
145 static void oce_intr(void *arg, int pending);
146 static int  oce_setup_intr(POCE_SOFTC sc);
147 static int  oce_fast_isr(void *arg);
148 static int  oce_alloc_intr(POCE_SOFTC sc, int vector,
149                           void (*isr) (void *arg, int pending));
150
151 /* Media callbacks prototypes */
152 static void oce_media_status(struct ifnet *ifp, struct ifmediareq *req);
153 static int  oce_media_change(struct ifnet *ifp);
154
155 /* Transmit routines prototypes */
156 static int  oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index);
157 static void oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq);
158 static void oce_process_tx_completion(struct oce_wq *wq);
159 static int  oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m,
160                                  struct oce_wq *wq);
161
162 /* Receive routines prototypes */
163 static int  oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
164 static int  oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
165 static void oce_rx(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe);
166 static void oce_check_rx_bufs(POCE_SOFTC sc, uint32_t num_cqes, struct oce_rq *rq);
167 static uint16_t oce_rq_handler_lro(void *arg);
168 static void oce_correct_header(struct mbuf *m, struct nic_hwlro_cqe_part1 *cqe1, struct nic_hwlro_cqe_part2 *cqe2);
169 static void oce_rx_lro(struct oce_rq *rq, struct nic_hwlro_singleton_cqe *cqe, struct nic_hwlro_cqe_part2 *cqe2);
170 static void oce_rx_mbuf_chain(struct oce_rq *rq, struct oce_common_cqe_info *cqe_info, struct mbuf **m);
171
172 /* Helper function prototypes in this file */
173 static int  oce_attach_ifp(POCE_SOFTC sc);
174 static void oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag);
175 static void oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag);
176 static int  oce_vid_config(POCE_SOFTC sc);
177 static void oce_mac_addr_set(POCE_SOFTC sc);
178 static int  oce_handle_passthrough(struct ifnet *ifp, caddr_t data);
179 static void oce_local_timer(void *arg);
180 static void oce_if_deactivate(POCE_SOFTC sc);
181 static void oce_if_activate(POCE_SOFTC sc);
182 static void setup_max_queues_want(POCE_SOFTC sc);
183 static void update_queues_got(POCE_SOFTC sc);
184 static void process_link_state(POCE_SOFTC sc,
185                  struct oce_async_cqe_link_state *acqe);
186 static int oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m);
187 static void oce_get_config(POCE_SOFTC sc);
188 static struct mbuf *oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete);
189 static void oce_read_env_variables(POCE_SOFTC sc);
190
191
192 /* IP specific */
193 #if defined(INET6) || defined(INET)
194 static int  oce_init_lro(POCE_SOFTC sc);
195 static struct mbuf * oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp);
196 #endif
197
198 static device_method_t oce_dispatch[] = {
199         DEVMETHOD(device_probe, oce_probe),
200         DEVMETHOD(device_attach, oce_attach),
201         DEVMETHOD(device_detach, oce_detach),
202         DEVMETHOD(device_shutdown, oce_shutdown),
203
204         DEVMETHOD_END
205 };
206
207 static driver_t oce_driver = {
208         "oce",
209         oce_dispatch,
210         sizeof(OCE_SOFTC)
211 };
212 static devclass_t oce_devclass;
213
214
215 DRIVER_MODULE(oce, pci, oce_driver, oce_devclass, 0, 0);
216 MODULE_DEPEND(oce, pci, 1, 1, 1);
217 MODULE_DEPEND(oce, ether, 1, 1, 1);
218 MODULE_VERSION(oce, 1);
219
220
221 /* global vars */
222 const char component_revision[32] = {"///" COMPONENT_REVISION "///"};
223
224 /* Module capabilites and parameters */
225 uint32_t oce_max_rsp_handled = OCE_MAX_RSP_HANDLED;
226 uint32_t oce_enable_rss = OCE_MODCAP_RSS;
227 uint32_t oce_rq_buf_size = 2048;
228
229 TUNABLE_INT("hw.oce.max_rsp_handled", &oce_max_rsp_handled);
230 TUNABLE_INT("hw.oce.enable_rss", &oce_enable_rss);
231
232
233 /* Supported devices table */
234 static uint32_t supportedDevices[] =  {
235         (PCI_VENDOR_SERVERENGINES << 16) | PCI_PRODUCT_BE2,
236         (PCI_VENDOR_SERVERENGINES << 16) | PCI_PRODUCT_BE3,
237         (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_BE3,
238         (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201,
239         (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201_VF,
240         (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_SH
241 };
242
243 POCE_SOFTC softc_head = NULL;
244 POCE_SOFTC softc_tail = NULL;
245
246 struct oce_rdma_if *oce_rdma_if = NULL;
247
248 /*****************************************************************************
249  *                      Driver entry points functions                        *
250  *****************************************************************************/
251
252 static int
253 oce_probe(device_t dev)
254 {
255         uint16_t vendor = 0;
256         uint16_t device = 0;
257         int i = 0;
258         char str[256] = {0};
259         POCE_SOFTC sc;
260
261         sc = device_get_softc(dev);
262         bzero(sc, sizeof(OCE_SOFTC));
263         sc->dev = dev;
264
265         vendor = pci_get_vendor(dev);
266         device = pci_get_device(dev);
267
268         for (i = 0; i < (sizeof(supportedDevices) / sizeof(uint32_t)); i++) {
269                 if (vendor == ((supportedDevices[i] >> 16) & 0xffff)) {
270                         if (device == (supportedDevices[i] & 0xffff)) {
271                                 sprintf(str, "%s:%s", "Emulex CNA NIC function",
272                                         component_revision);
273                                 device_set_desc_copy(dev, str);
274
275                                 switch (device) {
276                                 case PCI_PRODUCT_BE2:
277                                         sc->flags |= OCE_FLAGS_BE2;
278                                         break;
279                                 case PCI_PRODUCT_BE3:
280                                         sc->flags |= OCE_FLAGS_BE3;
281                                         break;
282                                 case PCI_PRODUCT_XE201:
283                                 case PCI_PRODUCT_XE201_VF:
284                                         sc->flags |= OCE_FLAGS_XE201;
285                                         break;
286                                 case PCI_PRODUCT_SH:
287                                         sc->flags |= OCE_FLAGS_SH;
288                                         break;
289                                 default:
290                                         return ENXIO;
291                                 }
292                                 return BUS_PROBE_DEFAULT;
293                         }
294                 }
295         }
296
297         return ENXIO;
298 }
299
300
301 static int
302 oce_attach(device_t dev)
303 {
304         POCE_SOFTC sc;
305         int rc = 0;
306
307         sc = device_get_softc(dev);
308
309         rc = oce_hw_pci_alloc(sc);
310         if (rc)
311                 return rc;
312
313         sc->tx_ring_size = OCE_TX_RING_SIZE;
314         sc->rx_ring_size = OCE_RX_RING_SIZE;
315         /* receive fragment size should be multiple of 2K */
316         sc->rq_frag_size = ((oce_rq_buf_size / 2048) * 2048);
317         sc->flow_control = OCE_DEFAULT_FLOW_CONTROL;
318         sc->promisc      = OCE_DEFAULT_PROMISCUOUS;
319
320         LOCK_CREATE(&sc->bmbx_lock, "Mailbox_lock");
321         LOCK_CREATE(&sc->dev_lock,  "Device_lock");
322
323         /* initialise the hardware */
324         rc = oce_hw_init(sc);
325         if (rc)
326                 goto pci_res_free;
327
328         oce_read_env_variables(sc);
329
330         oce_get_config(sc);
331
332         setup_max_queues_want(sc);      
333
334         rc = oce_setup_intr(sc);
335         if (rc)
336                 goto mbox_free;
337
338         rc = oce_queue_init_all(sc);
339         if (rc)
340                 goto intr_free;
341
342         rc = oce_attach_ifp(sc);
343         if (rc)
344                 goto queues_free;
345
346 #if defined(INET6) || defined(INET)
347         rc = oce_init_lro(sc);
348         if (rc)
349                 goto ifp_free;
350 #endif
351
352         rc = oce_hw_start(sc);
353         if (rc)
354                 goto lro_free;
355
356         sc->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
357                                 oce_add_vlan, sc, EVENTHANDLER_PRI_FIRST);
358         sc->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
359                                 oce_del_vlan, sc, EVENTHANDLER_PRI_FIRST);
360
361         rc = oce_stats_init(sc);
362         if (rc)
363                 goto vlan_free;
364
365         oce_add_sysctls(sc);
366
367         callout_init(&sc->timer, CALLOUT_MPSAFE);
368         rc = callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc);
369         if (rc)
370                 goto stats_free;
371
372         sc->next =NULL;
373         if (softc_tail != NULL) {
374           softc_tail->next = sc;
375         } else {
376           softc_head = sc;
377         }
378         softc_tail = sc;
379
380         return 0;
381
382 stats_free:
383         callout_drain(&sc->timer);
384         oce_stats_free(sc);
385 vlan_free:
386         if (sc->vlan_attach)
387                 EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
388         if (sc->vlan_detach)
389                 EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
390         oce_hw_intr_disable(sc);
391 lro_free:
392 #if defined(INET6) || defined(INET)
393         oce_free_lro(sc);
394 ifp_free:
395 #endif
396         ether_ifdetach(sc->ifp);
397         if_free(sc->ifp);
398 queues_free:
399         oce_queue_release_all(sc);
400 intr_free:
401         oce_intr_free(sc);
402 mbox_free:
403         oce_dma_free(sc, &sc->bsmbx);
404 pci_res_free:
405         oce_hw_pci_free(sc);
406         LOCK_DESTROY(&sc->dev_lock);
407         LOCK_DESTROY(&sc->bmbx_lock);
408         return rc;
409
410 }
411
412
413 static int
414 oce_detach(device_t dev)
415 {
416         POCE_SOFTC sc = device_get_softc(dev);
417         POCE_SOFTC poce_sc_tmp, *ppoce_sc_tmp1, poce_sc_tmp2 = NULL;
418
419         poce_sc_tmp = softc_head;
420         ppoce_sc_tmp1 = &softc_head;
421         while (poce_sc_tmp != NULL) {
422           if (poce_sc_tmp == sc) {
423             *ppoce_sc_tmp1 = sc->next;
424             if (sc->next == NULL) {
425               softc_tail = poce_sc_tmp2;
426             }
427             break;
428           }
429           poce_sc_tmp2 = poce_sc_tmp;
430           ppoce_sc_tmp1 = &poce_sc_tmp->next;
431           poce_sc_tmp = poce_sc_tmp->next;
432         }
433
434         LOCK(&sc->dev_lock);
435         oce_if_deactivate(sc);
436         UNLOCK(&sc->dev_lock);
437
438         callout_drain(&sc->timer);
439         
440         if (sc->vlan_attach != NULL)
441                 EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
442         if (sc->vlan_detach != NULL)
443                 EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
444
445         ether_ifdetach(sc->ifp);
446
447         if_free(sc->ifp);
448
449         oce_hw_shutdown(sc);
450
451         bus_generic_detach(dev);
452
453         return 0;
454 }
455
456
457 static int
458 oce_shutdown(device_t dev)
459 {
460         int rc;
461         
462         rc = oce_detach(dev);
463
464         return rc;      
465 }
466
467
468 static int
469 oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
470 {
471         struct ifreq *ifr = (struct ifreq *)data;
472         POCE_SOFTC sc = ifp->if_softc;
473         struct ifi2creq i2c;
474         uint8_t offset = 0;
475         int rc = 0;
476         uint32_t u;
477
478         switch (command) {
479
480         case SIOCGIFMEDIA:
481                 rc = ifmedia_ioctl(ifp, ifr, &sc->media, command);
482                 break;
483
484         case SIOCSIFMTU:
485                 if (ifr->ifr_mtu > OCE_MAX_MTU)
486                         rc = EINVAL;
487                 else
488                         ifp->if_mtu = ifr->ifr_mtu;
489                 break;
490
491         case SIOCSIFFLAGS:
492                 if (ifp->if_flags & IFF_UP) {
493                         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
494                                 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;       
495                                 oce_init(sc);
496                         }
497                         device_printf(sc->dev, "Interface Up\n");       
498                 } else {
499                         LOCK(&sc->dev_lock);
500
501                         sc->ifp->if_drv_flags &=
502                             ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
503                         oce_if_deactivate(sc);
504
505                         UNLOCK(&sc->dev_lock);
506
507                         device_printf(sc->dev, "Interface Down\n");
508                 }
509
510                 if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) {
511                         if (!oce_rxf_set_promiscuous(sc, (1 | (1 << 1))))
512                                 sc->promisc = TRUE;
513                 } else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) {
514                         if (!oce_rxf_set_promiscuous(sc, 0))
515                                 sc->promisc = FALSE;
516                 }
517
518                 break;
519
520         case SIOCADDMULTI:
521         case SIOCDELMULTI:
522                 rc = oce_hw_update_multicast(sc);
523                 if (rc)
524                         device_printf(sc->dev,
525                                 "Update multicast address failed\n");
526                 break;
527
528         case SIOCSIFCAP:
529                 u = ifr->ifr_reqcap ^ ifp->if_capenable;
530
531                 if (u & IFCAP_TXCSUM) {
532                         ifp->if_capenable ^= IFCAP_TXCSUM;
533                         ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
534                         
535                         if (IFCAP_TSO & ifp->if_capenable &&
536                             !(IFCAP_TXCSUM & ifp->if_capenable)) {
537                                 ifp->if_capenable &= ~IFCAP_TSO;
538                                 ifp->if_hwassist &= ~CSUM_TSO;
539                                 if_printf(ifp,
540                                          "TSO disabled due to -txcsum.\n");
541                         }
542                 }
543
544                 if (u & IFCAP_RXCSUM)
545                         ifp->if_capenable ^= IFCAP_RXCSUM;
546
547                 if (u & IFCAP_TSO4) {
548                         ifp->if_capenable ^= IFCAP_TSO4;
549
550                         if (IFCAP_TSO & ifp->if_capenable) {
551                                 if (IFCAP_TXCSUM & ifp->if_capenable)
552                                         ifp->if_hwassist |= CSUM_TSO;
553                                 else {
554                                         ifp->if_capenable &= ~IFCAP_TSO;
555                                         ifp->if_hwassist &= ~CSUM_TSO;
556                                         if_printf(ifp,
557                                             "Enable txcsum first.\n");
558                                         rc = EAGAIN;
559                                 }
560                         } else
561                                 ifp->if_hwassist &= ~CSUM_TSO;
562                 }
563
564                 if (u & IFCAP_VLAN_HWTAGGING)
565                         ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
566
567                 if (u & IFCAP_VLAN_HWFILTER) {
568                         ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
569                         oce_vid_config(sc);
570                 }
571 #if defined(INET6) || defined(INET)
572                 if (u & IFCAP_LRO) {
573                         ifp->if_capenable ^= IFCAP_LRO;
574                         if(sc->enable_hwlro) {
575                                 if(ifp->if_capenable & IFCAP_LRO) {
576                                         rc = oce_mbox_nic_set_iface_lro_config(sc, 1);
577                                 }else {
578                                         rc = oce_mbox_nic_set_iface_lro_config(sc, 0);
579                                 }
580                         }
581                 }
582 #endif
583
584                 break;
585
586         case SIOCGI2C:
587                 rc = copyin(ifr_data_get_ptr(ifr), &i2c, sizeof(i2c));
588                 if (rc)
589                         break;
590
591                 if (i2c.dev_addr != PAGE_NUM_A0 &&
592                     i2c.dev_addr != PAGE_NUM_A2) {
593                         rc = EINVAL;
594                         break;
595                 }
596
597                 if (i2c.len > sizeof(i2c.data)) {
598                         rc = EINVAL;
599                         break;
600                 }
601
602                 rc = oce_mbox_read_transrecv_data(sc, i2c.dev_addr);
603                 if(rc) {
604                         rc = -rc;
605                         break;
606                 }
607
608                 if (i2c.dev_addr == PAGE_NUM_A0)
609                         offset = i2c.offset;
610                 else
611                         offset = TRANSCEIVER_A0_SIZE + i2c.offset;
612
613                 memcpy(&i2c.data[0], &sfp_vpd_dump_buffer[offset], i2c.len);
614
615                 rc = copyout(&i2c, ifr_data_get_ptr(ifr), sizeof(i2c));
616                 break;
617
618         case SIOCGPRIVATE_0:
619                 rc = priv_check(curthread, PRIV_DRIVER);
620                 if (rc != 0)
621                         break;
622                 rc = oce_handle_passthrough(ifp, data);
623                 break;
624         default:
625                 rc = ether_ioctl(ifp, command, data);
626                 break;
627         }
628
629         return rc;
630 }
631
632
633 static void
634 oce_init(void *arg)
635 {
636         POCE_SOFTC sc = arg;
637         
638         LOCK(&sc->dev_lock);
639
640         if (sc->ifp->if_flags & IFF_UP) {
641                 oce_if_deactivate(sc);
642                 oce_if_activate(sc);
643         }
644         
645         UNLOCK(&sc->dev_lock);
646
647 }
648
649
650 static int
651 oce_multiq_start(struct ifnet *ifp, struct mbuf *m)
652 {
653         POCE_SOFTC sc = ifp->if_softc;
654         struct oce_wq *wq = NULL;
655         int queue_index = 0;
656         int status = 0;
657
658         if (!sc->link_status)
659                 return ENXIO;
660
661         if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE)
662                 queue_index = m->m_pkthdr.flowid % sc->nwqs;
663
664         wq = sc->wq[queue_index];
665
666         LOCK(&wq->tx_lock);
667         status = oce_multiq_transmit(ifp, m, wq);
668         UNLOCK(&wq->tx_lock);
669
670         return status;
671
672 }
673
674
675 static void
676 oce_multiq_flush(struct ifnet *ifp)
677 {
678         POCE_SOFTC sc = ifp->if_softc;
679         struct mbuf     *m;
680         int i = 0;
681
682         for (i = 0; i < sc->nwqs; i++) {
683                 while ((m = buf_ring_dequeue_sc(sc->wq[i]->br)) != NULL)
684                         m_freem(m);
685         }
686         if_qflush(ifp);
687 }
688
689
690
691 /*****************************************************************************
692  *                   Driver interrupt routines functions                     *
693  *****************************************************************************/
694
695 static void
696 oce_intr(void *arg, int pending)
697 {
698
699         POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
700         POCE_SOFTC sc = ii->sc;
701         struct oce_eq *eq = ii->eq;
702         struct oce_eqe *eqe;
703         struct oce_cq *cq = NULL;
704         int i, num_eqes = 0;
705
706
707         bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
708                                  BUS_DMASYNC_POSTWRITE);
709         do {
710                 eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
711                 if (eqe->evnt == 0)
712                         break;
713                 eqe->evnt = 0;
714                 bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
715                                         BUS_DMASYNC_POSTWRITE);
716                 RING_GET(eq->ring, 1);
717                 num_eqes++;
718
719         } while (TRUE);
720         
721         if (!num_eqes)
722                 goto eq_arm; /* Spurious */
723
724         /* Clear EQ entries, but dont arm */
725         oce_arm_eq(sc, eq->eq_id, num_eqes, FALSE, FALSE);
726
727         /* Process TX, RX and MCC. But dont arm CQ*/
728         for (i = 0; i < eq->cq_valid; i++) {
729                 cq = eq->cq[i];
730                 (*cq->cq_handler)(cq->cb_arg);
731         }
732
733         /* Arm all cqs connected to this EQ */
734         for (i = 0; i < eq->cq_valid; i++) {
735                 cq = eq->cq[i];
736                 oce_arm_cq(sc, cq->cq_id, 0, TRUE);
737         }
738
739 eq_arm:
740         oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
741
742         return;
743 }
744
745
746 static int
747 oce_setup_intr(POCE_SOFTC sc)
748 {
749         int rc = 0, use_intx = 0;
750         int vector = 0, req_vectors = 0;
751         int tot_req_vectors, tot_vectors;
752
753         if (is_rss_enabled(sc))
754                 req_vectors = MAX((sc->nrqs - 1), sc->nwqs);
755         else
756                 req_vectors = 1;
757
758         tot_req_vectors = req_vectors;
759         if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) {
760           if (req_vectors > 1) {
761             tot_req_vectors += OCE_RDMA_VECTORS;
762             sc->roce_intr_count = OCE_RDMA_VECTORS;
763           }
764         }
765
766         if (sc->flags & OCE_FLAGS_MSIX_CAPABLE) {
767                 sc->intr_count = req_vectors;
768                 tot_vectors = tot_req_vectors;
769                 rc = pci_alloc_msix(sc->dev, &tot_vectors);
770                 if (rc != 0) {
771                         use_intx = 1;
772                         pci_release_msi(sc->dev);
773                 } else {
774                   if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) {
775                     if (tot_vectors < tot_req_vectors) {
776                       if (sc->intr_count < (2 * OCE_RDMA_VECTORS)) {
777                         sc->roce_intr_count = (tot_vectors / 2);
778                       }
779                       sc->intr_count = tot_vectors - sc->roce_intr_count;
780                     }
781                   } else {
782                     sc->intr_count = tot_vectors;
783                   }
784                   sc->flags |= OCE_FLAGS_USING_MSIX;
785                 }
786         } else
787                 use_intx = 1;
788
789         if (use_intx)
790                 sc->intr_count = 1;
791
792         /* Scale number of queues based on intr we got */
793         update_queues_got(sc);
794
795         if (use_intx) {
796                 device_printf(sc->dev, "Using legacy interrupt\n");
797                 rc = oce_alloc_intr(sc, vector, oce_intr);
798                 if (rc)
799                         goto error;             
800         } else {
801                 for (; vector < sc->intr_count; vector++) {
802                         rc = oce_alloc_intr(sc, vector, oce_intr);
803                         if (rc)
804                                 goto error;
805                 }
806         }
807
808         return 0;
809 error:
810         oce_intr_free(sc);
811         return rc;
812 }
813
814
815 static int
816 oce_fast_isr(void *arg)
817 {
818         POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
819         POCE_SOFTC sc = ii->sc;
820
821         if (ii->eq == NULL)
822                 return FILTER_STRAY;
823
824         oce_arm_eq(sc, ii->eq->eq_id, 0, FALSE, TRUE);
825
826         taskqueue_enqueue(ii->tq, &ii->task);
827
828         ii->eq->intr++; 
829
830         return FILTER_HANDLED;
831 }
832
833
834 static int
835 oce_alloc_intr(POCE_SOFTC sc, int vector, void (*isr) (void *arg, int pending))
836 {
837         POCE_INTR_INFO ii = &sc->intrs[vector];
838         int rc = 0, rr;
839
840         if (vector >= OCE_MAX_EQ)
841                 return (EINVAL);
842
843         /* Set the resource id for the interrupt.
844          * MSIx is vector + 1 for the resource id,
845          * INTx is 0 for the resource id.
846          */
847         if (sc->flags & OCE_FLAGS_USING_MSIX)
848                 rr = vector + 1;
849         else
850                 rr = 0;
851         ii->intr_res = bus_alloc_resource_any(sc->dev,
852                                               SYS_RES_IRQ,
853                                               &rr, RF_ACTIVE|RF_SHAREABLE);
854         ii->irq_rr = rr;
855         if (ii->intr_res == NULL) {
856                 device_printf(sc->dev,
857                           "Could not allocate interrupt\n");
858                 rc = ENXIO;
859                 return rc;
860         }
861
862         TASK_INIT(&ii->task, 0, isr, ii);
863         ii->vector = vector;
864         sprintf(ii->task_name, "oce_task[%d]", ii->vector);
865         ii->tq = taskqueue_create_fast(ii->task_name,
866                         M_NOWAIT,
867                         taskqueue_thread_enqueue,
868                         &ii->tq);
869         taskqueue_start_threads(&ii->tq, 1, PI_NET, "%s taskq",
870                         device_get_nameunit(sc->dev));
871
872         ii->sc = sc;
873         rc = bus_setup_intr(sc->dev,
874                         ii->intr_res,
875                         INTR_TYPE_NET,
876                         oce_fast_isr, NULL, ii, &ii->tag);
877         return rc;
878
879 }
880
881
882 void
883 oce_intr_free(POCE_SOFTC sc)
884 {
885         int i = 0;
886         
887         for (i = 0; i < sc->intr_count; i++) {
888                 
889                 if (sc->intrs[i].tag != NULL)
890                         bus_teardown_intr(sc->dev, sc->intrs[i].intr_res,
891                                                 sc->intrs[i].tag);
892                 if (sc->intrs[i].tq != NULL)
893                         taskqueue_free(sc->intrs[i].tq);
894                 
895                 if (sc->intrs[i].intr_res != NULL)
896                         bus_release_resource(sc->dev, SYS_RES_IRQ,
897                                                 sc->intrs[i].irq_rr,
898                                                 sc->intrs[i].intr_res);
899                 sc->intrs[i].tag = NULL;
900                 sc->intrs[i].intr_res = NULL;
901         }
902
903         if (sc->flags & OCE_FLAGS_USING_MSIX)
904                 pci_release_msi(sc->dev);
905
906 }
907
908
909
910 /******************************************************************************
911 *                         Media callbacks functions                           *
912 ******************************************************************************/
913
914 static void
915 oce_media_status(struct ifnet *ifp, struct ifmediareq *req)
916 {
917         POCE_SOFTC sc = (POCE_SOFTC) ifp->if_softc;
918
919
920         req->ifm_status = IFM_AVALID;
921         req->ifm_active = IFM_ETHER;
922         
923         if (sc->link_status == 1)
924                 req->ifm_status |= IFM_ACTIVE;
925         else 
926                 return;
927         
928         switch (sc->link_speed) {
929         case 1: /* 10 Mbps */
930                 req->ifm_active |= IFM_10_T | IFM_FDX;
931                 sc->speed = 10;
932                 break;
933         case 2: /* 100 Mbps */
934                 req->ifm_active |= IFM_100_TX | IFM_FDX;
935                 sc->speed = 100;
936                 break;
937         case 3: /* 1 Gbps */
938                 req->ifm_active |= IFM_1000_T | IFM_FDX;
939                 sc->speed = 1000;
940                 break;
941         case 4: /* 10 Gbps */
942                 req->ifm_active |= IFM_10G_SR | IFM_FDX;
943                 sc->speed = 10000;
944                 break;
945         case 5: /* 20 Gbps */
946                 req->ifm_active |= IFM_10G_SR | IFM_FDX;
947                 sc->speed = 20000;
948                 break;
949         case 6: /* 25 Gbps */
950                 req->ifm_active |= IFM_10G_SR | IFM_FDX;
951                 sc->speed = 25000;
952                 break;
953         case 7: /* 40 Gbps */
954                 req->ifm_active |= IFM_40G_SR4 | IFM_FDX;
955                 sc->speed = 40000;
956                 break;
957         default:
958                 sc->speed = 0;
959                 break;
960         }
961         
962         return;
963 }
964
965
966 int
967 oce_media_change(struct ifnet *ifp)
968 {
969         return 0;
970 }
971
972
973 static void oce_is_pkt_dest_bmc(POCE_SOFTC sc,
974                                 struct mbuf *m, boolean_t *os2bmc,
975                                 struct mbuf **m_new)
976 {
977         struct ether_header *eh = NULL;
978
979         eh = mtod(m, struct ether_header *);
980
981         if (!is_os2bmc_enabled(sc) || *os2bmc) {
982                 *os2bmc = FALSE;
983                 goto done;
984         }
985         if (!ETHER_IS_MULTICAST(eh->ether_dhost))
986                 goto done;
987
988         if (is_mc_allowed_on_bmc(sc, eh) ||
989             is_bc_allowed_on_bmc(sc, eh) ||
990             is_arp_allowed_on_bmc(sc, ntohs(eh->ether_type))) {
991                 *os2bmc = TRUE;
992                 goto done;
993         }
994
995         if (mtod(m, struct ip *)->ip_p == IPPROTO_IPV6) {
996                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
997                 uint8_t nexthdr = ip6->ip6_nxt;
998                 if (nexthdr == IPPROTO_ICMPV6) {
999                         struct icmp6_hdr *icmp6 = (struct icmp6_hdr *)(ip6 + 1);
1000                         switch (icmp6->icmp6_type) {
1001                         case ND_ROUTER_ADVERT:
1002                                 *os2bmc = is_ipv6_ra_filt_enabled(sc);
1003                                 goto done;
1004                         case ND_NEIGHBOR_ADVERT:
1005                                 *os2bmc = is_ipv6_na_filt_enabled(sc);
1006                                 goto done;
1007                         default:
1008                                 break;
1009                         }
1010                 }
1011         }
1012
1013         if (mtod(m, struct ip *)->ip_p == IPPROTO_UDP) {
1014                 struct ip *ip = mtod(m, struct ip *);
1015                 int iphlen = ip->ip_hl << 2;
1016                 struct udphdr *uh = (struct udphdr *)((caddr_t)ip + iphlen);
1017                 switch (uh->uh_dport) {
1018                 case DHCP_CLIENT_PORT:
1019                         *os2bmc = is_dhcp_client_filt_enabled(sc);
1020                         goto done;
1021                 case DHCP_SERVER_PORT:
1022                         *os2bmc = is_dhcp_srvr_filt_enabled(sc);
1023                         goto done;
1024                 case NET_BIOS_PORT1:
1025                 case NET_BIOS_PORT2:
1026                         *os2bmc = is_nbios_filt_enabled(sc);
1027                         goto done;
1028                 case DHCPV6_RAS_PORT:
1029                         *os2bmc = is_ipv6_ras_filt_enabled(sc);
1030                         goto done;
1031                 default:
1032                         break;
1033                 }
1034         }
1035 done:
1036         if (*os2bmc) {
1037                 *m_new = m_dup(m, M_NOWAIT);
1038                 if (!*m_new) {
1039                         *os2bmc = FALSE;
1040                         return;
1041                 }
1042                 *m_new = oce_insert_vlan_tag(sc, *m_new, NULL);
1043         }
1044 }
1045
1046
1047
1048 /*****************************************************************************
1049  *                        Transmit routines functions                        *
1050  *****************************************************************************/
1051
1052 static int
1053 oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
1054 {
1055         int rc = 0, i, retry_cnt = 0;
1056         bus_dma_segment_t segs[OCE_MAX_TX_ELEMENTS];
1057         struct mbuf *m, *m_temp, *m_new = NULL;
1058         struct oce_wq *wq = sc->wq[wq_index];
1059         struct oce_packet_desc *pd;
1060         struct oce_nic_hdr_wqe *nichdr;
1061         struct oce_nic_frag_wqe *nicfrag;
1062         struct ether_header *eh = NULL;
1063         int num_wqes;
1064         uint32_t reg_value;
1065         boolean_t complete = TRUE;
1066         boolean_t os2bmc = FALSE;
1067
1068         m = *mpp;
1069         if (!m)
1070                 return EINVAL;
1071
1072         if (!(m->m_flags & M_PKTHDR)) {
1073                 rc = ENXIO;
1074                 goto free_ret;
1075         }
1076
1077         /* Don't allow non-TSO packets longer than MTU */
1078         if (!is_tso_pkt(m)) {
1079                 eh = mtod(m, struct ether_header *);
1080                 if(m->m_pkthdr.len > ETHER_MAX_FRAME(sc->ifp, eh->ether_type, FALSE))
1081                          goto free_ret;
1082         }
1083
1084         if(oce_tx_asic_stall_verify(sc, m)) {
1085                 m = oce_insert_vlan_tag(sc, m, &complete);
1086                 if(!m) {
1087                         device_printf(sc->dev, "Insertion unsuccessful\n");
1088                         return 0;
1089                 }
1090
1091         }
1092
1093         /* Lancer, SH ASIC has a bug wherein Packets that are 32 bytes or less
1094          * may cause a transmit stall on that port. So the work-around is to
1095          * pad short packets (<= 32 bytes) to a 36-byte length.
1096         */
1097         if(IS_SH(sc) || IS_XE201(sc) ) {
1098                 if(m->m_pkthdr.len <= 32) {
1099                         char buf[36];
1100                         bzero((void *)buf, 36);
1101                         m_append(m, (36 - m->m_pkthdr.len), buf);
1102                 }
1103         }
1104
1105 tx_start:
1106         if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1107                 /* consolidate packet buffers for TSO/LSO segment offload */
1108 #if defined(INET6) || defined(INET)
1109                 m = oce_tso_setup(sc, mpp);
1110 #else
1111                 m = NULL;
1112 #endif
1113                 if (m == NULL) {
1114                         rc = ENXIO;
1115                         goto free_ret;
1116                 }
1117         }
1118
1119
1120         pd = &wq->pckts[wq->pkt_desc_head];
1121
1122 retry:
1123         rc = bus_dmamap_load_mbuf_sg(wq->tag,
1124                                      pd->map,
1125                                      m, segs, &pd->nsegs, BUS_DMA_NOWAIT);
1126         if (rc == 0) {
1127                 num_wqes = pd->nsegs + 1;
1128                 if (IS_BE(sc) || IS_SH(sc)) {
1129                         /*Dummy required only for BE3.*/
1130                         if (num_wqes & 1)
1131                                 num_wqes++;
1132                 }
1133                 if (num_wqes >= RING_NUM_FREE(wq->ring)) {
1134                         bus_dmamap_unload(wq->tag, pd->map);
1135                         return EBUSY;
1136                 }
1137                 atomic_store_rel_int(&wq->pkt_desc_head,
1138                                      (wq->pkt_desc_head + 1) % \
1139                                       OCE_WQ_PACKET_ARRAY_SIZE);
1140                 bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_PREWRITE);
1141                 pd->mbuf = m;
1142
1143                 nichdr =
1144                     RING_GET_PRODUCER_ITEM_VA(wq->ring, struct oce_nic_hdr_wqe);
1145                 nichdr->u0.dw[0] = 0;
1146                 nichdr->u0.dw[1] = 0;
1147                 nichdr->u0.dw[2] = 0;
1148                 nichdr->u0.dw[3] = 0;
1149
1150                 nichdr->u0.s.complete = complete;
1151                 nichdr->u0.s.mgmt = os2bmc;
1152                 nichdr->u0.s.event = 1;
1153                 nichdr->u0.s.crc = 1;
1154                 nichdr->u0.s.forward = 0;
1155                 nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0;
1156                 nichdr->u0.s.udpcs =
1157                         (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
1158                 nichdr->u0.s.tcpcs =
1159                         (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
1160                 nichdr->u0.s.num_wqe = num_wqes;
1161                 nichdr->u0.s.total_length = m->m_pkthdr.len;
1162
1163                 if (m->m_flags & M_VLANTAG) {
1164                         nichdr->u0.s.vlan = 1; /*Vlan present*/
1165                         nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag;
1166                 }
1167
1168                 if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1169                         if (m->m_pkthdr.tso_segsz) {
1170                                 nichdr->u0.s.lso = 1;
1171                                 nichdr->u0.s.lso_mss  = m->m_pkthdr.tso_segsz;
1172                         }
1173                         if (!IS_BE(sc) || !IS_SH(sc))
1174                                 nichdr->u0.s.ipcs = 1;
1175                 }
1176
1177                 RING_PUT(wq->ring, 1);
1178                 atomic_add_int(&wq->ring->num_used, 1);
1179
1180                 for (i = 0; i < pd->nsegs; i++) {
1181                         nicfrag =
1182                             RING_GET_PRODUCER_ITEM_VA(wq->ring,
1183                                                       struct oce_nic_frag_wqe);
1184                         nicfrag->u0.s.rsvd0 = 0;
1185                         nicfrag->u0.s.frag_pa_hi = ADDR_HI(segs[i].ds_addr);
1186                         nicfrag->u0.s.frag_pa_lo = ADDR_LO(segs[i].ds_addr);
1187                         nicfrag->u0.s.frag_len = segs[i].ds_len;
1188                         pd->wqe_idx = wq->ring->pidx;
1189                         RING_PUT(wq->ring, 1);
1190                         atomic_add_int(&wq->ring->num_used, 1);
1191                 }
1192                 if (num_wqes > (pd->nsegs + 1)) {
1193                         nicfrag =
1194                             RING_GET_PRODUCER_ITEM_VA(wq->ring,
1195                                                       struct oce_nic_frag_wqe);
1196                         nicfrag->u0.dw[0] = 0;
1197                         nicfrag->u0.dw[1] = 0;
1198                         nicfrag->u0.dw[2] = 0;
1199                         nicfrag->u0.dw[3] = 0;
1200                         pd->wqe_idx = wq->ring->pidx;
1201                         RING_PUT(wq->ring, 1);
1202                         atomic_add_int(&wq->ring->num_used, 1);
1203                         pd->nsegs++;
1204                 }
1205
1206                 if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
1207                 wq->tx_stats.tx_reqs++;
1208                 wq->tx_stats.tx_wrbs += num_wqes;
1209                 wq->tx_stats.tx_bytes += m->m_pkthdr.len;
1210                 wq->tx_stats.tx_pkts++;
1211
1212                 bus_dmamap_sync(wq->ring->dma.tag, wq->ring->dma.map,
1213                                 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1214                 reg_value = (num_wqes << 16) | wq->wq_id;
1215
1216                 /* if os2bmc is not enabled or if the pkt is already tagged as
1217                    bmc, do nothing
1218                  */
1219                 oce_is_pkt_dest_bmc(sc, m, &os2bmc, &m_new);
1220
1221                 OCE_WRITE_REG32(sc, db, wq->db_offset, reg_value);
1222
1223         } else if (rc == EFBIG) {
1224                 if (retry_cnt == 0) {
1225                         m_temp = m_defrag(m, M_NOWAIT);
1226                         if (m_temp == NULL)
1227                                 goto free_ret;
1228                         m = m_temp;
1229                         *mpp = m_temp;
1230                         retry_cnt = retry_cnt + 1;
1231                         goto retry;
1232                 } else
1233                         goto free_ret;
1234         } else if (rc == ENOMEM)
1235                 return rc;
1236         else
1237                 goto free_ret;
1238
1239         if (os2bmc) {
1240                 m = m_new;
1241                 goto tx_start;
1242         }
1243         
1244         return 0;
1245
1246 free_ret:
1247         m_freem(*mpp);
1248         *mpp = NULL;
1249         return rc;
1250 }
1251
1252
1253 static void
1254 oce_process_tx_completion(struct oce_wq *wq)
1255 {
1256         struct oce_packet_desc *pd;
1257         POCE_SOFTC sc = (POCE_SOFTC) wq->parent;
1258         struct mbuf *m;
1259
1260         pd = &wq->pckts[wq->pkt_desc_tail];
1261         atomic_store_rel_int(&wq->pkt_desc_tail,
1262                              (wq->pkt_desc_tail + 1) % OCE_WQ_PACKET_ARRAY_SIZE); 
1263         atomic_subtract_int(&wq->ring->num_used, pd->nsegs + 1);
1264         bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1265         bus_dmamap_unload(wq->tag, pd->map);
1266
1267         m = pd->mbuf;
1268         m_freem(m);
1269         pd->mbuf = NULL;
1270
1271
1272         if (sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) {
1273                 if (wq->ring->num_used < (wq->ring->num_items / 2)) {
1274                         sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE);
1275                         oce_tx_restart(sc, wq); 
1276                 }
1277         }
1278 }
1279
1280
1281 static void
1282 oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq)
1283 {
1284
1285         if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING)
1286                 return;
1287
1288 #if __FreeBSD_version >= 800000
1289         if (!drbr_empty(sc->ifp, wq->br))
1290 #else
1291         if (!IFQ_DRV_IS_EMPTY(&sc->ifp->if_snd))
1292 #endif
1293                 taskqueue_enqueue(taskqueue_swi, &wq->txtask);
1294
1295 }
1296
1297
1298 #if defined(INET6) || defined(INET)
1299 static struct mbuf *
1300 oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp)
1301 {
1302         struct mbuf *m;
1303 #ifdef INET
1304         struct ip *ip;
1305 #endif
1306 #ifdef INET6
1307         struct ip6_hdr *ip6;
1308 #endif
1309         struct ether_vlan_header *eh;
1310         struct tcphdr *th;
1311         uint16_t etype;
1312         int total_len = 0, ehdrlen = 0;
1313         
1314         m = *mpp;
1315
1316         if (M_WRITABLE(m) == 0) {
1317                 m = m_dup(*mpp, M_NOWAIT);
1318                 if (!m)
1319                         return NULL;
1320                 m_freem(*mpp);
1321                 *mpp = m;
1322         }
1323
1324         eh = mtod(m, struct ether_vlan_header *);
1325         if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
1326                 etype = ntohs(eh->evl_proto);
1327                 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
1328         } else {
1329                 etype = ntohs(eh->evl_encap_proto);
1330                 ehdrlen = ETHER_HDR_LEN;
1331         }
1332
1333         switch (etype) {
1334 #ifdef INET
1335         case ETHERTYPE_IP:
1336                 ip = (struct ip *)(m->m_data + ehdrlen);
1337                 if (ip->ip_p != IPPROTO_TCP)
1338                         return NULL;
1339                 th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
1340
1341                 total_len = ehdrlen + (ip->ip_hl << 2) + (th->th_off << 2);
1342                 break;
1343 #endif
1344 #ifdef INET6
1345         case ETHERTYPE_IPV6:
1346                 ip6 = (struct ip6_hdr *)(m->m_data + ehdrlen);
1347                 if (ip6->ip6_nxt != IPPROTO_TCP)
1348                         return NULL;
1349                 th = (struct tcphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr));
1350
1351                 total_len = ehdrlen + sizeof(struct ip6_hdr) + (th->th_off << 2);
1352                 break;
1353 #endif
1354         default:
1355                 return NULL;
1356         }
1357         
1358         m = m_pullup(m, total_len);
1359         if (!m)
1360                 return NULL;
1361         *mpp = m;
1362         return m;
1363         
1364 }
1365 #endif /* INET6 || INET */
1366
1367 void
1368 oce_tx_task(void *arg, int npending)
1369 {
1370         struct oce_wq *wq = arg;
1371         POCE_SOFTC sc = wq->parent;
1372         struct ifnet *ifp = sc->ifp;
1373         int rc = 0;
1374
1375 #if __FreeBSD_version >= 800000
1376         LOCK(&wq->tx_lock);
1377         rc = oce_multiq_transmit(ifp, NULL, wq);
1378         if (rc) {
1379                 device_printf(sc->dev,
1380                                 "TX[%d] restart failed\n", wq->queue_index);
1381         }
1382         UNLOCK(&wq->tx_lock);
1383 #else
1384         oce_start(ifp);
1385 #endif
1386
1387 }
1388
1389
1390 void
1391 oce_start(struct ifnet *ifp)
1392 {
1393         POCE_SOFTC sc = ifp->if_softc;
1394         struct mbuf *m;
1395         int rc = 0;
1396         int def_q = 0; /* Defualt tx queue is 0*/
1397
1398         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
1399                         IFF_DRV_RUNNING)
1400                 return;
1401
1402         if (!sc->link_status)
1403                 return;
1404         
1405         do {
1406                 IF_DEQUEUE(&sc->ifp->if_snd, m);
1407                 if (m == NULL)
1408                         break;
1409
1410                 LOCK(&sc->wq[def_q]->tx_lock);
1411                 rc = oce_tx(sc, &m, def_q);
1412                 UNLOCK(&sc->wq[def_q]->tx_lock);
1413                 if (rc) {
1414                         if (m != NULL) {
1415                                 sc->wq[def_q]->tx_stats.tx_stops ++;
1416                                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1417                                 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1418                                 m = NULL;
1419                         }
1420                         break;
1421                 }
1422                 if (m != NULL)
1423                         ETHER_BPF_MTAP(ifp, m);
1424
1425         } while (TRUE);
1426
1427         return;
1428 }
1429
1430
1431 /* Handle the Completion Queue for transmit */
1432 uint16_t
1433 oce_wq_handler(void *arg)
1434 {
1435         struct oce_wq *wq = (struct oce_wq *)arg;
1436         POCE_SOFTC sc = wq->parent;
1437         struct oce_cq *cq = wq->cq;
1438         struct oce_nic_tx_cqe *cqe;
1439         int num_cqes = 0;
1440
1441         LOCK(&wq->tx_compl_lock);
1442         bus_dmamap_sync(cq->ring->dma.tag,
1443                         cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1444         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
1445         while (cqe->u0.dw[3]) {
1446                 DW_SWAP((uint32_t *) cqe, sizeof(oce_wq_cqe));
1447
1448                 wq->ring->cidx = cqe->u0.s.wqe_index + 1;
1449                 if (wq->ring->cidx >= wq->ring->num_items)
1450                         wq->ring->cidx -= wq->ring->num_items;
1451
1452                 oce_process_tx_completion(wq);
1453                 wq->tx_stats.tx_compl++;
1454                 cqe->u0.dw[3] = 0;
1455                 RING_GET(cq->ring, 1);
1456                 bus_dmamap_sync(cq->ring->dma.tag,
1457                                 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1458                 cqe =
1459                     RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
1460                 num_cqes++;
1461         }
1462
1463         if (num_cqes)
1464                 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
1465         
1466         UNLOCK(&wq->tx_compl_lock);
1467         return num_cqes;
1468 }
1469
1470
1471 static int 
1472 oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
1473 {
1474         POCE_SOFTC sc = ifp->if_softc;
1475         int status = 0, queue_index = 0;
1476         struct mbuf *next = NULL;
1477         struct buf_ring *br = NULL;
1478
1479         br  = wq->br;
1480         queue_index = wq->queue_index;
1481
1482         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
1483                 IFF_DRV_RUNNING) {
1484                 if (m != NULL)
1485                         status = drbr_enqueue(ifp, br, m);
1486                 return status;
1487         }
1488
1489         if (m != NULL) {
1490                 if ((status = drbr_enqueue(ifp, br, m)) != 0)
1491                         return status;
1492         } 
1493         while ((next = drbr_peek(ifp, br)) != NULL) {
1494                 if (oce_tx(sc, &next, queue_index)) {
1495                         if (next == NULL) {
1496                                 drbr_advance(ifp, br);
1497                         } else {
1498                                 drbr_putback(ifp, br, next);
1499                                 wq->tx_stats.tx_stops ++;
1500                                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1501                         }  
1502                         break;
1503                 }
1504                 drbr_advance(ifp, br);
1505                 if_inc_counter(ifp, IFCOUNTER_OBYTES, next->m_pkthdr.len);
1506                 if (next->m_flags & M_MCAST)
1507                         if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
1508                 ETHER_BPF_MTAP(ifp, next);
1509         }
1510
1511         return 0;
1512 }
1513
1514
1515
1516
1517 /*****************************************************************************
1518  *                          Receive  routines functions                      *
1519  *****************************************************************************/
1520
1521 static void
1522 oce_correct_header(struct mbuf *m, struct nic_hwlro_cqe_part1 *cqe1, struct nic_hwlro_cqe_part2 *cqe2)
1523 {
1524         uint32_t *p;
1525         struct ether_header *eh = NULL;
1526         struct tcphdr *tcp_hdr = NULL;
1527         struct ip *ip4_hdr = NULL;
1528         struct ip6_hdr *ip6 = NULL;
1529         uint32_t payload_len = 0;
1530
1531         eh = mtod(m, struct ether_header *);
1532         /* correct IP header */
1533         if(!cqe2->ipv6_frame) {
1534                 ip4_hdr = (struct ip *)((char*)eh + sizeof(struct ether_header));
1535                 ip4_hdr->ip_ttl = cqe2->frame_lifespan;
1536                 ip4_hdr->ip_len = htons(cqe2->coalesced_size - sizeof(struct ether_header));
1537                 tcp_hdr = (struct tcphdr *)((char*)ip4_hdr + sizeof(struct ip));
1538         }else {
1539                 ip6 = (struct ip6_hdr *)((char*)eh + sizeof(struct ether_header));
1540                 ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim = cqe2->frame_lifespan;
1541                 payload_len = cqe2->coalesced_size - sizeof(struct ether_header)
1542                                                 - sizeof(struct ip6_hdr);
1543                 ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(payload_len);
1544                 tcp_hdr = (struct tcphdr *)((char*)ip6 + sizeof(struct ip6_hdr));
1545         }
1546
1547         /* correct tcp header */
1548         tcp_hdr->th_ack = htonl(cqe2->tcp_ack_num);
1549         if(cqe2->push) {
1550                 tcp_hdr->th_flags |= TH_PUSH;
1551         }
1552         tcp_hdr->th_win = htons(cqe2->tcp_window);
1553         tcp_hdr->th_sum = 0xffff;
1554         if(cqe2->ts_opt) {
1555                 p = (uint32_t *)((char*)tcp_hdr + sizeof(struct tcphdr) + 2);
1556                 *p = cqe1->tcp_timestamp_val;
1557                 *(p+1) = cqe1->tcp_timestamp_ecr;
1558         }
1559
1560         return;
1561 }
1562
1563 static void
1564 oce_rx_mbuf_chain(struct oce_rq *rq, struct oce_common_cqe_info *cqe_info, struct mbuf **m)
1565 {
1566         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1567         uint32_t i = 0, frag_len = 0;
1568         uint32_t len = cqe_info->pkt_size;
1569         struct oce_packet_desc *pd;
1570         struct mbuf *tail = NULL;
1571
1572         for (i = 0; i < cqe_info->num_frags; i++) {
1573                 if (rq->ring->cidx == rq->ring->pidx) {
1574                         device_printf(sc->dev,
1575                                   "oce_rx_mbuf_chain: Invalid RX completion - Queue is empty\n");
1576                         return;
1577                 }
1578                 pd = &rq->pckts[rq->ring->cidx];
1579
1580                 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1581                 bus_dmamap_unload(rq->tag, pd->map);
1582                 RING_GET(rq->ring, 1);
1583                 rq->pending--;
1584
1585                 frag_len = (len > rq->cfg.frag_size) ? rq->cfg.frag_size : len;
1586                 pd->mbuf->m_len = frag_len;
1587
1588                 if (tail != NULL) {
1589                         /* additional fragments */
1590                         pd->mbuf->m_flags &= ~M_PKTHDR;
1591                         tail->m_next = pd->mbuf;
1592                         if(rq->islro)
1593                                 tail->m_nextpkt = NULL;
1594                         tail = pd->mbuf;
1595                 } else {
1596                         /* first fragment, fill out much of the packet header */
1597                         pd->mbuf->m_pkthdr.len = len;
1598                         if(rq->islro)
1599                                 pd->mbuf->m_nextpkt = NULL;
1600                         pd->mbuf->m_pkthdr.csum_flags = 0;
1601                         if (IF_CSUM_ENABLED(sc)) {
1602                                 if (cqe_info->l4_cksum_pass) {
1603                                         if(!cqe_info->ipv6_frame) { /* IPV4 */
1604                                                 pd->mbuf->m_pkthdr.csum_flags |=
1605                                                         (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
1606                                         }else { /* IPV6 frame */
1607                                                 if(rq->islro) {
1608                                                         pd->mbuf->m_pkthdr.csum_flags |=
1609                                                         (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
1610                                                 }
1611                                         }
1612                                         pd->mbuf->m_pkthdr.csum_data = 0xffff;
1613                                 }
1614                                 if (cqe_info->ip_cksum_pass) {
1615                                         pd->mbuf->m_pkthdr.csum_flags |=
1616                                                (CSUM_IP_CHECKED|CSUM_IP_VALID);
1617                                 }
1618                         }
1619                         *m = tail = pd->mbuf;
1620                }
1621                 pd->mbuf = NULL;
1622                 len -= frag_len;
1623         }
1624
1625         return;
1626 }
1627
1628 static void
1629 oce_rx_lro(struct oce_rq *rq, struct nic_hwlro_singleton_cqe *cqe, struct nic_hwlro_cqe_part2 *cqe2)
1630 {
1631         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1632         struct nic_hwlro_cqe_part1 *cqe1 = NULL;
1633         struct mbuf *m = NULL;
1634         struct oce_common_cqe_info cq_info;
1635
1636         /* parse cqe */
1637         if(cqe2 == NULL) {
1638                 cq_info.pkt_size =  cqe->pkt_size;
1639                 cq_info.vtag = cqe->vlan_tag;
1640                 cq_info.l4_cksum_pass = cqe->l4_cksum_pass;
1641                 cq_info.ip_cksum_pass = cqe->ip_cksum_pass;
1642                 cq_info.ipv6_frame = cqe->ipv6_frame;
1643                 cq_info.vtp = cqe->vtp;
1644                 cq_info.qnq = cqe->qnq;
1645         }else {
1646                 cqe1 = (struct nic_hwlro_cqe_part1 *)cqe;
1647                 cq_info.pkt_size =  cqe2->coalesced_size;
1648                 cq_info.vtag = cqe2->vlan_tag;
1649                 cq_info.l4_cksum_pass = cqe2->l4_cksum_pass;
1650                 cq_info.ip_cksum_pass = cqe2->ip_cksum_pass;
1651                 cq_info.ipv6_frame = cqe2->ipv6_frame;
1652                 cq_info.vtp = cqe2->vtp;
1653                 cq_info.qnq = cqe1->qnq;
1654         }
1655         
1656         cq_info.vtag = BSWAP_16(cq_info.vtag);
1657
1658         cq_info.num_frags = cq_info.pkt_size / rq->cfg.frag_size;
1659         if(cq_info.pkt_size % rq->cfg.frag_size)
1660                 cq_info.num_frags++;
1661
1662         oce_rx_mbuf_chain(rq, &cq_info, &m);
1663
1664         if (m) {
1665                 if(cqe2) {
1666                         //assert(cqe2->valid != 0);
1667                         
1668                         //assert(cqe2->cqe_type != 2);
1669                         oce_correct_header(m, cqe1, cqe2);
1670                 }
1671
1672                 m->m_pkthdr.rcvif = sc->ifp;
1673 #if __FreeBSD_version >= 800000
1674                 if (rq->queue_index)
1675                         m->m_pkthdr.flowid = (rq->queue_index - 1);
1676                 else
1677                         m->m_pkthdr.flowid = rq->queue_index;
1678                 M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
1679 #endif
1680                 /* This deternies if vlan tag is Valid */
1681                 if (cq_info.vtp) {
1682                         if (sc->function_mode & FNM_FLEX10_MODE) {
1683                                 /* FLEX10. If QnQ is not set, neglect VLAN */
1684                                 if (cq_info.qnq) {
1685                                         m->m_pkthdr.ether_vtag = cq_info.vtag;
1686                                         m->m_flags |= M_VLANTAG;
1687                                 }
1688                         } else if (sc->pvid != (cq_info.vtag & VLAN_VID_MASK))  {
1689                                 /* In UMC mode generally pvid will be striped by
1690                                    hw. But in some cases we have seen it comes
1691                                    with pvid. So if pvid == vlan, neglect vlan.
1692                                  */
1693                                 m->m_pkthdr.ether_vtag = cq_info.vtag;
1694                                 m->m_flags |= M_VLANTAG;
1695                         }
1696                 }
1697                 if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
1698                 
1699                 (*sc->ifp->if_input) (sc->ifp, m);
1700
1701                 /* Update rx stats per queue */
1702                 rq->rx_stats.rx_pkts++;
1703                 rq->rx_stats.rx_bytes += cq_info.pkt_size;
1704                 rq->rx_stats.rx_frags += cq_info.num_frags;
1705                 rq->rx_stats.rx_ucast_pkts++;
1706         }
1707         return;
1708 }
1709
1710 static void
1711 oce_rx(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
1712 {
1713         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1714         int len;
1715         struct mbuf *m = NULL;
1716         struct oce_common_cqe_info cq_info;
1717         uint16_t vtag = 0;
1718
1719         /* Is it a flush compl that has no data */
1720         if(!cqe->u0.s.num_fragments)
1721                 goto exit;
1722
1723         len = cqe->u0.s.pkt_size;
1724         if (!len) {
1725                 /*partial DMA workaround for Lancer*/
1726                 oce_discard_rx_comp(rq, cqe->u0.s.num_fragments);
1727                 goto exit;
1728         }
1729
1730         if (!oce_cqe_portid_valid(sc, cqe)) {
1731                 oce_discard_rx_comp(rq, cqe->u0.s.num_fragments);
1732                 goto exit;
1733         }
1734
1735          /* Get vlan_tag value */
1736         if(IS_BE(sc) || IS_SH(sc))
1737                 vtag = BSWAP_16(cqe->u0.s.vlan_tag);
1738         else
1739                 vtag = cqe->u0.s.vlan_tag;
1740         
1741         cq_info.l4_cksum_pass = cqe->u0.s.l4_cksum_pass;
1742         cq_info.ip_cksum_pass = cqe->u0.s.ip_cksum_pass;
1743         cq_info.ipv6_frame = cqe->u0.s.ip_ver;
1744         cq_info.num_frags = cqe->u0.s.num_fragments;
1745         cq_info.pkt_size = cqe->u0.s.pkt_size;
1746
1747         oce_rx_mbuf_chain(rq, &cq_info, &m);
1748
1749         if (m) {
1750                 m->m_pkthdr.rcvif = sc->ifp;
1751 #if __FreeBSD_version >= 800000
1752                 if (rq->queue_index)
1753                         m->m_pkthdr.flowid = (rq->queue_index - 1);
1754                 else
1755                         m->m_pkthdr.flowid = rq->queue_index;
1756                 M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
1757 #endif
1758                 /* This deternies if vlan tag is Valid */
1759                 if (oce_cqe_vtp_valid(sc, cqe)) { 
1760                         if (sc->function_mode & FNM_FLEX10_MODE) {
1761                                 /* FLEX10. If QnQ is not set, neglect VLAN */
1762                                 if (cqe->u0.s.qnq) {
1763                                         m->m_pkthdr.ether_vtag = vtag;
1764                                         m->m_flags |= M_VLANTAG;
1765                                 }
1766                         } else if (sc->pvid != (vtag & VLAN_VID_MASK))  {
1767                                 /* In UMC mode generally pvid will be striped by
1768                                    hw. But in some cases we have seen it comes
1769                                    with pvid. So if pvid == vlan, neglect vlan.
1770                                 */
1771                                 m->m_pkthdr.ether_vtag = vtag;
1772                                 m->m_flags |= M_VLANTAG;
1773                         }
1774                 }
1775
1776                 if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
1777 #if defined(INET6) || defined(INET)
1778                 /* Try to queue to LRO */
1779                 if (IF_LRO_ENABLED(sc) &&
1780                     (cqe->u0.s.ip_cksum_pass) &&
1781                     (cqe->u0.s.l4_cksum_pass) &&
1782                     (!cqe->u0.s.ip_ver)       &&
1783                     (rq->lro.lro_cnt != 0)) {
1784
1785                         if (tcp_lro_rx(&rq->lro, m, 0) == 0) {
1786                                 rq->lro_pkts_queued ++;         
1787                                 goto post_done;
1788                         }
1789                         /* If LRO posting fails then try to post to STACK */
1790                 }
1791 #endif
1792         
1793                 (*sc->ifp->if_input) (sc->ifp, m);
1794 #if defined(INET6) || defined(INET)
1795 post_done:
1796 #endif
1797                 /* Update rx stats per queue */
1798                 rq->rx_stats.rx_pkts++;
1799                 rq->rx_stats.rx_bytes += cqe->u0.s.pkt_size;
1800                 rq->rx_stats.rx_frags += cqe->u0.s.num_fragments;
1801                 if (cqe->u0.s.pkt_type == OCE_MULTICAST_PACKET)
1802                         rq->rx_stats.rx_mcast_pkts++;
1803                 if (cqe->u0.s.pkt_type == OCE_UNICAST_PACKET)
1804                         rq->rx_stats.rx_ucast_pkts++;
1805         }
1806 exit:
1807         return;
1808 }
1809
1810
1811 void
1812 oce_discard_rx_comp(struct oce_rq *rq, int num_frags)
1813 {
1814         uint32_t i = 0;
1815         struct oce_packet_desc *pd;
1816         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1817
1818         for (i = 0; i < num_frags; i++) {
1819                 if (rq->ring->cidx == rq->ring->pidx) {
1820                         device_printf(sc->dev,
1821                                 "oce_discard_rx_comp: Invalid RX completion - Queue is empty\n");
1822                         return;
1823                 }
1824                 pd = &rq->pckts[rq->ring->cidx];
1825                 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1826                 bus_dmamap_unload(rq->tag, pd->map);
1827                 if (pd->mbuf != NULL) {
1828                         m_freem(pd->mbuf);
1829                         pd->mbuf = NULL;
1830                 }
1831
1832                 RING_GET(rq->ring, 1);
1833                 rq->pending--;
1834         }
1835 }
1836
1837
1838 static int
1839 oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
1840 {
1841         struct oce_nic_rx_cqe_v1 *cqe_v1;
1842         int vtp = 0;
1843
1844         if (sc->be3_native) {
1845                 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1846                 vtp =  cqe_v1->u0.s.vlan_tag_present; 
1847         } else
1848                 vtp = cqe->u0.s.vlan_tag_present;
1849         
1850         return vtp;
1851
1852 }
1853
1854
1855 static int
1856 oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
1857 {
1858         struct oce_nic_rx_cqe_v1 *cqe_v1;
1859         int port_id = 0;
1860
1861         if (sc->be3_native && (IS_BE(sc) || IS_SH(sc))) {
1862                 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1863                 port_id =  cqe_v1->u0.s.port;
1864                 if (sc->port_id != port_id)
1865                         return 0;
1866         } else
1867                 ;/* For BE3 legacy and Lancer this is dummy */
1868         
1869         return 1;
1870
1871 }
1872
1873 #if defined(INET6) || defined(INET)
1874 void
1875 oce_rx_flush_lro(struct oce_rq *rq)
1876 {
1877         struct lro_ctrl *lro = &rq->lro;
1878         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1879
1880         if (!IF_LRO_ENABLED(sc))
1881                 return;
1882
1883         tcp_lro_flush_all(lro);
1884         rq->lro_pkts_queued = 0;
1885         
1886         return;
1887 }
1888
1889
1890 static int
1891 oce_init_lro(POCE_SOFTC sc)
1892 {
1893         struct lro_ctrl *lro = NULL;
1894         int i = 0, rc = 0;
1895
1896         for (i = 0; i < sc->nrqs; i++) { 
1897                 lro = &sc->rq[i]->lro;
1898                 rc = tcp_lro_init(lro);
1899                 if (rc != 0) {
1900                         device_printf(sc->dev, "LRO init failed\n");
1901                         return rc;              
1902                 }
1903                 lro->ifp = sc->ifp;
1904         }
1905
1906         return rc;              
1907 }
1908
1909
1910 void
1911 oce_free_lro(POCE_SOFTC sc)
1912 {
1913         struct lro_ctrl *lro = NULL;
1914         int i = 0;
1915
1916         for (i = 0; i < sc->nrqs; i++) {
1917                 lro = &sc->rq[i]->lro;
1918                 if (lro)
1919                         tcp_lro_free(lro);
1920         }
1921 }
1922 #endif
1923
1924 int
1925 oce_alloc_rx_bufs(struct oce_rq *rq, int count)
1926 {
1927         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1928         int i, in, rc;
1929         struct oce_packet_desc *pd;
1930         bus_dma_segment_t segs[6];
1931         int nsegs, added = 0;
1932         struct oce_nic_rqe *rqe;
1933         pd_rxulp_db_t rxdb_reg;
1934         uint32_t val = 0;
1935         uint32_t oce_max_rq_posts = 64;
1936
1937         bzero(&rxdb_reg, sizeof(pd_rxulp_db_t));
1938         for (i = 0; i < count; i++) {
1939                 in = (rq->ring->pidx + 1) % OCE_RQ_PACKET_ARRAY_SIZE;
1940
1941                 pd = &rq->pckts[rq->ring->pidx];
1942                 pd->mbuf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, oce_rq_buf_size);
1943                 if (pd->mbuf == NULL) {
1944                         device_printf(sc->dev, "mbuf allocation failed, size = %d\n",oce_rq_buf_size);
1945                         break;
1946                 }
1947                 pd->mbuf->m_nextpkt = NULL;
1948
1949                 pd->mbuf->m_len = pd->mbuf->m_pkthdr.len = rq->cfg.frag_size;
1950
1951                 rc = bus_dmamap_load_mbuf_sg(rq->tag,
1952                                              pd->map,
1953                                              pd->mbuf,
1954                                              segs, &nsegs, BUS_DMA_NOWAIT);
1955                 if (rc) {
1956                         m_free(pd->mbuf);
1957                         device_printf(sc->dev, "bus_dmamap_load_mbuf_sg failed rc = %d\n", rc);
1958                         break;
1959                 }
1960
1961                 if (nsegs != 1) {
1962                         i--;
1963                         continue;
1964                 }
1965
1966                 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_PREREAD);
1967
1968                 rqe = RING_GET_PRODUCER_ITEM_VA(rq->ring, struct oce_nic_rqe);
1969                 rqe->u0.s.frag_pa_hi = ADDR_HI(segs[0].ds_addr);
1970                 rqe->u0.s.frag_pa_lo = ADDR_LO(segs[0].ds_addr);
1971                 DW_SWAP(u32ptr(rqe), sizeof(struct oce_nic_rqe));
1972                 RING_PUT(rq->ring, 1);
1973                 added++;
1974                 rq->pending++;
1975         }
1976         oce_max_rq_posts = sc->enable_hwlro ? OCE_HWLRO_MAX_RQ_POSTS : OCE_MAX_RQ_POSTS;
1977         if (added != 0) {
1978                 for (i = added / oce_max_rq_posts; i > 0; i--) {
1979                         rxdb_reg.bits.num_posted = oce_max_rq_posts;
1980                         rxdb_reg.bits.qid = rq->rq_id;
1981                         if(rq->islro) {
1982                                 val |= rq->rq_id & DB_LRO_RQ_ID_MASK;
1983                                 val |= oce_max_rq_posts << 16;
1984                                 OCE_WRITE_REG32(sc, db, DB_OFFSET, val);
1985                         }else {
1986                                 OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
1987                         }
1988                         added -= oce_max_rq_posts;
1989                 }
1990                 if (added > 0) {
1991                         rxdb_reg.bits.qid = rq->rq_id;
1992                         rxdb_reg.bits.num_posted = added;
1993                         if(rq->islro) {
1994                                 val |= rq->rq_id & DB_LRO_RQ_ID_MASK;
1995                                 val |= added << 16;
1996                                 OCE_WRITE_REG32(sc, db, DB_OFFSET, val);
1997                         }else {
1998                                 OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
1999                         }
2000                 }
2001         }
2002         
2003         return 0;       
2004 }
2005
2006 static void
2007 oce_check_rx_bufs(POCE_SOFTC sc, uint32_t num_cqes, struct oce_rq *rq)
2008 {
2009         if (num_cqes) {
2010                 oce_arm_cq(sc, rq->cq->cq_id, num_cqes, FALSE);
2011                 if(!sc->enable_hwlro) {
2012                         if((OCE_RQ_PACKET_ARRAY_SIZE - rq->pending) > 1)
2013                                 oce_alloc_rx_bufs(rq, ((OCE_RQ_PACKET_ARRAY_SIZE - rq->pending) - 1));
2014                 }else {
2015                         if ((OCE_RQ_PACKET_ARRAY_SIZE -1 - rq->pending) > 64)
2016                                 oce_alloc_rx_bufs(rq, 64);
2017                 }
2018         }
2019
2020         return;
2021 }
2022
2023 uint16_t
2024 oce_rq_handler_lro(void *arg)
2025 {
2026         struct oce_rq *rq = (struct oce_rq *)arg;
2027         struct oce_cq *cq = rq->cq;
2028         POCE_SOFTC sc = rq->parent;
2029         struct nic_hwlro_singleton_cqe *cqe;
2030         struct nic_hwlro_cqe_part2 *cqe2;
2031         int num_cqes = 0;
2032
2033         LOCK(&rq->rx_lock);
2034         bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2035         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe);
2036         while (cqe->valid) {
2037                 if(cqe->cqe_type == 0) { /* singleton cqe */
2038                         /* we should not get singleton cqe after cqe1 on same rq */
2039                         if(rq->cqe_firstpart != NULL) {
2040                                 device_printf(sc->dev, "Got singleton cqe after cqe1 \n");
2041                                 goto exit_rq_handler_lro;
2042                         }                                                       
2043                         if(cqe->error != 0) {
2044                                 rq->rx_stats.rxcp_err++;
2045                                 if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
2046                         }
2047                         oce_rx_lro(rq, cqe, NULL);
2048                         rq->rx_stats.rx_compl++;
2049                         cqe->valid = 0;
2050                         RING_GET(cq->ring, 1);
2051                         num_cqes++;
2052                         if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
2053                                 break;
2054                 }else if(cqe->cqe_type == 0x1) { /* first part */
2055                         /* we should not get cqe1 after cqe1 on same rq */
2056                         if(rq->cqe_firstpart != NULL) {
2057                                 device_printf(sc->dev, "Got cqe1 after cqe1 \n");
2058                                 goto exit_rq_handler_lro;
2059                         }
2060                         rq->cqe_firstpart = (struct nic_hwlro_cqe_part1 *)cqe;
2061                         RING_GET(cq->ring, 1);
2062                 }else if(cqe->cqe_type == 0x2) { /* second part */
2063                         cqe2 = (struct nic_hwlro_cqe_part2 *)cqe;
2064                         if(cqe2->error != 0) {
2065                                 rq->rx_stats.rxcp_err++;
2066                                 if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
2067                         }
2068                         /* We should not get cqe2 without cqe1 */
2069                         if(rq->cqe_firstpart == NULL) {
2070                                 device_printf(sc->dev, "Got cqe2 without cqe1 \n");
2071                                 goto exit_rq_handler_lro;
2072                         }
2073                         oce_rx_lro(rq, (struct nic_hwlro_singleton_cqe *)rq->cqe_firstpart, cqe2);
2074
2075                         rq->rx_stats.rx_compl++;
2076                         rq->cqe_firstpart->valid = 0;
2077                         cqe2->valid = 0;
2078                         rq->cqe_firstpart = NULL;
2079
2080                         RING_GET(cq->ring, 1);
2081                         num_cqes += 2;
2082                         if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
2083                                 break;
2084                 }
2085
2086                 bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2087                 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe);
2088         }
2089         oce_check_rx_bufs(sc, num_cqes, rq);
2090 exit_rq_handler_lro:
2091         UNLOCK(&rq->rx_lock);
2092         return 0;
2093 }
2094
2095 /* Handle the Completion Queue for receive */
2096 uint16_t
2097 oce_rq_handler(void *arg)
2098 {
2099         struct oce_rq *rq = (struct oce_rq *)arg;
2100         struct oce_cq *cq = rq->cq;
2101         POCE_SOFTC sc = rq->parent;
2102         struct oce_nic_rx_cqe *cqe;
2103         int num_cqes = 0;
2104
2105         if(rq->islro) {
2106                 oce_rq_handler_lro(arg);
2107                 return 0;
2108         }
2109         LOCK(&rq->rx_lock);
2110         bus_dmamap_sync(cq->ring->dma.tag,
2111                         cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2112         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
2113         while (cqe->u0.dw[2]) {
2114                 DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe));
2115
2116                 if (cqe->u0.s.error == 0) {
2117                         oce_rx(rq, cqe);
2118                 } else {
2119                         rq->rx_stats.rxcp_err++;
2120                         if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
2121                         /* Post L3/L4 errors to stack.*/
2122                         oce_rx(rq, cqe);
2123                 }
2124                 rq->rx_stats.rx_compl++;
2125                 cqe->u0.dw[2] = 0;
2126
2127 #if defined(INET6) || defined(INET)
2128                 if (IF_LRO_ENABLED(sc) && rq->lro_pkts_queued >= 16) {
2129                         oce_rx_flush_lro(rq);
2130                 }
2131 #endif
2132
2133                 RING_GET(cq->ring, 1);
2134                 bus_dmamap_sync(cq->ring->dma.tag,
2135                                 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2136                 cqe =
2137                     RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
2138                 num_cqes++;
2139                 if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
2140                         break;
2141         }
2142
2143 #if defined(INET6) || defined(INET)
2144         if (IF_LRO_ENABLED(sc))
2145                 oce_rx_flush_lro(rq);
2146 #endif
2147
2148         oce_check_rx_bufs(sc, num_cqes, rq);
2149         UNLOCK(&rq->rx_lock);
2150         return 0;
2151
2152 }
2153
2154
2155
2156
2157 /*****************************************************************************
2158  *                 Helper function prototypes in this file                   *
2159  *****************************************************************************/
2160
2161 static int 
2162 oce_attach_ifp(POCE_SOFTC sc)
2163 {
2164
2165         sc->ifp = if_alloc(IFT_ETHER);
2166         if (!sc->ifp)
2167                 return ENOMEM;
2168
2169         ifmedia_init(&sc->media, IFM_IMASK, oce_media_change, oce_media_status);
2170         ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
2171         ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
2172
2173         sc->ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
2174         sc->ifp->if_ioctl = oce_ioctl;
2175         sc->ifp->if_start = oce_start;
2176         sc->ifp->if_init = oce_init;
2177         sc->ifp->if_mtu = ETHERMTU;
2178         sc->ifp->if_softc = sc;
2179 #if __FreeBSD_version >= 800000
2180         sc->ifp->if_transmit = oce_multiq_start;
2181         sc->ifp->if_qflush = oce_multiq_flush;
2182 #endif
2183
2184         if_initname(sc->ifp,
2185                     device_get_name(sc->dev), device_get_unit(sc->dev));
2186
2187         sc->ifp->if_snd.ifq_drv_maxlen = OCE_MAX_TX_DESC - 1;
2188         IFQ_SET_MAXLEN(&sc->ifp->if_snd, sc->ifp->if_snd.ifq_drv_maxlen);
2189         IFQ_SET_READY(&sc->ifp->if_snd);
2190
2191         sc->ifp->if_hwassist = OCE_IF_HWASSIST;
2192         sc->ifp->if_hwassist |= CSUM_TSO;
2193         sc->ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP);
2194
2195         sc->ifp->if_capabilities = OCE_IF_CAPABILITIES;
2196         sc->ifp->if_capabilities |= IFCAP_HWCSUM;
2197         sc->ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
2198
2199 #if defined(INET6) || defined(INET)
2200         sc->ifp->if_capabilities |= IFCAP_TSO;
2201         sc->ifp->if_capabilities |= IFCAP_LRO;
2202         sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
2203 #endif
2204         
2205         sc->ifp->if_capenable = sc->ifp->if_capabilities;
2206         sc->ifp->if_baudrate = IF_Gbps(10);
2207
2208 #if __FreeBSD_version >= 1000000
2209         sc->ifp->if_hw_tsomax = 65536 - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
2210         sc->ifp->if_hw_tsomaxsegcount = OCE_MAX_TX_ELEMENTS;
2211         sc->ifp->if_hw_tsomaxsegsize = 4096;
2212 #endif
2213
2214         ether_ifattach(sc->ifp, sc->macaddr.mac_addr);
2215         
2216         return 0;
2217 }
2218
2219
2220 static void
2221 oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
2222 {
2223         POCE_SOFTC sc = ifp->if_softc;
2224
2225         if (ifp->if_softc !=  arg)
2226                 return;
2227         if ((vtag == 0) || (vtag > 4095))
2228                 return;
2229
2230         sc->vlan_tag[vtag] = 1;
2231         sc->vlans_added++;
2232         if (sc->vlans_added <= (sc->max_vlans + 1))
2233                 oce_vid_config(sc);
2234 }
2235
2236
2237 static void
2238 oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
2239 {
2240         POCE_SOFTC sc = ifp->if_softc;
2241
2242         if (ifp->if_softc !=  arg)
2243                 return;
2244         if ((vtag == 0) || (vtag > 4095))
2245                 return;
2246
2247         sc->vlan_tag[vtag] = 0;
2248         sc->vlans_added--;
2249         oce_vid_config(sc);
2250 }
2251
2252
2253 /*
2254  * A max of 64 vlans can be configured in BE. If the user configures
2255  * more, place the card in vlan promiscuous mode.
2256  */
2257 static int
2258 oce_vid_config(POCE_SOFTC sc)
2259 {
2260         struct normal_vlan vtags[MAX_VLANFILTER_SIZE];
2261         uint16_t ntags = 0, i;
2262         int status = 0;
2263
2264         if ((sc->vlans_added <= MAX_VLANFILTER_SIZE) && 
2265                         (sc->ifp->if_capenable & IFCAP_VLAN_HWFILTER)) {
2266                 for (i = 0; i < MAX_VLANS; i++) {
2267                         if (sc->vlan_tag[i]) {
2268                                 vtags[ntags].vtag = i;
2269                                 ntags++;
2270                         }
2271                 }
2272                 if (ntags)
2273                         status = oce_config_vlan(sc, (uint8_t) sc->if_id,
2274                                                 vtags, ntags, 1, 0); 
2275         } else 
2276                 status = oce_config_vlan(sc, (uint8_t) sc->if_id,
2277                                                 NULL, 0, 1, 1);
2278         return status;
2279 }
2280
2281
2282 static void
2283 oce_mac_addr_set(POCE_SOFTC sc)
2284 {
2285         uint32_t old_pmac_id = sc->pmac_id;
2286         int status = 0;
2287
2288         
2289         status = bcmp((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
2290                          sc->macaddr.size_of_struct);
2291         if (!status)
2292                 return;
2293
2294         status = oce_mbox_macaddr_add(sc, (uint8_t *)(IF_LLADDR(sc->ifp)),
2295                                         sc->if_id, &sc->pmac_id);
2296         if (!status) {
2297                 status = oce_mbox_macaddr_del(sc, sc->if_id, old_pmac_id);
2298                 bcopy((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
2299                                  sc->macaddr.size_of_struct); 
2300         }
2301         if (status)
2302                 device_printf(sc->dev, "Failed update macaddress\n");
2303
2304 }
2305
2306
2307 static int
2308 oce_handle_passthrough(struct ifnet *ifp, caddr_t data)
2309 {
2310         POCE_SOFTC sc = ifp->if_softc;
2311         struct ifreq *ifr = (struct ifreq *)data;
2312         int rc = ENXIO;
2313         char cookie[32] = {0};
2314         void *priv_data = ifr_data_get_ptr(ifr);
2315         void *ioctl_ptr;
2316         uint32_t req_size;
2317         struct mbx_hdr req;
2318         OCE_DMA_MEM dma_mem;
2319         struct mbx_common_get_cntl_attr *fw_cmd;
2320
2321         if (copyin(priv_data, cookie, strlen(IOCTL_COOKIE)))
2322                 return EFAULT;
2323
2324         if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE)))
2325                 return EINVAL;
2326
2327         ioctl_ptr = (char *)priv_data + strlen(IOCTL_COOKIE);
2328         if (copyin(ioctl_ptr, &req, sizeof(struct mbx_hdr)))
2329                 return EFAULT;
2330
2331         req_size = le32toh(req.u0.req.request_length);
2332         if (req_size > 65536)
2333                 return EINVAL;
2334
2335         req_size += sizeof(struct mbx_hdr);
2336         rc = oce_dma_alloc(sc, req_size, &dma_mem, 0);
2337         if (rc)
2338                 return ENOMEM;
2339
2340         if (copyin(ioctl_ptr, OCE_DMAPTR(&dma_mem,char), req_size)) {
2341                 rc = EFAULT;
2342                 goto dma_free;
2343         }
2344
2345         rc = oce_pass_through_mbox(sc, &dma_mem, req_size);
2346         if (rc) {
2347                 rc = EIO;
2348                 goto dma_free;
2349         }
2350
2351         if (copyout(OCE_DMAPTR(&dma_mem,char), ioctl_ptr, req_size))
2352                 rc =  EFAULT;
2353
2354         /* 
2355            firmware is filling all the attributes for this ioctl except
2356            the driver version..so fill it 
2357          */
2358         if(req.u0.rsp.opcode == OPCODE_COMMON_GET_CNTL_ATTRIBUTES) {
2359                 fw_cmd = (struct mbx_common_get_cntl_attr *) ioctl_ptr;
2360                 strncpy(fw_cmd->params.rsp.cntl_attr_info.hba_attr.drv_ver_str,
2361                         COMPONENT_REVISION, strlen(COMPONENT_REVISION));        
2362         }
2363
2364 dma_free:
2365         oce_dma_free(sc, &dma_mem);
2366         return rc;
2367
2368 }
2369
2370 static void
2371 oce_eqd_set_periodic(POCE_SOFTC sc)
2372 {
2373         struct oce_set_eqd set_eqd[OCE_MAX_EQ];
2374         struct oce_aic_obj *aic;
2375         struct oce_eq *eqo;
2376         uint64_t now = 0, delta;
2377         int eqd, i, num = 0;
2378         uint32_t tx_reqs = 0, rxpkts = 0, pps;
2379         struct oce_wq *wq;
2380         struct oce_rq *rq;
2381
2382         #define ticks_to_msecs(t)       (1000 * (t) / hz)
2383
2384         for (i = 0 ; i < sc->neqs; i++) {
2385                 eqo = sc->eq[i];
2386                 aic = &sc->aic_obj[i];
2387                 /* When setting the static eq delay from the user space */
2388                 if (!aic->enable) {
2389                         if (aic->ticks)
2390                                 aic->ticks = 0;
2391                         eqd = aic->et_eqd;
2392                         goto modify_eqd;
2393                 }
2394
2395                 rq = sc->rq[i];
2396                 rxpkts = rq->rx_stats.rx_pkts;
2397                 wq = sc->wq[i];
2398                 tx_reqs = wq->tx_stats.tx_reqs;
2399                 now = ticks;
2400
2401                 if (!aic->ticks || now < aic->ticks ||
2402                     rxpkts < aic->prev_rxpkts || tx_reqs < aic->prev_txreqs) {
2403                         aic->prev_rxpkts = rxpkts;
2404                         aic->prev_txreqs = tx_reqs;
2405                         aic->ticks = now;
2406                         continue;
2407                 }
2408
2409                 delta = ticks_to_msecs(now - aic->ticks);
2410
2411                 pps = (((uint32_t)(rxpkts - aic->prev_rxpkts) * 1000) / delta) +
2412                       (((uint32_t)(tx_reqs - aic->prev_txreqs) * 1000) / delta);
2413                 eqd = (pps / 15000) << 2;
2414                 if (eqd < 8)
2415                         eqd = 0;
2416
2417                 /* Make sure that the eq delay is in the known range */
2418                 eqd = min(eqd, aic->max_eqd);
2419                 eqd = max(eqd, aic->min_eqd);
2420
2421                 aic->prev_rxpkts = rxpkts;
2422                 aic->prev_txreqs = tx_reqs;
2423                 aic->ticks = now;
2424
2425 modify_eqd:
2426                 if (eqd != aic->cur_eqd) {
2427                         set_eqd[num].delay_multiplier = (eqd * 65)/100;
2428                         set_eqd[num].eq_id = eqo->eq_id;
2429                         aic->cur_eqd = eqd;
2430                         num++;
2431                 }
2432         }
2433
2434         /* Is there atleast one eq that needs to be modified? */
2435         for(i = 0; i < num; i += 8) {
2436                 if((num - i) >=8 )
2437                         oce_mbox_eqd_modify_periodic(sc, &set_eqd[i], 8);
2438                 else
2439                         oce_mbox_eqd_modify_periodic(sc, &set_eqd[i], (num - i));
2440         }
2441
2442 }
2443
2444 static void oce_detect_hw_error(POCE_SOFTC sc)
2445 {
2446
2447         uint32_t ue_low = 0, ue_high = 0, ue_low_mask = 0, ue_high_mask = 0;
2448         uint32_t sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
2449         uint32_t i;
2450
2451         if (sc->hw_error)
2452                 return;
2453
2454         if (IS_XE201(sc)) {
2455                 sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET);
2456                 if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2457                         sliport_err1 = OCE_READ_REG32(sc, db, SLIPORT_ERROR1_OFFSET);
2458                         sliport_err2 = OCE_READ_REG32(sc, db, SLIPORT_ERROR2_OFFSET);
2459                 }
2460         } else {
2461                 ue_low = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW);
2462                 ue_high = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HIGH);
2463                 ue_low_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW_MASK);
2464                 ue_high_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HI_MASK);
2465
2466                 ue_low = (ue_low & ~ue_low_mask);
2467                 ue_high = (ue_high & ~ue_high_mask);
2468         }
2469
2470         /* On certain platforms BE hardware can indicate spurious UEs.
2471          * Allow the h/w to stop working completely in case of a real UE.
2472          * Hence not setting the hw_error for UE detection.
2473          */
2474         if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2475                 sc->hw_error = TRUE;
2476                 device_printf(sc->dev, "Error detected in the card\n");
2477         }
2478
2479         if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2480                 device_printf(sc->dev,
2481                                 "ERR: sliport status 0x%x\n", sliport_status);
2482                 device_printf(sc->dev,
2483                                 "ERR: sliport error1 0x%x\n", sliport_err1);
2484                 device_printf(sc->dev,
2485                                 "ERR: sliport error2 0x%x\n", sliport_err2);
2486         }
2487
2488         if (ue_low) {
2489                 for (i = 0; ue_low; ue_low >>= 1, i++) {
2490                         if (ue_low & 1)
2491                                 device_printf(sc->dev, "UE: %s bit set\n",
2492                                                         ue_status_low_desc[i]);
2493                 }
2494         }
2495
2496         if (ue_high) {
2497                 for (i = 0; ue_high; ue_high >>= 1, i++) {
2498                         if (ue_high & 1)
2499                                 device_printf(sc->dev, "UE: %s bit set\n",
2500                                                         ue_status_hi_desc[i]);
2501                 }
2502         }
2503
2504 }
2505
2506
2507 static void
2508 oce_local_timer(void *arg)
2509 {
2510         POCE_SOFTC sc = arg;
2511         int i = 0;
2512         
2513         oce_detect_hw_error(sc);
2514         oce_refresh_nic_stats(sc);
2515         oce_refresh_queue_stats(sc);
2516         oce_mac_addr_set(sc);
2517         
2518         /* TX Watch Dog*/
2519         for (i = 0; i < sc->nwqs; i++)
2520                 oce_tx_restart(sc, sc->wq[i]);
2521         
2522         /* calculate and set the eq delay for optimal interrupt rate */
2523         if (IS_BE(sc) || IS_SH(sc))
2524                 oce_eqd_set_periodic(sc);
2525
2526         callout_reset(&sc->timer, hz, oce_local_timer, sc);
2527 }
2528
2529 static void 
2530 oce_tx_compl_clean(POCE_SOFTC sc) 
2531 {
2532         struct oce_wq *wq;
2533         int i = 0, timeo = 0, num_wqes = 0;
2534         int pending_txqs = sc->nwqs;
2535
2536         /* Stop polling for compls when HW has been silent for 10ms or 
2537          * hw_error or no outstanding completions expected
2538          */
2539         do {
2540                 pending_txqs = sc->nwqs;
2541                 
2542                 for_all_wq_queues(sc, wq, i) {
2543                         num_wqes = oce_wq_handler(wq);
2544                         
2545                         if(num_wqes)
2546                                 timeo = 0;
2547
2548                         if(!wq->ring->num_used)
2549                                 pending_txqs--;
2550                 }
2551
2552                 if (pending_txqs == 0 || ++timeo > 10 || sc->hw_error)
2553                         break;
2554
2555                 DELAY(1000);
2556         } while (TRUE);
2557
2558         for_all_wq_queues(sc, wq, i) {
2559                 while(wq->ring->num_used) {
2560                         LOCK(&wq->tx_compl_lock);
2561                         oce_process_tx_completion(wq);
2562                         UNLOCK(&wq->tx_compl_lock);
2563                 }
2564         }       
2565                 
2566 }
2567
2568 /* NOTE : This should only be called holding
2569  *        DEVICE_LOCK.
2570  */
2571 static void
2572 oce_if_deactivate(POCE_SOFTC sc)
2573 {
2574         int i;
2575         struct oce_rq *rq;
2576         struct oce_wq *wq;
2577         struct oce_eq *eq;
2578
2579         sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
2580
2581         oce_tx_compl_clean(sc);
2582
2583         /* Stop intrs and finish any bottom halves pending */
2584         oce_hw_intr_disable(sc);
2585
2586         /* Since taskqueue_drain takes a Gaint Lock, We should not acquire
2587            any other lock. So unlock device lock and require after
2588            completing taskqueue_drain.
2589         */
2590         UNLOCK(&sc->dev_lock);
2591         for (i = 0; i < sc->intr_count; i++) {
2592                 if (sc->intrs[i].tq != NULL) {
2593                         taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task);
2594                 }
2595         }
2596         LOCK(&sc->dev_lock);
2597
2598         /* Delete RX queue in card with flush param */
2599         oce_stop_rx(sc);
2600
2601         /* Invalidate any pending cq and eq entries*/   
2602         for_all_evnt_queues(sc, eq, i)  
2603                 oce_drain_eq(eq);
2604         for_all_rq_queues(sc, rq, i)
2605                 oce_drain_rq_cq(rq);
2606         for_all_wq_queues(sc, wq, i)
2607                 oce_drain_wq_cq(wq);
2608
2609         /* But still we need to get MCC aync events.
2610            So enable intrs and also arm first EQ
2611         */
2612         oce_hw_intr_enable(sc);
2613         oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
2614
2615         DELAY(10);
2616 }
2617
2618
2619 static void
2620 oce_if_activate(POCE_SOFTC sc)
2621 {
2622         struct oce_eq *eq;
2623         struct oce_rq *rq;
2624         struct oce_wq *wq;
2625         int i, rc = 0;
2626
2627         sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; 
2628         
2629         oce_hw_intr_disable(sc);
2630         
2631         oce_start_rx(sc);
2632
2633         for_all_rq_queues(sc, rq, i) {
2634                 rc = oce_start_rq(rq);
2635                 if (rc)
2636                         device_printf(sc->dev, "Unable to start RX\n");
2637         }
2638
2639         for_all_wq_queues(sc, wq, i) {
2640                 rc = oce_start_wq(wq);
2641                 if (rc)
2642                         device_printf(sc->dev, "Unable to start TX\n");
2643         }
2644
2645         
2646         for_all_evnt_queues(sc, eq, i)
2647                 oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
2648
2649         oce_hw_intr_enable(sc);
2650
2651 }
2652
2653 static void
2654 process_link_state(POCE_SOFTC sc, struct oce_async_cqe_link_state *acqe)
2655 {
2656         /* Update Link status */
2657         if ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) ==
2658              ASYNC_EVENT_LINK_UP) {
2659                 sc->link_status = ASYNC_EVENT_LINK_UP;
2660                 if_link_state_change(sc->ifp, LINK_STATE_UP);
2661         } else {
2662                 sc->link_status = ASYNC_EVENT_LINK_DOWN;
2663                 if_link_state_change(sc->ifp, LINK_STATE_DOWN);
2664         }
2665 }
2666
2667
2668 static void oce_async_grp5_osbmc_process(POCE_SOFTC sc,
2669                                          struct oce_async_evt_grp5_os2bmc *evt)
2670 {
2671         DW_SWAP(evt, sizeof(struct oce_async_evt_grp5_os2bmc));
2672         if (evt->u.s.mgmt_enable)
2673                 sc->flags |= OCE_FLAGS_OS2BMC;
2674         else
2675                 return;
2676
2677         sc->bmc_filt_mask = evt->u.s.arp_filter;
2678         sc->bmc_filt_mask |= (evt->u.s.dhcp_client_filt << 1);
2679         sc->bmc_filt_mask |= (evt->u.s.dhcp_server_filt << 2);
2680         sc->bmc_filt_mask |= (evt->u.s.net_bios_filt << 3);
2681         sc->bmc_filt_mask |= (evt->u.s.bcast_filt << 4);
2682         sc->bmc_filt_mask |= (evt->u.s.ipv6_nbr_filt << 5);
2683         sc->bmc_filt_mask |= (evt->u.s.ipv6_ra_filt << 6);
2684         sc->bmc_filt_mask |= (evt->u.s.ipv6_ras_filt << 7);
2685         sc->bmc_filt_mask |= (evt->u.s.mcast_filt << 8);
2686 }
2687
2688
2689 static void oce_process_grp5_events(POCE_SOFTC sc, struct oce_mq_cqe *cqe)
2690 {
2691         struct oce_async_event_grp5_pvid_state *gcqe;
2692         struct oce_async_evt_grp5_os2bmc *bmccqe;
2693
2694         switch (cqe->u0.s.async_type) {
2695         case ASYNC_EVENT_PVID_STATE:
2696                 /* GRP5 PVID */
2697                 gcqe = (struct oce_async_event_grp5_pvid_state *)cqe;
2698                 if (gcqe->enabled)
2699                         sc->pvid = gcqe->tag & VLAN_VID_MASK;
2700                 else
2701                         sc->pvid = 0;
2702                 break;
2703         case ASYNC_EVENT_OS2BMC:
2704                 bmccqe = (struct oce_async_evt_grp5_os2bmc *)cqe;
2705                 oce_async_grp5_osbmc_process(sc, bmccqe);
2706                 break;
2707         default:
2708                 break;
2709         }
2710 }
2711
2712 /* Handle the Completion Queue for the Mailbox/Async notifications */
2713 uint16_t
2714 oce_mq_handler(void *arg)
2715 {
2716         struct oce_mq *mq = (struct oce_mq *)arg;
2717         POCE_SOFTC sc = mq->parent;
2718         struct oce_cq *cq = mq->cq;
2719         int num_cqes = 0, evt_type = 0, optype = 0;
2720         struct oce_mq_cqe *cqe;
2721         struct oce_async_cqe_link_state *acqe;
2722         struct oce_async_event_qnq *dbgcqe;
2723
2724
2725         bus_dmamap_sync(cq->ring->dma.tag,
2726                         cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2727         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
2728
2729         while (cqe->u0.dw[3]) {
2730                 DW_SWAP((uint32_t *) cqe, sizeof(oce_mq_cqe));
2731                 if (cqe->u0.s.async_event) {
2732                         evt_type = cqe->u0.s.event_type;
2733                         optype = cqe->u0.s.async_type;
2734                         if (evt_type  == ASYNC_EVENT_CODE_LINK_STATE) {
2735                                 /* Link status evt */
2736                                 acqe = (struct oce_async_cqe_link_state *)cqe;
2737                                 process_link_state(sc, acqe);
2738                         } else if (evt_type == ASYNC_EVENT_GRP5) {
2739                                 oce_process_grp5_events(sc, cqe);
2740                         } else if (evt_type == ASYNC_EVENT_CODE_DEBUG &&
2741                                         optype == ASYNC_EVENT_DEBUG_QNQ) {
2742                                 dbgcqe =  (struct oce_async_event_qnq *)cqe;
2743                                 if(dbgcqe->valid)
2744                                         sc->qnqid = dbgcqe->vlan_tag;
2745                                 sc->qnq_debug_event = TRUE;
2746                         }
2747                 }
2748                 cqe->u0.dw[3] = 0;
2749                 RING_GET(cq->ring, 1);
2750                 bus_dmamap_sync(cq->ring->dma.tag,
2751                                 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2752                 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
2753                 num_cqes++;
2754         }
2755
2756         if (num_cqes)
2757                 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
2758
2759         return 0;
2760 }
2761
2762
2763 static void
2764 setup_max_queues_want(POCE_SOFTC sc)
2765 {
2766         /* Check if it is FLEX machine. Is so dont use RSS */   
2767         if ((sc->function_mode & FNM_FLEX10_MODE) ||
2768             (sc->function_mode & FNM_UMC_MODE)    ||
2769             (sc->function_mode & FNM_VNIC_MODE)   ||
2770             (!is_rss_enabled(sc))                 ||
2771             IS_BE2(sc)) {
2772                 sc->nrqs = 1;
2773                 sc->nwqs = 1;
2774         } else {
2775                 sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1;
2776                 sc->nwqs = MIN(OCE_NCPUS, sc->nrssqs);
2777         }
2778
2779         if (IS_BE2(sc) && is_rss_enabled(sc))
2780                 sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1;
2781 }
2782
2783
2784 static void
2785 update_queues_got(POCE_SOFTC sc)
2786 {
2787         if (is_rss_enabled(sc)) {
2788                 sc->nrqs = sc->intr_count + 1;
2789                 sc->nwqs = sc->intr_count;
2790         } else {
2791                 sc->nrqs = 1;
2792                 sc->nwqs = 1;
2793         }
2794
2795         if (IS_BE2(sc))
2796                 sc->nwqs = 1;
2797 }
2798
2799 static int 
2800 oce_check_ipv6_ext_hdr(struct mbuf *m)
2801 {
2802         struct ether_header *eh = mtod(m, struct ether_header *);
2803         caddr_t m_datatemp = m->m_data;
2804
2805         if (eh->ether_type == htons(ETHERTYPE_IPV6)) {
2806                 m->m_data += sizeof(struct ether_header);
2807                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
2808
2809                 if((ip6->ip6_nxt != IPPROTO_TCP) && \
2810                                 (ip6->ip6_nxt != IPPROTO_UDP)){
2811                         struct ip6_ext *ip6e = NULL;
2812                         m->m_data += sizeof(struct ip6_hdr);
2813
2814                         ip6e = (struct ip6_ext *) mtod(m, struct ip6_ext *);
2815                         if(ip6e->ip6e_len == 0xff) {
2816                                 m->m_data = m_datatemp;
2817                                 return TRUE;
2818                         }
2819                 } 
2820                 m->m_data = m_datatemp;
2821         }
2822         return FALSE;
2823 }
2824
2825 static int 
2826 is_be3_a1(POCE_SOFTC sc)
2827 {
2828         if((sc->flags & OCE_FLAGS_BE3)  && ((sc->asic_revision & 0xFF) < 2)) {
2829                 return TRUE;
2830         }
2831         return FALSE;
2832 }
2833
2834 static struct mbuf *
2835 oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete)
2836 {
2837         uint16_t vlan_tag = 0;
2838
2839         if(!M_WRITABLE(m))
2840                 return NULL;
2841
2842         /* Embed vlan tag in the packet if it is not part of it */
2843         if(m->m_flags & M_VLANTAG) {
2844                 vlan_tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
2845                 m->m_flags &= ~M_VLANTAG;
2846         }
2847
2848         /* if UMC, ignore vlan tag insertion and instead insert pvid */
2849         if(sc->pvid) {
2850                 if(!vlan_tag)
2851                         vlan_tag = sc->pvid;
2852                 if (complete)
2853                         *complete = FALSE;
2854         }
2855
2856         if(vlan_tag) {
2857                 m = ether_vlanencap(m, vlan_tag);
2858         }
2859
2860         if(sc->qnqid) {
2861                 m = ether_vlanencap(m, sc->qnqid);
2862
2863                 if (complete)
2864                         *complete = FALSE;
2865         }
2866         return m;
2867 }
2868
2869 static int 
2870 oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m)
2871 {
2872         if(is_be3_a1(sc) && IS_QNQ_OR_UMC(sc) && \
2873                         oce_check_ipv6_ext_hdr(m)) {
2874                 return TRUE;
2875         }
2876         return FALSE;
2877 }
2878
2879 static void
2880 oce_get_config(POCE_SOFTC sc)
2881 {
2882         int rc = 0;
2883         uint32_t max_rss = 0;
2884
2885         if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
2886                 max_rss = OCE_LEGACY_MODE_RSS;
2887         else
2888                 max_rss = OCE_MAX_RSS;
2889
2890         if (!IS_BE(sc)) {
2891                 rc = oce_get_profile_config(sc, max_rss);
2892                 if (rc) {
2893                         sc->nwqs = OCE_MAX_WQ;
2894                         sc->nrssqs = max_rss;
2895                         sc->nrqs = sc->nrssqs + 1;
2896                 }
2897         }
2898         else { /* For BE3 don't rely on fw for determining the resources */
2899                 sc->nrssqs = max_rss;
2900                 sc->nrqs = sc->nrssqs + 1;
2901                 sc->nwqs = OCE_MAX_WQ;
2902                 sc->max_vlans = MAX_VLANFILTER_SIZE; 
2903         }
2904 }
2905
2906 static void
2907 oce_rdma_close(void)
2908 {
2909   if (oce_rdma_if != NULL) {
2910     oce_rdma_if = NULL;
2911   }
2912 }
2913
2914 static void
2915 oce_get_mac_addr(POCE_SOFTC sc, uint8_t *macaddr)
2916 {
2917   memcpy(macaddr, sc->macaddr.mac_addr, 6);
2918 }
2919
2920 int
2921 oce_register_rdma(POCE_RDMA_INFO rdma_info, POCE_RDMA_IF rdma_if)
2922 {
2923   POCE_SOFTC sc;
2924   struct oce_dev_info di;
2925   int i;
2926
2927   if ((rdma_info == NULL) || (rdma_if == NULL)) {
2928     return -EINVAL;
2929   }
2930
2931   if ((rdma_info->size != OCE_RDMA_INFO_SIZE) ||
2932       (rdma_if->size != OCE_RDMA_IF_SIZE)) {
2933     return -ENXIO;
2934   }
2935
2936   rdma_info->close = oce_rdma_close;
2937   rdma_info->mbox_post = oce_mbox_post;
2938   rdma_info->common_req_hdr_init = mbx_common_req_hdr_init;
2939   rdma_info->get_mac_addr = oce_get_mac_addr;
2940
2941   oce_rdma_if = rdma_if;
2942
2943   sc = softc_head;
2944   while (sc != NULL) {
2945     if (oce_rdma_if->announce != NULL) {
2946       memset(&di, 0, sizeof(di));
2947       di.dev = sc->dev;
2948       di.softc = sc;
2949       di.ifp = sc->ifp;
2950       di.db_bhandle = sc->db_bhandle;
2951       di.db_btag = sc->db_btag;
2952       di.db_page_size = 4096;
2953       if (sc->flags & OCE_FLAGS_USING_MSIX) {
2954         di.intr_mode = OCE_INTERRUPT_MODE_MSIX;
2955       } else if (sc->flags & OCE_FLAGS_USING_MSI) {
2956         di.intr_mode = OCE_INTERRUPT_MODE_MSI;
2957       } else {
2958         di.intr_mode = OCE_INTERRUPT_MODE_INTX;
2959       }
2960       di.dev_family = OCE_GEN2_FAMILY; // fixme: must detect skyhawk
2961       if (di.intr_mode != OCE_INTERRUPT_MODE_INTX) {
2962         di.msix.num_vectors = sc->intr_count + sc->roce_intr_count;
2963         di.msix.start_vector = sc->intr_count;
2964         for (i=0; i<di.msix.num_vectors; i++) {
2965           di.msix.vector_list[i] = sc->intrs[i].vector;
2966         }
2967       } else {
2968       }
2969       memcpy(di.mac_addr, sc->macaddr.mac_addr, 6);
2970       di.vendor_id = pci_get_vendor(sc->dev);
2971       di.dev_id = pci_get_device(sc->dev);
2972
2973       if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) {
2974           di.flags  |= OCE_RDMA_INFO_RDMA_SUPPORTED;
2975       }
2976
2977       rdma_if->announce(&di);
2978       sc = sc->next;
2979     }
2980   }
2981
2982   return 0;
2983 }
2984
2985 static void
2986 oce_read_env_variables( POCE_SOFTC sc )
2987 {
2988         char *value = NULL;
2989         int rc = 0;
2990
2991         /* read if user wants to enable hwlro or swlro */
2992         //value = getenv("oce_enable_hwlro");
2993         if(value && IS_SH(sc)) {
2994                 sc->enable_hwlro = strtol(value, NULL, 10);
2995                 if(sc->enable_hwlro) {
2996                         rc = oce_mbox_nic_query_lro_capabilities(sc, NULL, NULL);
2997                         if(rc) {
2998                                 device_printf(sc->dev, "no hardware lro support\n");
2999                                 device_printf(sc->dev, "software lro enabled\n");
3000                                 sc->enable_hwlro = 0;
3001                         }else {
3002                                 device_printf(sc->dev, "hardware lro enabled\n");
3003                                 oce_max_rsp_handled = 32;
3004                         }
3005                 }else {
3006                         device_printf(sc->dev, "software lro enabled\n");
3007                 }
3008         }else {
3009                 sc->enable_hwlro = 0;
3010         }
3011
3012         /* read mbuf size */
3013         //value = getenv("oce_rq_buf_size");
3014         if(value && IS_SH(sc)) {
3015                 oce_rq_buf_size = strtol(value, NULL, 10);
3016                 switch(oce_rq_buf_size) {
3017                 case 2048:
3018                 case 4096:
3019                 case 9216:
3020                 case 16384:
3021                         break;
3022
3023                 default:
3024                         device_printf(sc->dev, " Supported oce_rq_buf_size values are 2K, 4K, 9K, 16K \n");
3025                         oce_rq_buf_size = 2048;
3026                 }
3027         }
3028
3029         return;
3030 }