]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/oce/oce_if.c
MFC r342856: Added support for the SIOCGI2C ioctl.
[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 = oce_handle_passthrough(ifp, data);
620                 break;
621         default:
622                 rc = ether_ioctl(ifp, command, data);
623                 break;
624         }
625
626         return rc;
627 }
628
629
630 static void
631 oce_init(void *arg)
632 {
633         POCE_SOFTC sc = arg;
634         
635         LOCK(&sc->dev_lock);
636
637         if (sc->ifp->if_flags & IFF_UP) {
638                 oce_if_deactivate(sc);
639                 oce_if_activate(sc);
640         }
641         
642         UNLOCK(&sc->dev_lock);
643
644 }
645
646
647 static int
648 oce_multiq_start(struct ifnet *ifp, struct mbuf *m)
649 {
650         POCE_SOFTC sc = ifp->if_softc;
651         struct oce_wq *wq = NULL;
652         int queue_index = 0;
653         int status = 0;
654
655         if (!sc->link_status)
656                 return ENXIO;
657
658         if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE)
659                 queue_index = m->m_pkthdr.flowid % sc->nwqs;
660
661         wq = sc->wq[queue_index];
662
663         LOCK(&wq->tx_lock);
664         status = oce_multiq_transmit(ifp, m, wq);
665         UNLOCK(&wq->tx_lock);
666
667         return status;
668
669 }
670
671
672 static void
673 oce_multiq_flush(struct ifnet *ifp)
674 {
675         POCE_SOFTC sc = ifp->if_softc;
676         struct mbuf     *m;
677         int i = 0;
678
679         for (i = 0; i < sc->nwqs; i++) {
680                 while ((m = buf_ring_dequeue_sc(sc->wq[i]->br)) != NULL)
681                         m_freem(m);
682         }
683         if_qflush(ifp);
684 }
685
686
687
688 /*****************************************************************************
689  *                   Driver interrupt routines functions                     *
690  *****************************************************************************/
691
692 static void
693 oce_intr(void *arg, int pending)
694 {
695
696         POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
697         POCE_SOFTC sc = ii->sc;
698         struct oce_eq *eq = ii->eq;
699         struct oce_eqe *eqe;
700         struct oce_cq *cq = NULL;
701         int i, num_eqes = 0;
702
703
704         bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
705                                  BUS_DMASYNC_POSTWRITE);
706         do {
707                 eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
708                 if (eqe->evnt == 0)
709                         break;
710                 eqe->evnt = 0;
711                 bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
712                                         BUS_DMASYNC_POSTWRITE);
713                 RING_GET(eq->ring, 1);
714                 num_eqes++;
715
716         } while (TRUE);
717         
718         if (!num_eqes)
719                 goto eq_arm; /* Spurious */
720
721         /* Clear EQ entries, but dont arm */
722         oce_arm_eq(sc, eq->eq_id, num_eqes, FALSE, FALSE);
723
724         /* Process TX, RX and MCC. But dont arm CQ*/
725         for (i = 0; i < eq->cq_valid; i++) {
726                 cq = eq->cq[i];
727                 (*cq->cq_handler)(cq->cb_arg);
728         }
729
730         /* Arm all cqs connected to this EQ */
731         for (i = 0; i < eq->cq_valid; i++) {
732                 cq = eq->cq[i];
733                 oce_arm_cq(sc, cq->cq_id, 0, TRUE);
734         }
735
736 eq_arm:
737         oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
738
739         return;
740 }
741
742
743 static int
744 oce_setup_intr(POCE_SOFTC sc)
745 {
746         int rc = 0, use_intx = 0;
747         int vector = 0, req_vectors = 0;
748         int tot_req_vectors, tot_vectors;
749
750         if (is_rss_enabled(sc))
751                 req_vectors = MAX((sc->nrqs - 1), sc->nwqs);
752         else
753                 req_vectors = 1;
754
755         tot_req_vectors = req_vectors;
756         if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) {
757           if (req_vectors > 1) {
758             tot_req_vectors += OCE_RDMA_VECTORS;
759             sc->roce_intr_count = OCE_RDMA_VECTORS;
760           }
761         }
762
763         if (sc->flags & OCE_FLAGS_MSIX_CAPABLE) {
764                 sc->intr_count = req_vectors;
765                 tot_vectors = tot_req_vectors;
766                 rc = pci_alloc_msix(sc->dev, &tot_vectors);
767                 if (rc != 0) {
768                         use_intx = 1;
769                         pci_release_msi(sc->dev);
770                 } else {
771                   if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) {
772                     if (tot_vectors < tot_req_vectors) {
773                       if (sc->intr_count < (2 * OCE_RDMA_VECTORS)) {
774                         sc->roce_intr_count = (tot_vectors / 2);
775                       }
776                       sc->intr_count = tot_vectors - sc->roce_intr_count;
777                     }
778                   } else {
779                     sc->intr_count = tot_vectors;
780                   }
781                   sc->flags |= OCE_FLAGS_USING_MSIX;
782                 }
783         } else
784                 use_intx = 1;
785
786         if (use_intx)
787                 sc->intr_count = 1;
788
789         /* Scale number of queues based on intr we got */
790         update_queues_got(sc);
791
792         if (use_intx) {
793                 device_printf(sc->dev, "Using legacy interrupt\n");
794                 rc = oce_alloc_intr(sc, vector, oce_intr);
795                 if (rc)
796                         goto error;             
797         } else {
798                 for (; vector < sc->intr_count; vector++) {
799                         rc = oce_alloc_intr(sc, vector, oce_intr);
800                         if (rc)
801                                 goto error;
802                 }
803         }
804
805         return 0;
806 error:
807         oce_intr_free(sc);
808         return rc;
809 }
810
811
812 static int
813 oce_fast_isr(void *arg)
814 {
815         POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
816         POCE_SOFTC sc = ii->sc;
817
818         if (ii->eq == NULL)
819                 return FILTER_STRAY;
820
821         oce_arm_eq(sc, ii->eq->eq_id, 0, FALSE, TRUE);
822
823         taskqueue_enqueue(ii->tq, &ii->task);
824
825         ii->eq->intr++; 
826
827         return FILTER_HANDLED;
828 }
829
830
831 static int
832 oce_alloc_intr(POCE_SOFTC sc, int vector, void (*isr) (void *arg, int pending))
833 {
834         POCE_INTR_INFO ii = &sc->intrs[vector];
835         int rc = 0, rr;
836
837         if (vector >= OCE_MAX_EQ)
838                 return (EINVAL);
839
840         /* Set the resource id for the interrupt.
841          * MSIx is vector + 1 for the resource id,
842          * INTx is 0 for the resource id.
843          */
844         if (sc->flags & OCE_FLAGS_USING_MSIX)
845                 rr = vector + 1;
846         else
847                 rr = 0;
848         ii->intr_res = bus_alloc_resource_any(sc->dev,
849                                               SYS_RES_IRQ,
850                                               &rr, RF_ACTIVE|RF_SHAREABLE);
851         ii->irq_rr = rr;
852         if (ii->intr_res == NULL) {
853                 device_printf(sc->dev,
854                           "Could not allocate interrupt\n");
855                 rc = ENXIO;
856                 return rc;
857         }
858
859         TASK_INIT(&ii->task, 0, isr, ii);
860         ii->vector = vector;
861         sprintf(ii->task_name, "oce_task[%d]", ii->vector);
862         ii->tq = taskqueue_create_fast(ii->task_name,
863                         M_NOWAIT,
864                         taskqueue_thread_enqueue,
865                         &ii->tq);
866         taskqueue_start_threads(&ii->tq, 1, PI_NET, "%s taskq",
867                         device_get_nameunit(sc->dev));
868
869         ii->sc = sc;
870         rc = bus_setup_intr(sc->dev,
871                         ii->intr_res,
872                         INTR_TYPE_NET,
873                         oce_fast_isr, NULL, ii, &ii->tag);
874         return rc;
875
876 }
877
878
879 void
880 oce_intr_free(POCE_SOFTC sc)
881 {
882         int i = 0;
883         
884         for (i = 0; i < sc->intr_count; i++) {
885                 
886                 if (sc->intrs[i].tag != NULL)
887                         bus_teardown_intr(sc->dev, sc->intrs[i].intr_res,
888                                                 sc->intrs[i].tag);
889                 if (sc->intrs[i].tq != NULL)
890                         taskqueue_free(sc->intrs[i].tq);
891                 
892                 if (sc->intrs[i].intr_res != NULL)
893                         bus_release_resource(sc->dev, SYS_RES_IRQ,
894                                                 sc->intrs[i].irq_rr,
895                                                 sc->intrs[i].intr_res);
896                 sc->intrs[i].tag = NULL;
897                 sc->intrs[i].intr_res = NULL;
898         }
899
900         if (sc->flags & OCE_FLAGS_USING_MSIX)
901                 pci_release_msi(sc->dev);
902
903 }
904
905
906
907 /******************************************************************************
908 *                         Media callbacks functions                           *
909 ******************************************************************************/
910
911 static void
912 oce_media_status(struct ifnet *ifp, struct ifmediareq *req)
913 {
914         POCE_SOFTC sc = (POCE_SOFTC) ifp->if_softc;
915
916
917         req->ifm_status = IFM_AVALID;
918         req->ifm_active = IFM_ETHER;
919         
920         if (sc->link_status == 1)
921                 req->ifm_status |= IFM_ACTIVE;
922         else 
923                 return;
924         
925         switch (sc->link_speed) {
926         case 1: /* 10 Mbps */
927                 req->ifm_active |= IFM_10_T | IFM_FDX;
928                 sc->speed = 10;
929                 break;
930         case 2: /* 100 Mbps */
931                 req->ifm_active |= IFM_100_TX | IFM_FDX;
932                 sc->speed = 100;
933                 break;
934         case 3: /* 1 Gbps */
935                 req->ifm_active |= IFM_1000_T | IFM_FDX;
936                 sc->speed = 1000;
937                 break;
938         case 4: /* 10 Gbps */
939                 req->ifm_active |= IFM_10G_SR | IFM_FDX;
940                 sc->speed = 10000;
941                 break;
942         case 5: /* 20 Gbps */
943                 req->ifm_active |= IFM_10G_SR | IFM_FDX;
944                 sc->speed = 20000;
945                 break;
946         case 6: /* 25 Gbps */
947                 req->ifm_active |= IFM_10G_SR | IFM_FDX;
948                 sc->speed = 25000;
949                 break;
950         case 7: /* 40 Gbps */
951                 req->ifm_active |= IFM_40G_SR4 | IFM_FDX;
952                 sc->speed = 40000;
953                 break;
954         default:
955                 sc->speed = 0;
956                 break;
957         }
958         
959         return;
960 }
961
962
963 int
964 oce_media_change(struct ifnet *ifp)
965 {
966         return 0;
967 }
968
969
970 static void oce_is_pkt_dest_bmc(POCE_SOFTC sc,
971                                 struct mbuf *m, boolean_t *os2bmc,
972                                 struct mbuf **m_new)
973 {
974         struct ether_header *eh = NULL;
975
976         eh = mtod(m, struct ether_header *);
977
978         if (!is_os2bmc_enabled(sc) || *os2bmc) {
979                 *os2bmc = FALSE;
980                 goto done;
981         }
982         if (!ETHER_IS_MULTICAST(eh->ether_dhost))
983                 goto done;
984
985         if (is_mc_allowed_on_bmc(sc, eh) ||
986             is_bc_allowed_on_bmc(sc, eh) ||
987             is_arp_allowed_on_bmc(sc, ntohs(eh->ether_type))) {
988                 *os2bmc = TRUE;
989                 goto done;
990         }
991
992         if (mtod(m, struct ip *)->ip_p == IPPROTO_IPV6) {
993                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
994                 uint8_t nexthdr = ip6->ip6_nxt;
995                 if (nexthdr == IPPROTO_ICMPV6) {
996                         struct icmp6_hdr *icmp6 = (struct icmp6_hdr *)(ip6 + 1);
997                         switch (icmp6->icmp6_type) {
998                         case ND_ROUTER_ADVERT:
999                                 *os2bmc = is_ipv6_ra_filt_enabled(sc);
1000                                 goto done;
1001                         case ND_NEIGHBOR_ADVERT:
1002                                 *os2bmc = is_ipv6_na_filt_enabled(sc);
1003                                 goto done;
1004                         default:
1005                                 break;
1006                         }
1007                 }
1008         }
1009
1010         if (mtod(m, struct ip *)->ip_p == IPPROTO_UDP) {
1011                 struct ip *ip = mtod(m, struct ip *);
1012                 int iphlen = ip->ip_hl << 2;
1013                 struct udphdr *uh = (struct udphdr *)((caddr_t)ip + iphlen);
1014                 switch (uh->uh_dport) {
1015                 case DHCP_CLIENT_PORT:
1016                         *os2bmc = is_dhcp_client_filt_enabled(sc);
1017                         goto done;
1018                 case DHCP_SERVER_PORT:
1019                         *os2bmc = is_dhcp_srvr_filt_enabled(sc);
1020                         goto done;
1021                 case NET_BIOS_PORT1:
1022                 case NET_BIOS_PORT2:
1023                         *os2bmc = is_nbios_filt_enabled(sc);
1024                         goto done;
1025                 case DHCPV6_RAS_PORT:
1026                         *os2bmc = is_ipv6_ras_filt_enabled(sc);
1027                         goto done;
1028                 default:
1029                         break;
1030                 }
1031         }
1032 done:
1033         if (*os2bmc) {
1034                 *m_new = m_dup(m, M_NOWAIT);
1035                 if (!*m_new) {
1036                         *os2bmc = FALSE;
1037                         return;
1038                 }
1039                 *m_new = oce_insert_vlan_tag(sc, *m_new, NULL);
1040         }
1041 }
1042
1043
1044
1045 /*****************************************************************************
1046  *                        Transmit routines functions                        *
1047  *****************************************************************************/
1048
1049 static int
1050 oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
1051 {
1052         int rc = 0, i, retry_cnt = 0;
1053         bus_dma_segment_t segs[OCE_MAX_TX_ELEMENTS];
1054         struct mbuf *m, *m_temp, *m_new = NULL;
1055         struct oce_wq *wq = sc->wq[wq_index];
1056         struct oce_packet_desc *pd;
1057         struct oce_nic_hdr_wqe *nichdr;
1058         struct oce_nic_frag_wqe *nicfrag;
1059         struct ether_header *eh = NULL;
1060         int num_wqes;
1061         uint32_t reg_value;
1062         boolean_t complete = TRUE;
1063         boolean_t os2bmc = FALSE;
1064
1065         m = *mpp;
1066         if (!m)
1067                 return EINVAL;
1068
1069         if (!(m->m_flags & M_PKTHDR)) {
1070                 rc = ENXIO;
1071                 goto free_ret;
1072         }
1073
1074         /* Don't allow non-TSO packets longer than MTU */
1075         if (!is_tso_pkt(m)) {
1076                 eh = mtod(m, struct ether_header *);
1077                 if(m->m_pkthdr.len > ETHER_MAX_FRAME(sc->ifp, eh->ether_type, FALSE))
1078                          goto free_ret;
1079         }
1080
1081         if(oce_tx_asic_stall_verify(sc, m)) {
1082                 m = oce_insert_vlan_tag(sc, m, &complete);
1083                 if(!m) {
1084                         device_printf(sc->dev, "Insertion unsuccessful\n");
1085                         return 0;
1086                 }
1087
1088         }
1089
1090         /* Lancer, SH ASIC has a bug wherein Packets that are 32 bytes or less
1091          * may cause a transmit stall on that port. So the work-around is to
1092          * pad short packets (<= 32 bytes) to a 36-byte length.
1093         */
1094         if(IS_SH(sc) || IS_XE201(sc) ) {
1095                 if(m->m_pkthdr.len <= 32) {
1096                         char buf[36];
1097                         bzero((void *)buf, 36);
1098                         m_append(m, (36 - m->m_pkthdr.len), buf);
1099                 }
1100         }
1101
1102 tx_start:
1103         if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1104                 /* consolidate packet buffers for TSO/LSO segment offload */
1105 #if defined(INET6) || defined(INET)
1106                 m = oce_tso_setup(sc, mpp);
1107 #else
1108                 m = NULL;
1109 #endif
1110                 if (m == NULL) {
1111                         rc = ENXIO;
1112                         goto free_ret;
1113                 }
1114         }
1115
1116
1117         pd = &wq->pckts[wq->pkt_desc_head];
1118
1119 retry:
1120         rc = bus_dmamap_load_mbuf_sg(wq->tag,
1121                                      pd->map,
1122                                      m, segs, &pd->nsegs, BUS_DMA_NOWAIT);
1123         if (rc == 0) {
1124                 num_wqes = pd->nsegs + 1;
1125                 if (IS_BE(sc) || IS_SH(sc)) {
1126                         /*Dummy required only for BE3.*/
1127                         if (num_wqes & 1)
1128                                 num_wqes++;
1129                 }
1130                 if (num_wqes >= RING_NUM_FREE(wq->ring)) {
1131                         bus_dmamap_unload(wq->tag, pd->map);
1132                         return EBUSY;
1133                 }
1134                 atomic_store_rel_int(&wq->pkt_desc_head,
1135                                      (wq->pkt_desc_head + 1) % \
1136                                       OCE_WQ_PACKET_ARRAY_SIZE);
1137                 bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_PREWRITE);
1138                 pd->mbuf = m;
1139
1140                 nichdr =
1141                     RING_GET_PRODUCER_ITEM_VA(wq->ring, struct oce_nic_hdr_wqe);
1142                 nichdr->u0.dw[0] = 0;
1143                 nichdr->u0.dw[1] = 0;
1144                 nichdr->u0.dw[2] = 0;
1145                 nichdr->u0.dw[3] = 0;
1146
1147                 nichdr->u0.s.complete = complete;
1148                 nichdr->u0.s.mgmt = os2bmc;
1149                 nichdr->u0.s.event = 1;
1150                 nichdr->u0.s.crc = 1;
1151                 nichdr->u0.s.forward = 0;
1152                 nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0;
1153                 nichdr->u0.s.udpcs =
1154                         (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
1155                 nichdr->u0.s.tcpcs =
1156                         (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
1157                 nichdr->u0.s.num_wqe = num_wqes;
1158                 nichdr->u0.s.total_length = m->m_pkthdr.len;
1159
1160                 if (m->m_flags & M_VLANTAG) {
1161                         nichdr->u0.s.vlan = 1; /*Vlan present*/
1162                         nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag;
1163                 }
1164
1165                 if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1166                         if (m->m_pkthdr.tso_segsz) {
1167                                 nichdr->u0.s.lso = 1;
1168                                 nichdr->u0.s.lso_mss  = m->m_pkthdr.tso_segsz;
1169                         }
1170                         if (!IS_BE(sc) || !IS_SH(sc))
1171                                 nichdr->u0.s.ipcs = 1;
1172                 }
1173
1174                 RING_PUT(wq->ring, 1);
1175                 atomic_add_int(&wq->ring->num_used, 1);
1176
1177                 for (i = 0; i < pd->nsegs; i++) {
1178                         nicfrag =
1179                             RING_GET_PRODUCER_ITEM_VA(wq->ring,
1180                                                       struct oce_nic_frag_wqe);
1181                         nicfrag->u0.s.rsvd0 = 0;
1182                         nicfrag->u0.s.frag_pa_hi = ADDR_HI(segs[i].ds_addr);
1183                         nicfrag->u0.s.frag_pa_lo = ADDR_LO(segs[i].ds_addr);
1184                         nicfrag->u0.s.frag_len = segs[i].ds_len;
1185                         pd->wqe_idx = wq->ring->pidx;
1186                         RING_PUT(wq->ring, 1);
1187                         atomic_add_int(&wq->ring->num_used, 1);
1188                 }
1189                 if (num_wqes > (pd->nsegs + 1)) {
1190                         nicfrag =
1191                             RING_GET_PRODUCER_ITEM_VA(wq->ring,
1192                                                       struct oce_nic_frag_wqe);
1193                         nicfrag->u0.dw[0] = 0;
1194                         nicfrag->u0.dw[1] = 0;
1195                         nicfrag->u0.dw[2] = 0;
1196                         nicfrag->u0.dw[3] = 0;
1197                         pd->wqe_idx = wq->ring->pidx;
1198                         RING_PUT(wq->ring, 1);
1199                         atomic_add_int(&wq->ring->num_used, 1);
1200                         pd->nsegs++;
1201                 }
1202
1203                 if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
1204                 wq->tx_stats.tx_reqs++;
1205                 wq->tx_stats.tx_wrbs += num_wqes;
1206                 wq->tx_stats.tx_bytes += m->m_pkthdr.len;
1207                 wq->tx_stats.tx_pkts++;
1208
1209                 bus_dmamap_sync(wq->ring->dma.tag, wq->ring->dma.map,
1210                                 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1211                 reg_value = (num_wqes << 16) | wq->wq_id;
1212
1213                 /* if os2bmc is not enabled or if the pkt is already tagged as
1214                    bmc, do nothing
1215                  */
1216                 oce_is_pkt_dest_bmc(sc, m, &os2bmc, &m_new);
1217
1218                 OCE_WRITE_REG32(sc, db, wq->db_offset, reg_value);
1219
1220         } else if (rc == EFBIG) {
1221                 if (retry_cnt == 0) {
1222                         m_temp = m_defrag(m, M_NOWAIT);
1223                         if (m_temp == NULL)
1224                                 goto free_ret;
1225                         m = m_temp;
1226                         *mpp = m_temp;
1227                         retry_cnt = retry_cnt + 1;
1228                         goto retry;
1229                 } else
1230                         goto free_ret;
1231         } else if (rc == ENOMEM)
1232                 return rc;
1233         else
1234                 goto free_ret;
1235
1236         if (os2bmc) {
1237                 m = m_new;
1238                 goto tx_start;
1239         }
1240         
1241         return 0;
1242
1243 free_ret:
1244         m_freem(*mpp);
1245         *mpp = NULL;
1246         return rc;
1247 }
1248
1249
1250 static void
1251 oce_process_tx_completion(struct oce_wq *wq)
1252 {
1253         struct oce_packet_desc *pd;
1254         POCE_SOFTC sc = (POCE_SOFTC) wq->parent;
1255         struct mbuf *m;
1256
1257         pd = &wq->pckts[wq->pkt_desc_tail];
1258         atomic_store_rel_int(&wq->pkt_desc_tail,
1259                              (wq->pkt_desc_tail + 1) % OCE_WQ_PACKET_ARRAY_SIZE); 
1260         atomic_subtract_int(&wq->ring->num_used, pd->nsegs + 1);
1261         bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1262         bus_dmamap_unload(wq->tag, pd->map);
1263
1264         m = pd->mbuf;
1265         m_freem(m);
1266         pd->mbuf = NULL;
1267
1268
1269         if (sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) {
1270                 if (wq->ring->num_used < (wq->ring->num_items / 2)) {
1271                         sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE);
1272                         oce_tx_restart(sc, wq); 
1273                 }
1274         }
1275 }
1276
1277
1278 static void
1279 oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq)
1280 {
1281
1282         if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING)
1283                 return;
1284
1285 #if __FreeBSD_version >= 800000
1286         if (!drbr_empty(sc->ifp, wq->br))
1287 #else
1288         if (!IFQ_DRV_IS_EMPTY(&sc->ifp->if_snd))
1289 #endif
1290                 taskqueue_enqueue(taskqueue_swi, &wq->txtask);
1291
1292 }
1293
1294
1295 #if defined(INET6) || defined(INET)
1296 static struct mbuf *
1297 oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp)
1298 {
1299         struct mbuf *m;
1300 #ifdef INET
1301         struct ip *ip;
1302 #endif
1303 #ifdef INET6
1304         struct ip6_hdr *ip6;
1305 #endif
1306         struct ether_vlan_header *eh;
1307         struct tcphdr *th;
1308         uint16_t etype;
1309         int total_len = 0, ehdrlen = 0;
1310         
1311         m = *mpp;
1312
1313         if (M_WRITABLE(m) == 0) {
1314                 m = m_dup(*mpp, M_NOWAIT);
1315                 if (!m)
1316                         return NULL;
1317                 m_freem(*mpp);
1318                 *mpp = m;
1319         }
1320
1321         eh = mtod(m, struct ether_vlan_header *);
1322         if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
1323                 etype = ntohs(eh->evl_proto);
1324                 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
1325         } else {
1326                 etype = ntohs(eh->evl_encap_proto);
1327                 ehdrlen = ETHER_HDR_LEN;
1328         }
1329
1330         switch (etype) {
1331 #ifdef INET
1332         case ETHERTYPE_IP:
1333                 ip = (struct ip *)(m->m_data + ehdrlen);
1334                 if (ip->ip_p != IPPROTO_TCP)
1335                         return NULL;
1336                 th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
1337
1338                 total_len = ehdrlen + (ip->ip_hl << 2) + (th->th_off << 2);
1339                 break;
1340 #endif
1341 #ifdef INET6
1342         case ETHERTYPE_IPV6:
1343                 ip6 = (struct ip6_hdr *)(m->m_data + ehdrlen);
1344                 if (ip6->ip6_nxt != IPPROTO_TCP)
1345                         return NULL;
1346                 th = (struct tcphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr));
1347
1348                 total_len = ehdrlen + sizeof(struct ip6_hdr) + (th->th_off << 2);
1349                 break;
1350 #endif
1351         default:
1352                 return NULL;
1353         }
1354         
1355         m = m_pullup(m, total_len);
1356         if (!m)
1357                 return NULL;
1358         *mpp = m;
1359         return m;
1360         
1361 }
1362 #endif /* INET6 || INET */
1363
1364 void
1365 oce_tx_task(void *arg, int npending)
1366 {
1367         struct oce_wq *wq = arg;
1368         POCE_SOFTC sc = wq->parent;
1369         struct ifnet *ifp = sc->ifp;
1370         int rc = 0;
1371
1372 #if __FreeBSD_version >= 800000
1373         LOCK(&wq->tx_lock);
1374         rc = oce_multiq_transmit(ifp, NULL, wq);
1375         if (rc) {
1376                 device_printf(sc->dev,
1377                                 "TX[%d] restart failed\n", wq->queue_index);
1378         }
1379         UNLOCK(&wq->tx_lock);
1380 #else
1381         oce_start(ifp);
1382 #endif
1383
1384 }
1385
1386
1387 void
1388 oce_start(struct ifnet *ifp)
1389 {
1390         POCE_SOFTC sc = ifp->if_softc;
1391         struct mbuf *m;
1392         int rc = 0;
1393         int def_q = 0; /* Defualt tx queue is 0*/
1394
1395         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
1396                         IFF_DRV_RUNNING)
1397                 return;
1398
1399         if (!sc->link_status)
1400                 return;
1401         
1402         do {
1403                 IF_DEQUEUE(&sc->ifp->if_snd, m);
1404                 if (m == NULL)
1405                         break;
1406
1407                 LOCK(&sc->wq[def_q]->tx_lock);
1408                 rc = oce_tx(sc, &m, def_q);
1409                 UNLOCK(&sc->wq[def_q]->tx_lock);
1410                 if (rc) {
1411                         if (m != NULL) {
1412                                 sc->wq[def_q]->tx_stats.tx_stops ++;
1413                                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1414                                 IFQ_DRV_PREPEND(&ifp->if_snd, m);
1415                                 m = NULL;
1416                         }
1417                         break;
1418                 }
1419                 if (m != NULL)
1420                         ETHER_BPF_MTAP(ifp, m);
1421
1422         } while (TRUE);
1423
1424         return;
1425 }
1426
1427
1428 /* Handle the Completion Queue for transmit */
1429 uint16_t
1430 oce_wq_handler(void *arg)
1431 {
1432         struct oce_wq *wq = (struct oce_wq *)arg;
1433         POCE_SOFTC sc = wq->parent;
1434         struct oce_cq *cq = wq->cq;
1435         struct oce_nic_tx_cqe *cqe;
1436         int num_cqes = 0;
1437
1438         LOCK(&wq->tx_compl_lock);
1439         bus_dmamap_sync(cq->ring->dma.tag,
1440                         cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1441         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
1442         while (cqe->u0.dw[3]) {
1443                 DW_SWAP((uint32_t *) cqe, sizeof(oce_wq_cqe));
1444
1445                 wq->ring->cidx = cqe->u0.s.wqe_index + 1;
1446                 if (wq->ring->cidx >= wq->ring->num_items)
1447                         wq->ring->cidx -= wq->ring->num_items;
1448
1449                 oce_process_tx_completion(wq);
1450                 wq->tx_stats.tx_compl++;
1451                 cqe->u0.dw[3] = 0;
1452                 RING_GET(cq->ring, 1);
1453                 bus_dmamap_sync(cq->ring->dma.tag,
1454                                 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1455                 cqe =
1456                     RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
1457                 num_cqes++;
1458         }
1459
1460         if (num_cqes)
1461                 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
1462         
1463         UNLOCK(&wq->tx_compl_lock);
1464         return num_cqes;
1465 }
1466
1467
1468 static int 
1469 oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
1470 {
1471         POCE_SOFTC sc = ifp->if_softc;
1472         int status = 0, queue_index = 0;
1473         struct mbuf *next = NULL;
1474         struct buf_ring *br = NULL;
1475
1476         br  = wq->br;
1477         queue_index = wq->queue_index;
1478
1479         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
1480                 IFF_DRV_RUNNING) {
1481                 if (m != NULL)
1482                         status = drbr_enqueue(ifp, br, m);
1483                 return status;
1484         }
1485
1486         if (m != NULL) {
1487                 if ((status = drbr_enqueue(ifp, br, m)) != 0)
1488                         return status;
1489         } 
1490         while ((next = drbr_peek(ifp, br)) != NULL) {
1491                 if (oce_tx(sc, &next, queue_index)) {
1492                         if (next == NULL) {
1493                                 drbr_advance(ifp, br);
1494                         } else {
1495                                 drbr_putback(ifp, br, next);
1496                                 wq->tx_stats.tx_stops ++;
1497                                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1498                         }  
1499                         break;
1500                 }
1501                 drbr_advance(ifp, br);
1502                 if_inc_counter(ifp, IFCOUNTER_OBYTES, next->m_pkthdr.len);
1503                 if (next->m_flags & M_MCAST)
1504                         if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
1505                 ETHER_BPF_MTAP(ifp, next);
1506         }
1507
1508         return 0;
1509 }
1510
1511
1512
1513
1514 /*****************************************************************************
1515  *                          Receive  routines functions                      *
1516  *****************************************************************************/
1517
1518 static void
1519 oce_correct_header(struct mbuf *m, struct nic_hwlro_cqe_part1 *cqe1, struct nic_hwlro_cqe_part2 *cqe2)
1520 {
1521         uint32_t *p;
1522         struct ether_header *eh = NULL;
1523         struct tcphdr *tcp_hdr = NULL;
1524         struct ip *ip4_hdr = NULL;
1525         struct ip6_hdr *ip6 = NULL;
1526         uint32_t payload_len = 0;
1527
1528         eh = mtod(m, struct ether_header *);
1529         /* correct IP header */
1530         if(!cqe2->ipv6_frame) {
1531                 ip4_hdr = (struct ip *)((char*)eh + sizeof(struct ether_header));
1532                 ip4_hdr->ip_ttl = cqe2->frame_lifespan;
1533                 ip4_hdr->ip_len = htons(cqe2->coalesced_size - sizeof(struct ether_header));
1534                 tcp_hdr = (struct tcphdr *)((char*)ip4_hdr + sizeof(struct ip));
1535         }else {
1536                 ip6 = (struct ip6_hdr *)((char*)eh + sizeof(struct ether_header));
1537                 ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim = cqe2->frame_lifespan;
1538                 payload_len = cqe2->coalesced_size - sizeof(struct ether_header)
1539                                                 - sizeof(struct ip6_hdr);
1540                 ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(payload_len);
1541                 tcp_hdr = (struct tcphdr *)((char*)ip6 + sizeof(struct ip6_hdr));
1542         }
1543
1544         /* correct tcp header */
1545         tcp_hdr->th_ack = htonl(cqe2->tcp_ack_num);
1546         if(cqe2->push) {
1547                 tcp_hdr->th_flags |= TH_PUSH;
1548         }
1549         tcp_hdr->th_win = htons(cqe2->tcp_window);
1550         tcp_hdr->th_sum = 0xffff;
1551         if(cqe2->ts_opt) {
1552                 p = (uint32_t *)((char*)tcp_hdr + sizeof(struct tcphdr) + 2);
1553                 *p = cqe1->tcp_timestamp_val;
1554                 *(p+1) = cqe1->tcp_timestamp_ecr;
1555         }
1556
1557         return;
1558 }
1559
1560 static void
1561 oce_rx_mbuf_chain(struct oce_rq *rq, struct oce_common_cqe_info *cqe_info, struct mbuf **m)
1562 {
1563         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1564         uint32_t i = 0, frag_len = 0;
1565         uint32_t len = cqe_info->pkt_size;
1566         struct oce_packet_desc *pd;
1567         struct mbuf *tail = NULL;
1568
1569         for (i = 0; i < cqe_info->num_frags; i++) {
1570                 if (rq->ring->cidx == rq->ring->pidx) {
1571                         device_printf(sc->dev,
1572                                   "oce_rx_mbuf_chain: Invalid RX completion - Queue is empty\n");
1573                         return;
1574                 }
1575                 pd = &rq->pckts[rq->ring->cidx];
1576
1577                 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1578                 bus_dmamap_unload(rq->tag, pd->map);
1579                 RING_GET(rq->ring, 1);
1580                 rq->pending--;
1581
1582                 frag_len = (len > rq->cfg.frag_size) ? rq->cfg.frag_size : len;
1583                 pd->mbuf->m_len = frag_len;
1584
1585                 if (tail != NULL) {
1586                         /* additional fragments */
1587                         pd->mbuf->m_flags &= ~M_PKTHDR;
1588                         tail->m_next = pd->mbuf;
1589                         if(rq->islro)
1590                                 tail->m_nextpkt = NULL;
1591                         tail = pd->mbuf;
1592                 } else {
1593                         /* first fragment, fill out much of the packet header */
1594                         pd->mbuf->m_pkthdr.len = len;
1595                         if(rq->islro)
1596                                 pd->mbuf->m_nextpkt = NULL;
1597                         pd->mbuf->m_pkthdr.csum_flags = 0;
1598                         if (IF_CSUM_ENABLED(sc)) {
1599                                 if (cqe_info->l4_cksum_pass) {
1600                                         if(!cqe_info->ipv6_frame) { /* IPV4 */
1601                                                 pd->mbuf->m_pkthdr.csum_flags |=
1602                                                         (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
1603                                         }else { /* IPV6 frame */
1604                                                 if(rq->islro) {
1605                                                         pd->mbuf->m_pkthdr.csum_flags |=
1606                                                         (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
1607                                                 }
1608                                         }
1609                                         pd->mbuf->m_pkthdr.csum_data = 0xffff;
1610                                 }
1611                                 if (cqe_info->ip_cksum_pass) {
1612                                         pd->mbuf->m_pkthdr.csum_flags |=
1613                                                (CSUM_IP_CHECKED|CSUM_IP_VALID);
1614                                 }
1615                         }
1616                         *m = tail = pd->mbuf;
1617                }
1618                 pd->mbuf = NULL;
1619                 len -= frag_len;
1620         }
1621
1622         return;
1623 }
1624
1625 static void
1626 oce_rx_lro(struct oce_rq *rq, struct nic_hwlro_singleton_cqe *cqe, struct nic_hwlro_cqe_part2 *cqe2)
1627 {
1628         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1629         struct nic_hwlro_cqe_part1 *cqe1 = NULL;
1630         struct mbuf *m = NULL;
1631         struct oce_common_cqe_info cq_info;
1632
1633         /* parse cqe */
1634         if(cqe2 == NULL) {
1635                 cq_info.pkt_size =  cqe->pkt_size;
1636                 cq_info.vtag = cqe->vlan_tag;
1637                 cq_info.l4_cksum_pass = cqe->l4_cksum_pass;
1638                 cq_info.ip_cksum_pass = cqe->ip_cksum_pass;
1639                 cq_info.ipv6_frame = cqe->ipv6_frame;
1640                 cq_info.vtp = cqe->vtp;
1641                 cq_info.qnq = cqe->qnq;
1642         }else {
1643                 cqe1 = (struct nic_hwlro_cqe_part1 *)cqe;
1644                 cq_info.pkt_size =  cqe2->coalesced_size;
1645                 cq_info.vtag = cqe2->vlan_tag;
1646                 cq_info.l4_cksum_pass = cqe2->l4_cksum_pass;
1647                 cq_info.ip_cksum_pass = cqe2->ip_cksum_pass;
1648                 cq_info.ipv6_frame = cqe2->ipv6_frame;
1649                 cq_info.vtp = cqe2->vtp;
1650                 cq_info.qnq = cqe1->qnq;
1651         }
1652         
1653         cq_info.vtag = BSWAP_16(cq_info.vtag);
1654
1655         cq_info.num_frags = cq_info.pkt_size / rq->cfg.frag_size;
1656         if(cq_info.pkt_size % rq->cfg.frag_size)
1657                 cq_info.num_frags++;
1658
1659         oce_rx_mbuf_chain(rq, &cq_info, &m);
1660
1661         if (m) {
1662                 if(cqe2) {
1663                         //assert(cqe2->valid != 0);
1664                         
1665                         //assert(cqe2->cqe_type != 2);
1666                         oce_correct_header(m, cqe1, cqe2);
1667                 }
1668
1669                 m->m_pkthdr.rcvif = sc->ifp;
1670 #if __FreeBSD_version >= 800000
1671                 if (rq->queue_index)
1672                         m->m_pkthdr.flowid = (rq->queue_index - 1);
1673                 else
1674                         m->m_pkthdr.flowid = rq->queue_index;
1675                 M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
1676 #endif
1677                 /* This deternies if vlan tag is Valid */
1678                 if (cq_info.vtp) {
1679                         if (sc->function_mode & FNM_FLEX10_MODE) {
1680                                 /* FLEX10. If QnQ is not set, neglect VLAN */
1681                                 if (cq_info.qnq) {
1682                                         m->m_pkthdr.ether_vtag = cq_info.vtag;
1683                                         m->m_flags |= M_VLANTAG;
1684                                 }
1685                         } else if (sc->pvid != (cq_info.vtag & VLAN_VID_MASK))  {
1686                                 /* In UMC mode generally pvid will be striped by
1687                                    hw. But in some cases we have seen it comes
1688                                    with pvid. So if pvid == vlan, neglect vlan.
1689                                  */
1690                                 m->m_pkthdr.ether_vtag = cq_info.vtag;
1691                                 m->m_flags |= M_VLANTAG;
1692                         }
1693                 }
1694                 if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
1695                 
1696                 (*sc->ifp->if_input) (sc->ifp, m);
1697
1698                 /* Update rx stats per queue */
1699                 rq->rx_stats.rx_pkts++;
1700                 rq->rx_stats.rx_bytes += cq_info.pkt_size;
1701                 rq->rx_stats.rx_frags += cq_info.num_frags;
1702                 rq->rx_stats.rx_ucast_pkts++;
1703         }
1704         return;
1705 }
1706
1707 static void
1708 oce_rx(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
1709 {
1710         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1711         int len;
1712         struct mbuf *m = NULL;
1713         struct oce_common_cqe_info cq_info;
1714         uint16_t vtag = 0;
1715
1716         /* Is it a flush compl that has no data */
1717         if(!cqe->u0.s.num_fragments)
1718                 goto exit;
1719
1720         len = cqe->u0.s.pkt_size;
1721         if (!len) {
1722                 /*partial DMA workaround for Lancer*/
1723                 oce_discard_rx_comp(rq, cqe->u0.s.num_fragments);
1724                 goto exit;
1725         }
1726
1727         if (!oce_cqe_portid_valid(sc, cqe)) {
1728                 oce_discard_rx_comp(rq, cqe->u0.s.num_fragments);
1729                 goto exit;
1730         }
1731
1732          /* Get vlan_tag value */
1733         if(IS_BE(sc) || IS_SH(sc))
1734                 vtag = BSWAP_16(cqe->u0.s.vlan_tag);
1735         else
1736                 vtag = cqe->u0.s.vlan_tag;
1737         
1738         cq_info.l4_cksum_pass = cqe->u0.s.l4_cksum_pass;
1739         cq_info.ip_cksum_pass = cqe->u0.s.ip_cksum_pass;
1740         cq_info.ipv6_frame = cqe->u0.s.ip_ver;
1741         cq_info.num_frags = cqe->u0.s.num_fragments;
1742         cq_info.pkt_size = cqe->u0.s.pkt_size;
1743
1744         oce_rx_mbuf_chain(rq, &cq_info, &m);
1745
1746         if (m) {
1747                 m->m_pkthdr.rcvif = sc->ifp;
1748 #if __FreeBSD_version >= 800000
1749                 if (rq->queue_index)
1750                         m->m_pkthdr.flowid = (rq->queue_index - 1);
1751                 else
1752                         m->m_pkthdr.flowid = rq->queue_index;
1753                 M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
1754 #endif
1755                 /* This deternies if vlan tag is Valid */
1756                 if (oce_cqe_vtp_valid(sc, cqe)) { 
1757                         if (sc->function_mode & FNM_FLEX10_MODE) {
1758                                 /* FLEX10. If QnQ is not set, neglect VLAN */
1759                                 if (cqe->u0.s.qnq) {
1760                                         m->m_pkthdr.ether_vtag = vtag;
1761                                         m->m_flags |= M_VLANTAG;
1762                                 }
1763                         } else if (sc->pvid != (vtag & VLAN_VID_MASK))  {
1764                                 /* In UMC mode generally pvid will be striped by
1765                                    hw. But in some cases we have seen it comes
1766                                    with pvid. So if pvid == vlan, neglect vlan.
1767                                 */
1768                                 m->m_pkthdr.ether_vtag = vtag;
1769                                 m->m_flags |= M_VLANTAG;
1770                         }
1771                 }
1772
1773                 if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
1774 #if defined(INET6) || defined(INET)
1775                 /* Try to queue to LRO */
1776                 if (IF_LRO_ENABLED(sc) &&
1777                     (cqe->u0.s.ip_cksum_pass) &&
1778                     (cqe->u0.s.l4_cksum_pass) &&
1779                     (!cqe->u0.s.ip_ver)       &&
1780                     (rq->lro.lro_cnt != 0)) {
1781
1782                         if (tcp_lro_rx(&rq->lro, m, 0) == 0) {
1783                                 rq->lro_pkts_queued ++;         
1784                                 goto post_done;
1785                         }
1786                         /* If LRO posting fails then try to post to STACK */
1787                 }
1788 #endif
1789         
1790                 (*sc->ifp->if_input) (sc->ifp, m);
1791 #if defined(INET6) || defined(INET)
1792 post_done:
1793 #endif
1794                 /* Update rx stats per queue */
1795                 rq->rx_stats.rx_pkts++;
1796                 rq->rx_stats.rx_bytes += cqe->u0.s.pkt_size;
1797                 rq->rx_stats.rx_frags += cqe->u0.s.num_fragments;
1798                 if (cqe->u0.s.pkt_type == OCE_MULTICAST_PACKET)
1799                         rq->rx_stats.rx_mcast_pkts++;
1800                 if (cqe->u0.s.pkt_type == OCE_UNICAST_PACKET)
1801                         rq->rx_stats.rx_ucast_pkts++;
1802         }
1803 exit:
1804         return;
1805 }
1806
1807
1808 void
1809 oce_discard_rx_comp(struct oce_rq *rq, int num_frags)
1810 {
1811         uint32_t i = 0;
1812         struct oce_packet_desc *pd;
1813         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1814
1815         for (i = 0; i < num_frags; i++) {
1816                 if (rq->ring->cidx == rq->ring->pidx) {
1817                         device_printf(sc->dev,
1818                                 "oce_discard_rx_comp: Invalid RX completion - Queue is empty\n");
1819                         return;
1820                 }
1821                 pd = &rq->pckts[rq->ring->cidx];
1822                 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1823                 bus_dmamap_unload(rq->tag, pd->map);
1824                 if (pd->mbuf != NULL) {
1825                         m_freem(pd->mbuf);
1826                         pd->mbuf = NULL;
1827                 }
1828
1829                 RING_GET(rq->ring, 1);
1830                 rq->pending--;
1831         }
1832 }
1833
1834
1835 static int
1836 oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
1837 {
1838         struct oce_nic_rx_cqe_v1 *cqe_v1;
1839         int vtp = 0;
1840
1841         if (sc->be3_native) {
1842                 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1843                 vtp =  cqe_v1->u0.s.vlan_tag_present; 
1844         } else
1845                 vtp = cqe->u0.s.vlan_tag_present;
1846         
1847         return vtp;
1848
1849 }
1850
1851
1852 static int
1853 oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
1854 {
1855         struct oce_nic_rx_cqe_v1 *cqe_v1;
1856         int port_id = 0;
1857
1858         if (sc->be3_native && (IS_BE(sc) || IS_SH(sc))) {
1859                 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1860                 port_id =  cqe_v1->u0.s.port;
1861                 if (sc->port_id != port_id)
1862                         return 0;
1863         } else
1864                 ;/* For BE3 legacy and Lancer this is dummy */
1865         
1866         return 1;
1867
1868 }
1869
1870 #if defined(INET6) || defined(INET)
1871 void
1872 oce_rx_flush_lro(struct oce_rq *rq)
1873 {
1874         struct lro_ctrl *lro = &rq->lro;
1875         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1876
1877         if (!IF_LRO_ENABLED(sc))
1878                 return;
1879
1880         tcp_lro_flush_all(lro);
1881         rq->lro_pkts_queued = 0;
1882         
1883         return;
1884 }
1885
1886
1887 static int
1888 oce_init_lro(POCE_SOFTC sc)
1889 {
1890         struct lro_ctrl *lro = NULL;
1891         int i = 0, rc = 0;
1892
1893         for (i = 0; i < sc->nrqs; i++) { 
1894                 lro = &sc->rq[i]->lro;
1895                 rc = tcp_lro_init(lro);
1896                 if (rc != 0) {
1897                         device_printf(sc->dev, "LRO init failed\n");
1898                         return rc;              
1899                 }
1900                 lro->ifp = sc->ifp;
1901         }
1902
1903         return rc;              
1904 }
1905
1906
1907 void
1908 oce_free_lro(POCE_SOFTC sc)
1909 {
1910         struct lro_ctrl *lro = NULL;
1911         int i = 0;
1912
1913         for (i = 0; i < sc->nrqs; i++) {
1914                 lro = &sc->rq[i]->lro;
1915                 if (lro)
1916                         tcp_lro_free(lro);
1917         }
1918 }
1919 #endif
1920
1921 int
1922 oce_alloc_rx_bufs(struct oce_rq *rq, int count)
1923 {
1924         POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1925         int i, in, rc;
1926         struct oce_packet_desc *pd;
1927         bus_dma_segment_t segs[6];
1928         int nsegs, added = 0;
1929         struct oce_nic_rqe *rqe;
1930         pd_rxulp_db_t rxdb_reg;
1931         uint32_t val = 0;
1932         uint32_t oce_max_rq_posts = 64;
1933
1934         bzero(&rxdb_reg, sizeof(pd_rxulp_db_t));
1935         for (i = 0; i < count; i++) {
1936                 in = (rq->ring->pidx + 1) % OCE_RQ_PACKET_ARRAY_SIZE;
1937
1938                 pd = &rq->pckts[rq->ring->pidx];
1939                 pd->mbuf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, oce_rq_buf_size);
1940                 if (pd->mbuf == NULL) {
1941                         device_printf(sc->dev, "mbuf allocation failed, size = %d\n",oce_rq_buf_size);
1942                         break;
1943                 }
1944                 pd->mbuf->m_nextpkt = NULL;
1945
1946                 pd->mbuf->m_len = pd->mbuf->m_pkthdr.len = rq->cfg.frag_size;
1947
1948                 rc = bus_dmamap_load_mbuf_sg(rq->tag,
1949                                              pd->map,
1950                                              pd->mbuf,
1951                                              segs, &nsegs, BUS_DMA_NOWAIT);
1952                 if (rc) {
1953                         m_free(pd->mbuf);
1954                         device_printf(sc->dev, "bus_dmamap_load_mbuf_sg failed rc = %d\n", rc);
1955                         break;
1956                 }
1957
1958                 if (nsegs != 1) {
1959                         i--;
1960                         continue;
1961                 }
1962
1963                 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_PREREAD);
1964
1965                 rqe = RING_GET_PRODUCER_ITEM_VA(rq->ring, struct oce_nic_rqe);
1966                 rqe->u0.s.frag_pa_hi = ADDR_HI(segs[0].ds_addr);
1967                 rqe->u0.s.frag_pa_lo = ADDR_LO(segs[0].ds_addr);
1968                 DW_SWAP(u32ptr(rqe), sizeof(struct oce_nic_rqe));
1969                 RING_PUT(rq->ring, 1);
1970                 added++;
1971                 rq->pending++;
1972         }
1973         oce_max_rq_posts = sc->enable_hwlro ? OCE_HWLRO_MAX_RQ_POSTS : OCE_MAX_RQ_POSTS;
1974         if (added != 0) {
1975                 for (i = added / oce_max_rq_posts; i > 0; i--) {
1976                         rxdb_reg.bits.num_posted = oce_max_rq_posts;
1977                         rxdb_reg.bits.qid = rq->rq_id;
1978                         if(rq->islro) {
1979                                 val |= rq->rq_id & DB_LRO_RQ_ID_MASK;
1980                                 val |= oce_max_rq_posts << 16;
1981                                 OCE_WRITE_REG32(sc, db, DB_OFFSET, val);
1982                         }else {
1983                                 OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
1984                         }
1985                         added -= oce_max_rq_posts;
1986                 }
1987                 if (added > 0) {
1988                         rxdb_reg.bits.qid = rq->rq_id;
1989                         rxdb_reg.bits.num_posted = added;
1990                         if(rq->islro) {
1991                                 val |= rq->rq_id & DB_LRO_RQ_ID_MASK;
1992                                 val |= added << 16;
1993                                 OCE_WRITE_REG32(sc, db, DB_OFFSET, val);
1994                         }else {
1995                                 OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
1996                         }
1997                 }
1998         }
1999         
2000         return 0;       
2001 }
2002
2003 static void
2004 oce_check_rx_bufs(POCE_SOFTC sc, uint32_t num_cqes, struct oce_rq *rq)
2005 {
2006         if (num_cqes) {
2007                 oce_arm_cq(sc, rq->cq->cq_id, num_cqes, FALSE);
2008                 if(!sc->enable_hwlro) {
2009                         if((OCE_RQ_PACKET_ARRAY_SIZE - rq->pending) > 1)
2010                                 oce_alloc_rx_bufs(rq, ((OCE_RQ_PACKET_ARRAY_SIZE - rq->pending) - 1));
2011                 }else {
2012                         if ((OCE_RQ_PACKET_ARRAY_SIZE -1 - rq->pending) > 64)
2013                                 oce_alloc_rx_bufs(rq, 64);
2014                 }
2015         }
2016
2017         return;
2018 }
2019
2020 uint16_t
2021 oce_rq_handler_lro(void *arg)
2022 {
2023         struct oce_rq *rq = (struct oce_rq *)arg;
2024         struct oce_cq *cq = rq->cq;
2025         POCE_SOFTC sc = rq->parent;
2026         struct nic_hwlro_singleton_cqe *cqe;
2027         struct nic_hwlro_cqe_part2 *cqe2;
2028         int num_cqes = 0;
2029
2030         LOCK(&rq->rx_lock);
2031         bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2032         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe);
2033         while (cqe->valid) {
2034                 if(cqe->cqe_type == 0) { /* singleton cqe */
2035                         /* we should not get singleton cqe after cqe1 on same rq */
2036                         if(rq->cqe_firstpart != NULL) {
2037                                 device_printf(sc->dev, "Got singleton cqe after cqe1 \n");
2038                                 goto exit_rq_handler_lro;
2039                         }                                                       
2040                         if(cqe->error != 0) {
2041                                 rq->rx_stats.rxcp_err++;
2042                                 if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
2043                         }
2044                         oce_rx_lro(rq, cqe, NULL);
2045                         rq->rx_stats.rx_compl++;
2046                         cqe->valid = 0;
2047                         RING_GET(cq->ring, 1);
2048                         num_cqes++;
2049                         if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
2050                                 break;
2051                 }else if(cqe->cqe_type == 0x1) { /* first part */
2052                         /* we should not get cqe1 after cqe1 on same rq */
2053                         if(rq->cqe_firstpart != NULL) {
2054                                 device_printf(sc->dev, "Got cqe1 after cqe1 \n");
2055                                 goto exit_rq_handler_lro;
2056                         }
2057                         rq->cqe_firstpart = (struct nic_hwlro_cqe_part1 *)cqe;
2058                         RING_GET(cq->ring, 1);
2059                 }else if(cqe->cqe_type == 0x2) { /* second part */
2060                         cqe2 = (struct nic_hwlro_cqe_part2 *)cqe;
2061                         if(cqe2->error != 0) {
2062                                 rq->rx_stats.rxcp_err++;
2063                                 if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
2064                         }
2065                         /* We should not get cqe2 without cqe1 */
2066                         if(rq->cqe_firstpart == NULL) {
2067                                 device_printf(sc->dev, "Got cqe2 without cqe1 \n");
2068                                 goto exit_rq_handler_lro;
2069                         }
2070                         oce_rx_lro(rq, (struct nic_hwlro_singleton_cqe *)rq->cqe_firstpart, cqe2);
2071
2072                         rq->rx_stats.rx_compl++;
2073                         rq->cqe_firstpart->valid = 0;
2074                         cqe2->valid = 0;
2075                         rq->cqe_firstpart = NULL;
2076
2077                         RING_GET(cq->ring, 1);
2078                         num_cqes += 2;
2079                         if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
2080                                 break;
2081                 }
2082
2083                 bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2084                 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe);
2085         }
2086         oce_check_rx_bufs(sc, num_cqes, rq);
2087 exit_rq_handler_lro:
2088         UNLOCK(&rq->rx_lock);
2089         return 0;
2090 }
2091
2092 /* Handle the Completion Queue for receive */
2093 uint16_t
2094 oce_rq_handler(void *arg)
2095 {
2096         struct oce_rq *rq = (struct oce_rq *)arg;
2097         struct oce_cq *cq = rq->cq;
2098         POCE_SOFTC sc = rq->parent;
2099         struct oce_nic_rx_cqe *cqe;
2100         int num_cqes = 0;
2101
2102         if(rq->islro) {
2103                 oce_rq_handler_lro(arg);
2104                 return 0;
2105         }
2106         LOCK(&rq->rx_lock);
2107         bus_dmamap_sync(cq->ring->dma.tag,
2108                         cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2109         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
2110         while (cqe->u0.dw[2]) {
2111                 DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe));
2112
2113                 if (cqe->u0.s.error == 0) {
2114                         oce_rx(rq, cqe);
2115                 } else {
2116                         rq->rx_stats.rxcp_err++;
2117                         if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
2118                         /* Post L3/L4 errors to stack.*/
2119                         oce_rx(rq, cqe);
2120                 }
2121                 rq->rx_stats.rx_compl++;
2122                 cqe->u0.dw[2] = 0;
2123
2124 #if defined(INET6) || defined(INET)
2125                 if (IF_LRO_ENABLED(sc) && rq->lro_pkts_queued >= 16) {
2126                         oce_rx_flush_lro(rq);
2127                 }
2128 #endif
2129
2130                 RING_GET(cq->ring, 1);
2131                 bus_dmamap_sync(cq->ring->dma.tag,
2132                                 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2133                 cqe =
2134                     RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
2135                 num_cqes++;
2136                 if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
2137                         break;
2138         }
2139
2140 #if defined(INET6) || defined(INET)
2141         if (IF_LRO_ENABLED(sc))
2142                 oce_rx_flush_lro(rq);
2143 #endif
2144
2145         oce_check_rx_bufs(sc, num_cqes, rq);
2146         UNLOCK(&rq->rx_lock);
2147         return 0;
2148
2149 }
2150
2151
2152
2153
2154 /*****************************************************************************
2155  *                 Helper function prototypes in this file                   *
2156  *****************************************************************************/
2157
2158 static int 
2159 oce_attach_ifp(POCE_SOFTC sc)
2160 {
2161
2162         sc->ifp = if_alloc(IFT_ETHER);
2163         if (!sc->ifp)
2164                 return ENOMEM;
2165
2166         ifmedia_init(&sc->media, IFM_IMASK, oce_media_change, oce_media_status);
2167         ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
2168         ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
2169
2170         sc->ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
2171         sc->ifp->if_ioctl = oce_ioctl;
2172         sc->ifp->if_start = oce_start;
2173         sc->ifp->if_init = oce_init;
2174         sc->ifp->if_mtu = ETHERMTU;
2175         sc->ifp->if_softc = sc;
2176 #if __FreeBSD_version >= 800000
2177         sc->ifp->if_transmit = oce_multiq_start;
2178         sc->ifp->if_qflush = oce_multiq_flush;
2179 #endif
2180
2181         if_initname(sc->ifp,
2182                     device_get_name(sc->dev), device_get_unit(sc->dev));
2183
2184         sc->ifp->if_snd.ifq_drv_maxlen = OCE_MAX_TX_DESC - 1;
2185         IFQ_SET_MAXLEN(&sc->ifp->if_snd, sc->ifp->if_snd.ifq_drv_maxlen);
2186         IFQ_SET_READY(&sc->ifp->if_snd);
2187
2188         sc->ifp->if_hwassist = OCE_IF_HWASSIST;
2189         sc->ifp->if_hwassist |= CSUM_TSO;
2190         sc->ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP);
2191
2192         sc->ifp->if_capabilities = OCE_IF_CAPABILITIES;
2193         sc->ifp->if_capabilities |= IFCAP_HWCSUM;
2194         sc->ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
2195
2196 #if defined(INET6) || defined(INET)
2197         sc->ifp->if_capabilities |= IFCAP_TSO;
2198         sc->ifp->if_capabilities |= IFCAP_LRO;
2199         sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
2200 #endif
2201         
2202         sc->ifp->if_capenable = sc->ifp->if_capabilities;
2203         sc->ifp->if_baudrate = IF_Gbps(10);
2204
2205 #if __FreeBSD_version >= 1000000
2206         sc->ifp->if_hw_tsomax = 65536 - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
2207         sc->ifp->if_hw_tsomaxsegcount = OCE_MAX_TX_ELEMENTS;
2208         sc->ifp->if_hw_tsomaxsegsize = 4096;
2209 #endif
2210
2211         ether_ifattach(sc->ifp, sc->macaddr.mac_addr);
2212         
2213         return 0;
2214 }
2215
2216
2217 static void
2218 oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
2219 {
2220         POCE_SOFTC sc = ifp->if_softc;
2221
2222         if (ifp->if_softc !=  arg)
2223                 return;
2224         if ((vtag == 0) || (vtag > 4095))
2225                 return;
2226
2227         sc->vlan_tag[vtag] = 1;
2228         sc->vlans_added++;
2229         if (sc->vlans_added <= (sc->max_vlans + 1))
2230                 oce_vid_config(sc);
2231 }
2232
2233
2234 static void
2235 oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
2236 {
2237         POCE_SOFTC sc = ifp->if_softc;
2238
2239         if (ifp->if_softc !=  arg)
2240                 return;
2241         if ((vtag == 0) || (vtag > 4095))
2242                 return;
2243
2244         sc->vlan_tag[vtag] = 0;
2245         sc->vlans_added--;
2246         oce_vid_config(sc);
2247 }
2248
2249
2250 /*
2251  * A max of 64 vlans can be configured in BE. If the user configures
2252  * more, place the card in vlan promiscuous mode.
2253  */
2254 static int
2255 oce_vid_config(POCE_SOFTC sc)
2256 {
2257         struct normal_vlan vtags[MAX_VLANFILTER_SIZE];
2258         uint16_t ntags = 0, i;
2259         int status = 0;
2260
2261         if ((sc->vlans_added <= MAX_VLANFILTER_SIZE) && 
2262                         (sc->ifp->if_capenable & IFCAP_VLAN_HWFILTER)) {
2263                 for (i = 0; i < MAX_VLANS; i++) {
2264                         if (sc->vlan_tag[i]) {
2265                                 vtags[ntags].vtag = i;
2266                                 ntags++;
2267                         }
2268                 }
2269                 if (ntags)
2270                         status = oce_config_vlan(sc, (uint8_t) sc->if_id,
2271                                                 vtags, ntags, 1, 0); 
2272         } else 
2273                 status = oce_config_vlan(sc, (uint8_t) sc->if_id,
2274                                                 NULL, 0, 1, 1);
2275         return status;
2276 }
2277
2278
2279 static void
2280 oce_mac_addr_set(POCE_SOFTC sc)
2281 {
2282         uint32_t old_pmac_id = sc->pmac_id;
2283         int status = 0;
2284
2285         
2286         status = bcmp((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
2287                          sc->macaddr.size_of_struct);
2288         if (!status)
2289                 return;
2290
2291         status = oce_mbox_macaddr_add(sc, (uint8_t *)(IF_LLADDR(sc->ifp)),
2292                                         sc->if_id, &sc->pmac_id);
2293         if (!status) {
2294                 status = oce_mbox_macaddr_del(sc, sc->if_id, old_pmac_id);
2295                 bcopy((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
2296                                  sc->macaddr.size_of_struct); 
2297         }
2298         if (status)
2299                 device_printf(sc->dev, "Failed update macaddress\n");
2300
2301 }
2302
2303
2304 static int
2305 oce_handle_passthrough(struct ifnet *ifp, caddr_t data)
2306 {
2307         POCE_SOFTC sc = ifp->if_softc;
2308         struct ifreq *ifr = (struct ifreq *)data;
2309         int rc = ENXIO;
2310         char cookie[32] = {0};
2311         void *priv_data = ifr_data_get_ptr(ifr);
2312         void *ioctl_ptr;
2313         uint32_t req_size;
2314         struct mbx_hdr req;
2315         OCE_DMA_MEM dma_mem;
2316         struct mbx_common_get_cntl_attr *fw_cmd;
2317
2318         if (copyin(priv_data, cookie, strlen(IOCTL_COOKIE)))
2319                 return EFAULT;
2320
2321         if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE)))
2322                 return EINVAL;
2323
2324         ioctl_ptr = (char *)priv_data + strlen(IOCTL_COOKIE);
2325         if (copyin(ioctl_ptr, &req, sizeof(struct mbx_hdr)))
2326                 return EFAULT;
2327
2328         req_size = le32toh(req.u0.req.request_length);
2329         if (req_size > 65536)
2330                 return EINVAL;
2331
2332         req_size += sizeof(struct mbx_hdr);
2333         rc = oce_dma_alloc(sc, req_size, &dma_mem, 0);
2334         if (rc)
2335                 return ENOMEM;
2336
2337         if (copyin(ioctl_ptr, OCE_DMAPTR(&dma_mem,char), req_size)) {
2338                 rc = EFAULT;
2339                 goto dma_free;
2340         }
2341
2342         rc = oce_pass_through_mbox(sc, &dma_mem, req_size);
2343         if (rc) {
2344                 rc = EIO;
2345                 goto dma_free;
2346         }
2347
2348         if (copyout(OCE_DMAPTR(&dma_mem,char), ioctl_ptr, req_size))
2349                 rc =  EFAULT;
2350
2351         /* 
2352            firmware is filling all the attributes for this ioctl except
2353            the driver version..so fill it 
2354          */
2355         if(req.u0.rsp.opcode == OPCODE_COMMON_GET_CNTL_ATTRIBUTES) {
2356                 fw_cmd = (struct mbx_common_get_cntl_attr *) ioctl_ptr;
2357                 strncpy(fw_cmd->params.rsp.cntl_attr_info.hba_attr.drv_ver_str,
2358                         COMPONENT_REVISION, strlen(COMPONENT_REVISION));        
2359         }
2360
2361 dma_free:
2362         oce_dma_free(sc, &dma_mem);
2363         return rc;
2364
2365 }
2366
2367 static void
2368 oce_eqd_set_periodic(POCE_SOFTC sc)
2369 {
2370         struct oce_set_eqd set_eqd[OCE_MAX_EQ];
2371         struct oce_aic_obj *aic;
2372         struct oce_eq *eqo;
2373         uint64_t now = 0, delta;
2374         int eqd, i, num = 0;
2375         uint32_t tx_reqs = 0, rxpkts = 0, pps;
2376         struct oce_wq *wq;
2377         struct oce_rq *rq;
2378
2379         #define ticks_to_msecs(t)       (1000 * (t) / hz)
2380
2381         for (i = 0 ; i < sc->neqs; i++) {
2382                 eqo = sc->eq[i];
2383                 aic = &sc->aic_obj[i];
2384                 /* When setting the static eq delay from the user space */
2385                 if (!aic->enable) {
2386                         if (aic->ticks)
2387                                 aic->ticks = 0;
2388                         eqd = aic->et_eqd;
2389                         goto modify_eqd;
2390                 }
2391
2392                 rq = sc->rq[i];
2393                 rxpkts = rq->rx_stats.rx_pkts;
2394                 wq = sc->wq[i];
2395                 tx_reqs = wq->tx_stats.tx_reqs;
2396                 now = ticks;
2397
2398                 if (!aic->ticks || now < aic->ticks ||
2399                     rxpkts < aic->prev_rxpkts || tx_reqs < aic->prev_txreqs) {
2400                         aic->prev_rxpkts = rxpkts;
2401                         aic->prev_txreqs = tx_reqs;
2402                         aic->ticks = now;
2403                         continue;
2404                 }
2405
2406                 delta = ticks_to_msecs(now - aic->ticks);
2407
2408                 pps = (((uint32_t)(rxpkts - aic->prev_rxpkts) * 1000) / delta) +
2409                       (((uint32_t)(tx_reqs - aic->prev_txreqs) * 1000) / delta);
2410                 eqd = (pps / 15000) << 2;
2411                 if (eqd < 8)
2412                         eqd = 0;
2413
2414                 /* Make sure that the eq delay is in the known range */
2415                 eqd = min(eqd, aic->max_eqd);
2416                 eqd = max(eqd, aic->min_eqd);
2417
2418                 aic->prev_rxpkts = rxpkts;
2419                 aic->prev_txreqs = tx_reqs;
2420                 aic->ticks = now;
2421
2422 modify_eqd:
2423                 if (eqd != aic->cur_eqd) {
2424                         set_eqd[num].delay_multiplier = (eqd * 65)/100;
2425                         set_eqd[num].eq_id = eqo->eq_id;
2426                         aic->cur_eqd = eqd;
2427                         num++;
2428                 }
2429         }
2430
2431         /* Is there atleast one eq that needs to be modified? */
2432         for(i = 0; i < num; i += 8) {
2433                 if((num - i) >=8 )
2434                         oce_mbox_eqd_modify_periodic(sc, &set_eqd[i], 8);
2435                 else
2436                         oce_mbox_eqd_modify_periodic(sc, &set_eqd[i], (num - i));
2437         }
2438
2439 }
2440
2441 static void oce_detect_hw_error(POCE_SOFTC sc)
2442 {
2443
2444         uint32_t ue_low = 0, ue_high = 0, ue_low_mask = 0, ue_high_mask = 0;
2445         uint32_t sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
2446         uint32_t i;
2447
2448         if (sc->hw_error)
2449                 return;
2450
2451         if (IS_XE201(sc)) {
2452                 sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET);
2453                 if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2454                         sliport_err1 = OCE_READ_REG32(sc, db, SLIPORT_ERROR1_OFFSET);
2455                         sliport_err2 = OCE_READ_REG32(sc, db, SLIPORT_ERROR2_OFFSET);
2456                 }
2457         } else {
2458                 ue_low = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW);
2459                 ue_high = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HIGH);
2460                 ue_low_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW_MASK);
2461                 ue_high_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HI_MASK);
2462
2463                 ue_low = (ue_low & ~ue_low_mask);
2464                 ue_high = (ue_high & ~ue_high_mask);
2465         }
2466
2467         /* On certain platforms BE hardware can indicate spurious UEs.
2468          * Allow the h/w to stop working completely in case of a real UE.
2469          * Hence not setting the hw_error for UE detection.
2470          */
2471         if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2472                 sc->hw_error = TRUE;
2473                 device_printf(sc->dev, "Error detected in the card\n");
2474         }
2475
2476         if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
2477                 device_printf(sc->dev,
2478                                 "ERR: sliport status 0x%x\n", sliport_status);
2479                 device_printf(sc->dev,
2480                                 "ERR: sliport error1 0x%x\n", sliport_err1);
2481                 device_printf(sc->dev,
2482                                 "ERR: sliport error2 0x%x\n", sliport_err2);
2483         }
2484
2485         if (ue_low) {
2486                 for (i = 0; ue_low; ue_low >>= 1, i++) {
2487                         if (ue_low & 1)
2488                                 device_printf(sc->dev, "UE: %s bit set\n",
2489                                                         ue_status_low_desc[i]);
2490                 }
2491         }
2492
2493         if (ue_high) {
2494                 for (i = 0; ue_high; ue_high >>= 1, i++) {
2495                         if (ue_high & 1)
2496                                 device_printf(sc->dev, "UE: %s bit set\n",
2497                                                         ue_status_hi_desc[i]);
2498                 }
2499         }
2500
2501 }
2502
2503
2504 static void
2505 oce_local_timer(void *arg)
2506 {
2507         POCE_SOFTC sc = arg;
2508         int i = 0;
2509         
2510         oce_detect_hw_error(sc);
2511         oce_refresh_nic_stats(sc);
2512         oce_refresh_queue_stats(sc);
2513         oce_mac_addr_set(sc);
2514         
2515         /* TX Watch Dog*/
2516         for (i = 0; i < sc->nwqs; i++)
2517                 oce_tx_restart(sc, sc->wq[i]);
2518         
2519         /* calculate and set the eq delay for optimal interrupt rate */
2520         if (IS_BE(sc) || IS_SH(sc))
2521                 oce_eqd_set_periodic(sc);
2522
2523         callout_reset(&sc->timer, hz, oce_local_timer, sc);
2524 }
2525
2526 static void 
2527 oce_tx_compl_clean(POCE_SOFTC sc) 
2528 {
2529         struct oce_wq *wq;
2530         int i = 0, timeo = 0, num_wqes = 0;
2531         int pending_txqs = sc->nwqs;
2532
2533         /* Stop polling for compls when HW has been silent for 10ms or 
2534          * hw_error or no outstanding completions expected
2535          */
2536         do {
2537                 pending_txqs = sc->nwqs;
2538                 
2539                 for_all_wq_queues(sc, wq, i) {
2540                         num_wqes = oce_wq_handler(wq);
2541                         
2542                         if(num_wqes)
2543                                 timeo = 0;
2544
2545                         if(!wq->ring->num_used)
2546                                 pending_txqs--;
2547                 }
2548
2549                 if (pending_txqs == 0 || ++timeo > 10 || sc->hw_error)
2550                         break;
2551
2552                 DELAY(1000);
2553         } while (TRUE);
2554
2555         for_all_wq_queues(sc, wq, i) {
2556                 while(wq->ring->num_used) {
2557                         LOCK(&wq->tx_compl_lock);
2558                         oce_process_tx_completion(wq);
2559                         UNLOCK(&wq->tx_compl_lock);
2560                 }
2561         }       
2562                 
2563 }
2564
2565 /* NOTE : This should only be called holding
2566  *        DEVICE_LOCK.
2567  */
2568 static void
2569 oce_if_deactivate(POCE_SOFTC sc)
2570 {
2571         int i;
2572         struct oce_rq *rq;
2573         struct oce_wq *wq;
2574         struct oce_eq *eq;
2575
2576         sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
2577
2578         oce_tx_compl_clean(sc);
2579
2580         /* Stop intrs and finish any bottom halves pending */
2581         oce_hw_intr_disable(sc);
2582
2583         /* Since taskqueue_drain takes a Gaint Lock, We should not acquire
2584            any other lock. So unlock device lock and require after
2585            completing taskqueue_drain.
2586         */
2587         UNLOCK(&sc->dev_lock);
2588         for (i = 0; i < sc->intr_count; i++) {
2589                 if (sc->intrs[i].tq != NULL) {
2590                         taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task);
2591                 }
2592         }
2593         LOCK(&sc->dev_lock);
2594
2595         /* Delete RX queue in card with flush param */
2596         oce_stop_rx(sc);
2597
2598         /* Invalidate any pending cq and eq entries*/   
2599         for_all_evnt_queues(sc, eq, i)  
2600                 oce_drain_eq(eq);
2601         for_all_rq_queues(sc, rq, i)
2602                 oce_drain_rq_cq(rq);
2603         for_all_wq_queues(sc, wq, i)
2604                 oce_drain_wq_cq(wq);
2605
2606         /* But still we need to get MCC aync events.
2607            So enable intrs and also arm first EQ
2608         */
2609         oce_hw_intr_enable(sc);
2610         oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
2611
2612         DELAY(10);
2613 }
2614
2615
2616 static void
2617 oce_if_activate(POCE_SOFTC sc)
2618 {
2619         struct oce_eq *eq;
2620         struct oce_rq *rq;
2621         struct oce_wq *wq;
2622         int i, rc = 0;
2623
2624         sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; 
2625         
2626         oce_hw_intr_disable(sc);
2627         
2628         oce_start_rx(sc);
2629
2630         for_all_rq_queues(sc, rq, i) {
2631                 rc = oce_start_rq(rq);
2632                 if (rc)
2633                         device_printf(sc->dev, "Unable to start RX\n");
2634         }
2635
2636         for_all_wq_queues(sc, wq, i) {
2637                 rc = oce_start_wq(wq);
2638                 if (rc)
2639                         device_printf(sc->dev, "Unable to start TX\n");
2640         }
2641
2642         
2643         for_all_evnt_queues(sc, eq, i)
2644                 oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
2645
2646         oce_hw_intr_enable(sc);
2647
2648 }
2649
2650 static void
2651 process_link_state(POCE_SOFTC sc, struct oce_async_cqe_link_state *acqe)
2652 {
2653         /* Update Link status */
2654         if ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) ==
2655              ASYNC_EVENT_LINK_UP) {
2656                 sc->link_status = ASYNC_EVENT_LINK_UP;
2657                 if_link_state_change(sc->ifp, LINK_STATE_UP);
2658         } else {
2659                 sc->link_status = ASYNC_EVENT_LINK_DOWN;
2660                 if_link_state_change(sc->ifp, LINK_STATE_DOWN);
2661         }
2662 }
2663
2664
2665 static void oce_async_grp5_osbmc_process(POCE_SOFTC sc,
2666                                          struct oce_async_evt_grp5_os2bmc *evt)
2667 {
2668         DW_SWAP(evt, sizeof(struct oce_async_evt_grp5_os2bmc));
2669         if (evt->u.s.mgmt_enable)
2670                 sc->flags |= OCE_FLAGS_OS2BMC;
2671         else
2672                 return;
2673
2674         sc->bmc_filt_mask = evt->u.s.arp_filter;
2675         sc->bmc_filt_mask |= (evt->u.s.dhcp_client_filt << 1);
2676         sc->bmc_filt_mask |= (evt->u.s.dhcp_server_filt << 2);
2677         sc->bmc_filt_mask |= (evt->u.s.net_bios_filt << 3);
2678         sc->bmc_filt_mask |= (evt->u.s.bcast_filt << 4);
2679         sc->bmc_filt_mask |= (evt->u.s.ipv6_nbr_filt << 5);
2680         sc->bmc_filt_mask |= (evt->u.s.ipv6_ra_filt << 6);
2681         sc->bmc_filt_mask |= (evt->u.s.ipv6_ras_filt << 7);
2682         sc->bmc_filt_mask |= (evt->u.s.mcast_filt << 8);
2683 }
2684
2685
2686 static void oce_process_grp5_events(POCE_SOFTC sc, struct oce_mq_cqe *cqe)
2687 {
2688         struct oce_async_event_grp5_pvid_state *gcqe;
2689         struct oce_async_evt_grp5_os2bmc *bmccqe;
2690
2691         switch (cqe->u0.s.async_type) {
2692         case ASYNC_EVENT_PVID_STATE:
2693                 /* GRP5 PVID */
2694                 gcqe = (struct oce_async_event_grp5_pvid_state *)cqe;
2695                 if (gcqe->enabled)
2696                         sc->pvid = gcqe->tag & VLAN_VID_MASK;
2697                 else
2698                         sc->pvid = 0;
2699                 break;
2700         case ASYNC_EVENT_OS2BMC:
2701                 bmccqe = (struct oce_async_evt_grp5_os2bmc *)cqe;
2702                 oce_async_grp5_osbmc_process(sc, bmccqe);
2703                 break;
2704         default:
2705                 break;
2706         }
2707 }
2708
2709 /* Handle the Completion Queue for the Mailbox/Async notifications */
2710 uint16_t
2711 oce_mq_handler(void *arg)
2712 {
2713         struct oce_mq *mq = (struct oce_mq *)arg;
2714         POCE_SOFTC sc = mq->parent;
2715         struct oce_cq *cq = mq->cq;
2716         int num_cqes = 0, evt_type = 0, optype = 0;
2717         struct oce_mq_cqe *cqe;
2718         struct oce_async_cqe_link_state *acqe;
2719         struct oce_async_event_qnq *dbgcqe;
2720
2721
2722         bus_dmamap_sync(cq->ring->dma.tag,
2723                         cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2724         cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
2725
2726         while (cqe->u0.dw[3]) {
2727                 DW_SWAP((uint32_t *) cqe, sizeof(oce_mq_cqe));
2728                 if (cqe->u0.s.async_event) {
2729                         evt_type = cqe->u0.s.event_type;
2730                         optype = cqe->u0.s.async_type;
2731                         if (evt_type  == ASYNC_EVENT_CODE_LINK_STATE) {
2732                                 /* Link status evt */
2733                                 acqe = (struct oce_async_cqe_link_state *)cqe;
2734                                 process_link_state(sc, acqe);
2735                         } else if (evt_type == ASYNC_EVENT_GRP5) {
2736                                 oce_process_grp5_events(sc, cqe);
2737                         } else if (evt_type == ASYNC_EVENT_CODE_DEBUG &&
2738                                         optype == ASYNC_EVENT_DEBUG_QNQ) {
2739                                 dbgcqe =  (struct oce_async_event_qnq *)cqe;
2740                                 if(dbgcqe->valid)
2741                                         sc->qnqid = dbgcqe->vlan_tag;
2742                                 sc->qnq_debug_event = TRUE;
2743                         }
2744                 }
2745                 cqe->u0.dw[3] = 0;
2746                 RING_GET(cq->ring, 1);
2747                 bus_dmamap_sync(cq->ring->dma.tag,
2748                                 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2749                 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
2750                 num_cqes++;
2751         }
2752
2753         if (num_cqes)
2754                 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
2755
2756         return 0;
2757 }
2758
2759
2760 static void
2761 setup_max_queues_want(POCE_SOFTC sc)
2762 {
2763         /* Check if it is FLEX machine. Is so dont use RSS */   
2764         if ((sc->function_mode & FNM_FLEX10_MODE) ||
2765             (sc->function_mode & FNM_UMC_MODE)    ||
2766             (sc->function_mode & FNM_VNIC_MODE)   ||
2767             (!is_rss_enabled(sc))                 ||
2768             IS_BE2(sc)) {
2769                 sc->nrqs = 1;
2770                 sc->nwqs = 1;
2771         } else {
2772                 sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1;
2773                 sc->nwqs = MIN(OCE_NCPUS, sc->nrssqs);
2774         }
2775
2776         if (IS_BE2(sc) && is_rss_enabled(sc))
2777                 sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1;
2778 }
2779
2780
2781 static void
2782 update_queues_got(POCE_SOFTC sc)
2783 {
2784         if (is_rss_enabled(sc)) {
2785                 sc->nrqs = sc->intr_count + 1;
2786                 sc->nwqs = sc->intr_count;
2787         } else {
2788                 sc->nrqs = 1;
2789                 sc->nwqs = 1;
2790         }
2791
2792         if (IS_BE2(sc))
2793                 sc->nwqs = 1;
2794 }
2795
2796 static int 
2797 oce_check_ipv6_ext_hdr(struct mbuf *m)
2798 {
2799         struct ether_header *eh = mtod(m, struct ether_header *);
2800         caddr_t m_datatemp = m->m_data;
2801
2802         if (eh->ether_type == htons(ETHERTYPE_IPV6)) {
2803                 m->m_data += sizeof(struct ether_header);
2804                 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
2805
2806                 if((ip6->ip6_nxt != IPPROTO_TCP) && \
2807                                 (ip6->ip6_nxt != IPPROTO_UDP)){
2808                         struct ip6_ext *ip6e = NULL;
2809                         m->m_data += sizeof(struct ip6_hdr);
2810
2811                         ip6e = (struct ip6_ext *) mtod(m, struct ip6_ext *);
2812                         if(ip6e->ip6e_len == 0xff) {
2813                                 m->m_data = m_datatemp;
2814                                 return TRUE;
2815                         }
2816                 } 
2817                 m->m_data = m_datatemp;
2818         }
2819         return FALSE;
2820 }
2821
2822 static int 
2823 is_be3_a1(POCE_SOFTC sc)
2824 {
2825         if((sc->flags & OCE_FLAGS_BE3)  && ((sc->asic_revision & 0xFF) < 2)) {
2826                 return TRUE;
2827         }
2828         return FALSE;
2829 }
2830
2831 static struct mbuf *
2832 oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete)
2833 {
2834         uint16_t vlan_tag = 0;
2835
2836         if(!M_WRITABLE(m))
2837                 return NULL;
2838
2839         /* Embed vlan tag in the packet if it is not part of it */
2840         if(m->m_flags & M_VLANTAG) {
2841                 vlan_tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
2842                 m->m_flags &= ~M_VLANTAG;
2843         }
2844
2845         /* if UMC, ignore vlan tag insertion and instead insert pvid */
2846         if(sc->pvid) {
2847                 if(!vlan_tag)
2848                         vlan_tag = sc->pvid;
2849                 if (complete)
2850                         *complete = FALSE;
2851         }
2852
2853         if(vlan_tag) {
2854                 m = ether_vlanencap(m, vlan_tag);
2855         }
2856
2857         if(sc->qnqid) {
2858                 m = ether_vlanencap(m, sc->qnqid);
2859
2860                 if (complete)
2861                         *complete = FALSE;
2862         }
2863         return m;
2864 }
2865
2866 static int 
2867 oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m)
2868 {
2869         if(is_be3_a1(sc) && IS_QNQ_OR_UMC(sc) && \
2870                         oce_check_ipv6_ext_hdr(m)) {
2871                 return TRUE;
2872         }
2873         return FALSE;
2874 }
2875
2876 static void
2877 oce_get_config(POCE_SOFTC sc)
2878 {
2879         int rc = 0;
2880         uint32_t max_rss = 0;
2881
2882         if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
2883                 max_rss = OCE_LEGACY_MODE_RSS;
2884         else
2885                 max_rss = OCE_MAX_RSS;
2886
2887         if (!IS_BE(sc)) {
2888                 rc = oce_get_profile_config(sc, max_rss);
2889                 if (rc) {
2890                         sc->nwqs = OCE_MAX_WQ;
2891                         sc->nrssqs = max_rss;
2892                         sc->nrqs = sc->nrssqs + 1;
2893                 }
2894         }
2895         else { /* For BE3 don't rely on fw for determining the resources */
2896                 sc->nrssqs = max_rss;
2897                 sc->nrqs = sc->nrssqs + 1;
2898                 sc->nwqs = OCE_MAX_WQ;
2899                 sc->max_vlans = MAX_VLANFILTER_SIZE; 
2900         }
2901 }
2902
2903 static void
2904 oce_rdma_close(void)
2905 {
2906   if (oce_rdma_if != NULL) {
2907     oce_rdma_if = NULL;
2908   }
2909 }
2910
2911 static void
2912 oce_get_mac_addr(POCE_SOFTC sc, uint8_t *macaddr)
2913 {
2914   memcpy(macaddr, sc->macaddr.mac_addr, 6);
2915 }
2916
2917 int
2918 oce_register_rdma(POCE_RDMA_INFO rdma_info, POCE_RDMA_IF rdma_if)
2919 {
2920   POCE_SOFTC sc;
2921   struct oce_dev_info di;
2922   int i;
2923
2924   if ((rdma_info == NULL) || (rdma_if == NULL)) {
2925     return -EINVAL;
2926   }
2927
2928   if ((rdma_info->size != OCE_RDMA_INFO_SIZE) ||
2929       (rdma_if->size != OCE_RDMA_IF_SIZE)) {
2930     return -ENXIO;
2931   }
2932
2933   rdma_info->close = oce_rdma_close;
2934   rdma_info->mbox_post = oce_mbox_post;
2935   rdma_info->common_req_hdr_init = mbx_common_req_hdr_init;
2936   rdma_info->get_mac_addr = oce_get_mac_addr;
2937
2938   oce_rdma_if = rdma_if;
2939
2940   sc = softc_head;
2941   while (sc != NULL) {
2942     if (oce_rdma_if->announce != NULL) {
2943       memset(&di, 0, sizeof(di));
2944       di.dev = sc->dev;
2945       di.softc = sc;
2946       di.ifp = sc->ifp;
2947       di.db_bhandle = sc->db_bhandle;
2948       di.db_btag = sc->db_btag;
2949       di.db_page_size = 4096;
2950       if (sc->flags & OCE_FLAGS_USING_MSIX) {
2951         di.intr_mode = OCE_INTERRUPT_MODE_MSIX;
2952       } else if (sc->flags & OCE_FLAGS_USING_MSI) {
2953         di.intr_mode = OCE_INTERRUPT_MODE_MSI;
2954       } else {
2955         di.intr_mode = OCE_INTERRUPT_MODE_INTX;
2956       }
2957       di.dev_family = OCE_GEN2_FAMILY; // fixme: must detect skyhawk
2958       if (di.intr_mode != OCE_INTERRUPT_MODE_INTX) {
2959         di.msix.num_vectors = sc->intr_count + sc->roce_intr_count;
2960         di.msix.start_vector = sc->intr_count;
2961         for (i=0; i<di.msix.num_vectors; i++) {
2962           di.msix.vector_list[i] = sc->intrs[i].vector;
2963         }
2964       } else {
2965       }
2966       memcpy(di.mac_addr, sc->macaddr.mac_addr, 6);
2967       di.vendor_id = pci_get_vendor(sc->dev);
2968       di.dev_id = pci_get_device(sc->dev);
2969
2970       if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) {
2971           di.flags  |= OCE_RDMA_INFO_RDMA_SUPPORTED;
2972       }
2973
2974       rdma_if->announce(&di);
2975       sc = sc->next;
2976     }
2977   }
2978
2979   return 0;
2980 }
2981
2982 static void
2983 oce_read_env_variables( POCE_SOFTC sc )
2984 {
2985         char *value = NULL;
2986         int rc = 0;
2987
2988         /* read if user wants to enable hwlro or swlro */
2989         //value = getenv("oce_enable_hwlro");
2990         if(value && IS_SH(sc)) {
2991                 sc->enable_hwlro = strtol(value, NULL, 10);
2992                 if(sc->enable_hwlro) {
2993                         rc = oce_mbox_nic_query_lro_capabilities(sc, NULL, NULL);
2994                         if(rc) {
2995                                 device_printf(sc->dev, "no hardware lro support\n");
2996                                 device_printf(sc->dev, "software lro enabled\n");
2997                                 sc->enable_hwlro = 0;
2998                         }else {
2999                                 device_printf(sc->dev, "hardware lro enabled\n");
3000                                 oce_max_rsp_handled = 32;
3001                         }
3002                 }else {
3003                         device_printf(sc->dev, "software lro enabled\n");
3004                 }
3005         }else {
3006                 sc->enable_hwlro = 0;
3007         }
3008
3009         /* read mbuf size */
3010         //value = getenv("oce_rq_buf_size");
3011         if(value && IS_SH(sc)) {
3012                 oce_rq_buf_size = strtol(value, NULL, 10);
3013                 switch(oce_rq_buf_size) {
3014                 case 2048:
3015                 case 4096:
3016                 case 9216:
3017                 case 16384:
3018                         break;
3019
3020                 default:
3021                         device_printf(sc->dev, " Supported oce_rq_buf_size values are 2K, 4K, 9K, 16K \n");
3022                         oce_rq_buf_size = 2048;
3023                 }
3024         }
3025
3026         return;
3027 }