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
40 /* $FreeBSD: src/sys/dev/oce/oce_if.c,v 1.14 2013/07/07 00:30:13 svnexp Exp $ */
41
42 #include "opt_inet6.h"
43 #include "opt_inet.h"
44
45 #include "oce_if.h"
46
47
48 /* Driver entry points prototypes */
49 static int oce_probe(device_t dev);
50 static int oce_attach(device_t dev);
51 static int oce_detach(device_t dev);
52 static int oce_shutdown(device_t dev);
53 static int oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr);
54 static void oce_init(void *xsc);
55 #if 0 /* XXX swildner: MULTIQUEUE */
56 static int oce_multiq_start(struct ifnet *ifp, struct mbuf *m);
57 static void oce_multiq_flush(struct ifnet *ifp);
58 #endif
59
60 /* Driver interrupt routines protypes */
61 static void oce_intr(void *arg, int pending);
62 static int oce_setup_intr(POCE_SOFTC sc);
63 static void oce_fast_isr(void *arg);
64 static int oce_alloc_intr(POCE_SOFTC sc, int vector,
65 void (*isr) (void *arg, int pending));
66
67 /* Media callbacks prototypes */
68 static void oce_media_status(struct ifnet *ifp, struct ifmediareq *req);
69 static int oce_media_change(struct ifnet *ifp);
70
71 /* Transmit routines prototypes */
72 static int oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index);
73 static void oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq);
74 static void oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx,
75 uint32_t status);
76 #if 0 /* XXX swildner: MULTIQUEUE */
77 static int oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m,
78 struct oce_wq *wq);
79 #endif
80
81 /* Receive routines prototypes */
82 static void oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe);
83 #if 0 /* XXX swildner: ETHER_VTAG */
84 static int oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
85 #endif
86 static int oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
87 static void oce_rx(struct oce_rq *rq, uint32_t rqe_idx,
88 struct oce_nic_rx_cqe *cqe);
89
90 /* Helper function prototypes in this file */
91 static int oce_attach_ifp(POCE_SOFTC sc);
92 static void oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag);
93 static void oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag);
94 static int oce_vid_config(POCE_SOFTC sc);
95 static void oce_mac_addr_set(POCE_SOFTC sc);
96 static int oce_handle_passthrough(struct ifnet *ifp, caddr_t data);
97 static void oce_local_timer(void *arg);
98 static void oce_if_deactivate(POCE_SOFTC sc);
99 static void oce_if_activate(POCE_SOFTC sc);
100 static void setup_max_queues_want(POCE_SOFTC sc);
101 static void update_queues_got(POCE_SOFTC sc);
102 static void process_link_state(POCE_SOFTC sc,
103 struct oce_async_cqe_link_state *acqe);
104 static int oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m);
105 static void oce_get_config(POCE_SOFTC sc);
106 static struct mbuf *oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete);
107
108 /* IP specific */
109 #if defined(INET6) || defined(INET)
110 #if 0 /* XXX swildner: LRO */
111 static int oce_init_lro(POCE_SOFTC sc);
112 static void oce_rx_flush_lro(struct oce_rq *rq);
113 #endif
114 static struct mbuf * oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp);
115 #endif
116
117 static device_method_t oce_dispatch[] = {
118 DEVMETHOD(device_probe, oce_probe),
119 DEVMETHOD(device_attach, oce_attach),
120 DEVMETHOD(device_detach, oce_detach),
121 DEVMETHOD(device_shutdown, oce_shutdown),
122
123 DEVMETHOD_END
124 };
125
126 static driver_t oce_driver = {
127 "oce",
128 oce_dispatch,
129 sizeof(OCE_SOFTC)
130 };
131 static devclass_t oce_devclass;
132
133
134 DRIVER_MODULE(oce, pci, oce_driver, oce_devclass, NULL, NULL);
135 MODULE_DEPEND(oce, pci, 1, 1, 1);
136 MODULE_DEPEND(oce, ether, 1, 1, 1);
137 MODULE_VERSION(oce, 1);
138
139
140 /* global vars */
141 const char component_revision[32] = {"///" COMPONENT_REVISION "///"};
142
143 /* Module capabilites and parameters */
144 uint32_t oce_max_rsp_handled = OCE_MAX_RSP_HANDLED;
145 #if 0 /* XXX swildner: RSS */
146 uint32_t oce_enable_rss = OCE_MODCAP_RSS;
147 #else
148 uint32_t oce_enable_rss = 0;
149 #endif
150
151
152 TUNABLE_INT("hw.oce.max_rsp_handled", &oce_max_rsp_handled);
153 TUNABLE_INT("hw.oce.enable_rss", &oce_enable_rss);
154
155
156 /* Supported devices table */
157 static uint32_t supportedDevices[] = {
158 (PCI_VENDOR_SERVERENGINES << 16) | PCI_PRODUCT_BE2,
159 (PCI_VENDOR_SERVERENGINES << 16) | PCI_PRODUCT_BE3,
160 (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_BE3,
161 (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201,
162 (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201_VF,
163 (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_SH
164 };
165
166
167
168
169 /*****************************************************************************
170 * Driver entry points functions *
171 *****************************************************************************/
172
173 static int
oce_probe(device_t dev)174 oce_probe(device_t dev)
175 {
176 uint16_t vendor = 0;
177 uint16_t device = 0;
178 int i = 0;
179 char str[256] = {0};
180 POCE_SOFTC sc;
181
182 sc = device_get_softc(dev);
183 bzero(sc, sizeof(OCE_SOFTC));
184 sc->dev = dev;
185
186 vendor = pci_get_vendor(dev);
187 device = pci_get_device(dev);
188
189 for (i = 0; i < (sizeof(supportedDevices) / sizeof(uint32_t)); i++) {
190 if (vendor == ((supportedDevices[i] >> 16) & 0xffff)) {
191 if (device == (supportedDevices[i] & 0xffff)) {
192 ksprintf(str, "%s:%s", "Emulex CNA NIC function",
193 component_revision);
194 device_set_desc_copy(dev, str);
195
196 switch (device) {
197 case PCI_PRODUCT_BE2:
198 sc->flags |= OCE_FLAGS_BE2;
199 break;
200 case PCI_PRODUCT_BE3:
201 sc->flags |= OCE_FLAGS_BE3;
202 break;
203 case PCI_PRODUCT_XE201:
204 case PCI_PRODUCT_XE201_VF:
205 sc->flags |= OCE_FLAGS_XE201;
206 break;
207 case PCI_PRODUCT_SH:
208 sc->flags |= OCE_FLAGS_SH;
209 break;
210 default:
211 return ENXIO;
212 }
213 return BUS_PROBE_DEFAULT;
214 }
215 }
216 }
217
218 return ENXIO;
219 }
220
221
222 static int
oce_attach(device_t dev)223 oce_attach(device_t dev)
224 {
225 POCE_SOFTC sc;
226 int rc = 0;
227
228 sc = device_get_softc(dev);
229
230 rc = oce_hw_pci_alloc(sc);
231 if (rc)
232 return rc;
233
234 sc->tx_ring_size = OCE_TX_RING_SIZE;
235 sc->rx_ring_size = OCE_RX_RING_SIZE;
236 sc->rq_frag_size = OCE_RQ_BUF_SIZE;
237 sc->flow_control = OCE_DEFAULT_FLOW_CONTROL;
238 sc->promisc = OCE_DEFAULT_PROMISCUOUS;
239
240 LOCK_CREATE(&sc->bmbx_lock, "Mailbox_lock");
241 LOCK_CREATE(&sc->dev_lock, "Device_lock");
242
243 /* initialise the hardware */
244 rc = oce_hw_init(sc);
245 if (rc)
246 goto pci_res_free;
247
248 oce_get_config(sc);
249
250 setup_max_queues_want(sc);
251
252 rc = oce_setup_intr(sc);
253 if (rc)
254 goto mbox_free;
255
256 rc = oce_queue_init_all(sc);
257 if (rc)
258 goto intr_free;
259
260 rc = oce_attach_ifp(sc);
261 if (rc)
262 goto queues_free;
263
264 #if defined(INET6) || defined(INET)
265 #if 0 /* XXX swildner: LRO */
266 rc = oce_init_lro(sc);
267 if (rc)
268 goto ifp_free;
269 #endif
270 #endif
271
272 rc = oce_hw_start(sc);
273 if (rc)
274 goto lro_free;
275
276 sc->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
277 oce_add_vlan, sc, EVENTHANDLER_PRI_FIRST);
278 sc->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
279 oce_del_vlan, sc, EVENTHANDLER_PRI_FIRST);
280
281 rc = oce_stats_init(sc);
282 if (rc)
283 goto vlan_free;
284
285 oce_add_sysctls(sc);
286
287 callout_init_mp(&sc->timer);
288 callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc);
289
290 return 0;
291
292 vlan_free:
293 if (sc->vlan_attach)
294 EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
295 if (sc->vlan_detach)
296 EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
297 oce_hw_intr_disable(sc);
298 lro_free:
299 #if defined(INET6) || defined(INET)
300 #if 0 /* XXX swildner: LRO */
301 oce_free_lro(sc);
302 ifp_free:
303 #endif
304 #endif
305 ether_ifdetach(sc->ifp);
306 if_free(sc->ifp);
307 queues_free:
308 oce_queue_release_all(sc);
309 intr_free:
310 oce_intr_free(sc);
311 mbox_free:
312 oce_dma_free(sc, &sc->bsmbx);
313 pci_res_free:
314 oce_hw_pci_free(sc);
315 LOCK_DESTROY(&sc->dev_lock);
316 LOCK_DESTROY(&sc->bmbx_lock);
317 return rc;
318
319 }
320
321
322 static int
oce_detach(device_t dev)323 oce_detach(device_t dev)
324 {
325 POCE_SOFTC sc = device_get_softc(dev);
326
327 LOCK(&sc->dev_lock);
328 oce_if_deactivate(sc);
329 UNLOCK(&sc->dev_lock);
330
331 callout_terminate(&sc->timer);
332
333 if (sc->vlan_attach != NULL)
334 EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
335 if (sc->vlan_detach != NULL)
336 EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
337
338 ether_ifdetach(sc->ifp);
339
340 if_free(sc->ifp);
341
342 oce_hw_shutdown(sc);
343
344 bus_generic_detach(dev);
345 return 0;
346 }
347
348
349 static int
oce_shutdown(device_t dev)350 oce_shutdown(device_t dev)
351 {
352 int rc;
353
354 rc = oce_detach(dev);
355
356 return rc;
357 }
358
359
360 static int
oce_ioctl(struct ifnet * ifp,u_long command,caddr_t data,struct ucred * cr)361 oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
362 {
363 struct ifreq *ifr = (struct ifreq *)data;
364 POCE_SOFTC sc = ifp->if_softc;
365 int rc = 0;
366 uint32_t u;
367
368 switch (command) {
369
370 case SIOCGIFMEDIA:
371 rc = ifmedia_ioctl(ifp, ifr, &sc->media, command);
372 break;
373
374 case SIOCSIFMTU:
375 if (ifr->ifr_mtu > OCE_MAX_MTU)
376 rc = EINVAL;
377 else
378 ifp->if_mtu = ifr->ifr_mtu;
379 break;
380
381 case SIOCSIFFLAGS:
382 if (ifp->if_flags & IFF_UP) {
383 if (!(ifp->if_flags & IFF_RUNNING)) {
384 sc->ifp->if_flags |= IFF_RUNNING;
385 oce_init(sc);
386 }
387 device_printf(sc->dev, "Interface Up\n");
388 } else {
389 LOCK(&sc->dev_lock);
390
391 sc->ifp->if_flags &= ~IFF_RUNNING;
392 ifq_clr_oactive(&ifp->if_snd);
393 oce_if_deactivate(sc);
394
395 UNLOCK(&sc->dev_lock);
396
397 device_printf(sc->dev, "Interface Down\n");
398 }
399
400 if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) {
401 sc->promisc = TRUE;
402 oce_rxf_set_promiscuous(sc, sc->promisc);
403 } else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) {
404 sc->promisc = FALSE;
405 oce_rxf_set_promiscuous(sc, sc->promisc);
406 }
407
408 break;
409
410 case SIOCADDMULTI:
411 case SIOCDELMULTI:
412 rc = oce_hw_update_multicast(sc);
413 if (rc)
414 device_printf(sc->dev,
415 "Update multicast address failed\n");
416 break;
417
418 case SIOCSIFCAP:
419 u = ifr->ifr_reqcap ^ ifp->if_capenable;
420
421 if (u & IFCAP_TXCSUM) {
422 ifp->if_capenable ^= IFCAP_TXCSUM;
423 ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
424
425 if (IFCAP_TSO & ifp->if_capenable &&
426 !(IFCAP_TXCSUM & ifp->if_capenable)) {
427 ifp->if_capenable &= ~IFCAP_TSO;
428 ifp->if_hwassist &= ~CSUM_TSO;
429 if_printf(ifp,
430 "TSO disabled due to -txcsum.\n");
431 }
432 }
433
434 if (u & IFCAP_RXCSUM)
435 ifp->if_capenable ^= IFCAP_RXCSUM;
436
437 if (u & IFCAP_TSO4) {
438 ifp->if_capenable ^= IFCAP_TSO4;
439
440 if (IFCAP_TSO & ifp->if_capenable) {
441 if (IFCAP_TXCSUM & ifp->if_capenable)
442 ifp->if_hwassist |= CSUM_TSO;
443 else {
444 ifp->if_capenable &= ~IFCAP_TSO;
445 ifp->if_hwassist &= ~CSUM_TSO;
446 if_printf(ifp,
447 "Enable txcsum first.\n");
448 rc = EAGAIN;
449 }
450 } else
451 ifp->if_hwassist &= ~CSUM_TSO;
452 }
453
454 if (u & IFCAP_VLAN_HWTAGGING)
455 ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
456
457 #if 0 /* XXX swildner: VLAN_HWFILTER */
458 if (u & IFCAP_VLAN_HWFILTER) {
459 ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
460 oce_vid_config(sc);
461 }
462 #endif
463 #if defined(INET6) || defined(INET)
464 #if 0 /* XXX swildner: LRO */
465 if (u & IFCAP_LRO)
466 ifp->if_capenable ^= IFCAP_LRO;
467 #endif
468 #endif
469
470 break;
471
472 case SIOCGPRIVATE_0:
473 rc = caps_priv_check(cr, SYSCAP_RESTRICTEDROOT |
474 __SYSCAP_NULLCRED);
475 if (rc == 0)
476 rc = oce_handle_passthrough(ifp, data);
477 break;
478 default:
479 rc = ether_ioctl(ifp, command, data);
480 break;
481 }
482
483 return rc;
484 }
485
486
487 static void
oce_init(void * arg)488 oce_init(void *arg)
489 {
490 POCE_SOFTC sc = arg;
491
492 LOCK(&sc->dev_lock);
493
494 if (sc->ifp->if_flags & IFF_UP) {
495 oce_if_deactivate(sc);
496 oce_if_activate(sc);
497 }
498
499 UNLOCK(&sc->dev_lock);
500
501 }
502
503
504 #if 0 /* XXX swildner: MULTIQUEUE */
505 static int
506 oce_multiq_start(struct ifnet *ifp, struct mbuf *m)
507 {
508 POCE_SOFTC sc = ifp->if_softc;
509 struct oce_wq *wq = NULL;
510 int queue_index = 0;
511 int status = 0;
512
513 if (!sc->link_status) {
514 ifq_purge(&ifp->if_snd);
515 return ENXIO;
516 }
517
518 if ((m->m_flags & M_FLOWID) != 0)
519 queue_index = m->m_pkthdr.flowid % sc->nwqs;
520
521 wq = sc->wq[queue_index];
522
523 LOCK(&wq->tx_lock);
524 status = oce_multiq_transmit(ifp, m, wq);
525 UNLOCK(&wq->tx_lock);
526
527 return status;
528
529 }
530
531
532 static void
533 oce_multiq_flush(struct ifnet *ifp)
534 {
535 POCE_SOFTC sc = ifp->if_softc;
536 struct mbuf *m;
537 int i = 0;
538
539 for (i = 0; i < sc->nwqs; i++) {
540 while ((m = buf_ring_dequeue_sc(sc->wq[i]->br)) != NULL)
541 m_freem(m);
542 }
543 if_qflush(ifp);
544 }
545 #endif
546
547
548
549 /*****************************************************************************
550 * Driver interrupt routines functions *
551 *****************************************************************************/
552
553 static void
oce_intr(void * arg,int pending)554 oce_intr(void *arg, int pending)
555 {
556
557 POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
558 POCE_SOFTC sc = ii->sc;
559 struct oce_eq *eq = ii->eq;
560 struct oce_eqe *eqe;
561 struct oce_cq *cq = NULL;
562 int i, num_eqes = 0;
563
564
565 bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
566 BUS_DMASYNC_POSTWRITE);
567 do {
568 eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
569 if (eqe->evnt == 0)
570 break;
571 eqe->evnt = 0;
572 bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
573 BUS_DMASYNC_POSTWRITE);
574 RING_GET(eq->ring, 1);
575 num_eqes++;
576
577 } while (TRUE);
578
579 if (!num_eqes)
580 goto eq_arm; /* Spurious */
581
582 /* Clear EQ entries, but dont arm */
583 oce_arm_eq(sc, eq->eq_id, num_eqes, FALSE, FALSE);
584
585 /* Process TX, RX and MCC. But dont arm CQ*/
586 for (i = 0; i < eq->cq_valid; i++) {
587 cq = eq->cq[i];
588 (*cq->cq_handler)(cq->cb_arg);
589 }
590
591 /* Arm all cqs connected to this EQ */
592 for (i = 0; i < eq->cq_valid; i++) {
593 cq = eq->cq[i];
594 oce_arm_cq(sc, cq->cq_id, 0, TRUE);
595 }
596
597 eq_arm:
598 oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
599
600 return;
601 }
602
603
604 static int
oce_setup_intr(POCE_SOFTC sc)605 oce_setup_intr(POCE_SOFTC sc)
606 {
607 int rc = 0, use_intx = 0;
608 int vector = 0;
609 #if 0 /* XXX swildner: MSI-X */
610 int req_vectors = 0;
611
612 if (is_rss_enabled(sc))
613 req_vectors = MAX((sc->nrqs - 1), sc->nwqs);
614 else
615 req_vectors = 1;
616
617 if (sc->flags & OCE_FLAGS_MSIX_CAPABLE) {
618 sc->intr_count = req_vectors;
619 rc = pci_alloc_msix(sc->dev, &sc->intr_count);
620 if (rc != 0) {
621 use_intx = 1;
622 pci_release_msi(sc->dev);
623 } else
624 sc->flags |= OCE_FLAGS_USING_MSIX;
625 } else
626 #endif
627 use_intx = 1;
628
629 if (use_intx)
630 sc->intr_count = 1;
631
632 /* Scale number of queues based on intr we got */
633 update_queues_got(sc);
634
635 if (use_intx) {
636 device_printf(sc->dev, "Using legacy interrupt\n");
637 rc = oce_alloc_intr(sc, vector, oce_intr);
638 if (rc)
639 goto error;
640 #if 0 /* XXX swildner: MSI-X */
641 } else {
642 for (; vector < sc->intr_count; vector++) {
643 rc = oce_alloc_intr(sc, vector, oce_intr);
644 if (rc)
645 goto error;
646 }
647 #endif
648 }
649
650 return 0;
651 error:
652 oce_intr_free(sc);
653 return rc;
654 }
655
656
657 void
oce_fast_isr(void * arg)658 oce_fast_isr(void *arg)
659 {
660 POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
661 POCE_SOFTC sc = ii->sc;
662
663 if (ii->eq == NULL)
664 return;
665
666 oce_arm_eq(sc, ii->eq->eq_id, 0, FALSE, TRUE);
667
668 taskqueue_enqueue(ii->tq, &ii->task);
669
670 ii->eq->intr++;
671 }
672
673
674 static int
oce_alloc_intr(POCE_SOFTC sc,int vector,void (* isr)(void * arg,int pending))675 oce_alloc_intr(POCE_SOFTC sc, int vector, void (*isr) (void *arg, int pending))
676 {
677 POCE_INTR_INFO ii = &sc->intrs[vector];
678 int rc = 0, rr;
679 u_int irq_flags;
680
681 if (vector >= OCE_MAX_EQ)
682 return (EINVAL);
683
684 #if 0 /* XXX swildner: MSI-X */
685 /* Set the resource id for the interrupt.
686 * MSIx is vector + 1 for the resource id,
687 * INTx is 0 for the resource id.
688 */
689 if (sc->flags & OCE_FLAGS_USING_MSIX)
690 rr = vector + 1;
691 else
692 #endif
693 rr = 0;
694 ii->irq_type = pci_alloc_1intr(sc->dev,
695 sc->flags & OCE_FLAGS_USING_MSI, &rr, &irq_flags);
696 ii->intr_res = bus_alloc_resource_any(sc->dev,
697 SYS_RES_IRQ,
698 &rr, irq_flags);
699 ii->irq_rr = rr;
700 if (ii->intr_res == NULL) {
701 device_printf(sc->dev,
702 "Could not allocate interrupt\n");
703 rc = ENXIO;
704 return rc;
705 }
706
707 TASK_INIT(&ii->task, 0, isr, ii);
708 ii->vector = vector;
709 ksprintf(ii->task_name, "oce_task[%d]", ii->vector);
710 ii->tq = taskqueue_create(ii->task_name,
711 M_NOWAIT,
712 taskqueue_thread_enqueue,
713 &ii->tq);
714 taskqueue_start_threads(&ii->tq, 1, TDPRI_KERN_DAEMON, -1, "%s taskq",
715 device_get_nameunit(sc->dev));
716
717 ii->sc = sc;
718 rc = bus_setup_intr(sc->dev,
719 ii->intr_res,
720 0,
721 oce_fast_isr, ii, &ii->tag, NULL);
722 return rc;
723
724 }
725
726
727 void
oce_intr_free(POCE_SOFTC sc)728 oce_intr_free(POCE_SOFTC sc)
729 {
730 int i = 0;
731
732 for (i = 0; i < sc->intr_count; i++) {
733
734 if (sc->intrs[i].tag != NULL)
735 bus_teardown_intr(sc->dev, sc->intrs[i].intr_res,
736 sc->intrs[i].tag);
737 if (sc->intrs[i].tq != NULL)
738 taskqueue_free(sc->intrs[i].tq);
739
740 if (sc->intrs[i].intr_res != NULL)
741 bus_release_resource(sc->dev, SYS_RES_IRQ,
742 sc->intrs[i].irq_rr,
743 sc->intrs[i].intr_res);
744 sc->intrs[i].tag = NULL;
745 sc->intrs[i].intr_res = NULL;
746 }
747
748 if (sc->flags & OCE_FLAGS_USING_MSIX ||
749 sc->flags & OCE_FLAGS_USING_MSI)
750 pci_release_msi(sc->dev);
751
752 }
753
754
755
756 /******************************************************************************
757 * Media callbacks functions *
758 ******************************************************************************/
759
760 static void
oce_media_status(struct ifnet * ifp,struct ifmediareq * req)761 oce_media_status(struct ifnet *ifp, struct ifmediareq *req)
762 {
763 POCE_SOFTC sc = (POCE_SOFTC) ifp->if_softc;
764
765
766 req->ifm_status = IFM_AVALID;
767 req->ifm_active = IFM_ETHER;
768
769 if (sc->link_status == 1)
770 req->ifm_status |= IFM_ACTIVE;
771 else
772 return;
773
774 switch (sc->link_speed) {
775 case 1: /* 10 Mbps */
776 req->ifm_active |= IFM_10_T | IFM_FDX;
777 sc->speed = 10;
778 break;
779 case 2: /* 100 Mbps */
780 req->ifm_active |= IFM_100_TX | IFM_FDX;
781 sc->speed = 100;
782 break;
783 case 3: /* 1 Gbps */
784 req->ifm_active |= IFM_1000_T | IFM_FDX;
785 sc->speed = 1000;
786 break;
787 case 4: /* 10 Gbps */
788 req->ifm_active |= IFM_10G_SR | IFM_FDX;
789 sc->speed = 10000;
790 break;
791 }
792
793 return;
794 }
795
796
797 int
oce_media_change(struct ifnet * ifp)798 oce_media_change(struct ifnet *ifp)
799 {
800 return 0;
801 }
802
803
804
805
806 /*****************************************************************************
807 * Transmit routines functions *
808 *****************************************************************************/
809
810 static int
oce_tx(POCE_SOFTC sc,struct mbuf ** mpp,int wq_index)811 oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
812 {
813 int rc = 0, i, retry_cnt = 0;
814 bus_dma_segment_t segs[OCE_MAX_TX_ELEMENTS];
815 struct mbuf *m, *m_temp;
816 struct oce_wq *wq = sc->wq[wq_index];
817 struct oce_packet_desc *pd;
818 struct oce_nic_hdr_wqe *nichdr;
819 struct oce_nic_frag_wqe *nicfrag;
820 int num_wqes;
821 uint32_t reg_value;
822 boolean_t complete = TRUE;
823
824 m = *mpp;
825 if (!m)
826 return EINVAL;
827
828 if (!(m->m_flags & M_PKTHDR)) {
829 rc = ENXIO;
830 goto free_ret;
831 }
832
833 if(oce_tx_asic_stall_verify(sc, m)) {
834 m = oce_insert_vlan_tag(sc, m, &complete);
835 if(!m) {
836 device_printf(sc->dev, "Insertion unsuccessful\n");
837 return 0;
838 }
839
840 }
841
842 if (m->m_pkthdr.csum_flags & CSUM_TSO) {
843 /* consolidate packet buffers for TSO/LSO segment offload */
844 #if defined(INET6) || defined(INET)
845 m = oce_tso_setup(sc, mpp);
846 #else
847 m = NULL;
848 #endif
849 if (m == NULL) {
850 rc = ENXIO;
851 goto free_ret;
852 }
853 }
854
855 pd = &wq->pckts[wq->pkt_desc_head];
856 retry:
857 rc = bus_dmamap_load_mbuf_defrag(wq->tag,
858 pd->map,
859 mpp, segs, OCE_MAX_TX_ELEMENTS,
860 &pd->nsegs, BUS_DMA_NOWAIT);
861 if (rc == 0) {
862 num_wqes = pd->nsegs + 1;
863 if (IS_BE(sc) || IS_SH(sc)) {
864 /*Dummy required only for BE3.*/
865 if (num_wqes & 1)
866 num_wqes++;
867 }
868 if (num_wqes >= RING_NUM_FREE(wq->ring)) {
869 bus_dmamap_unload(wq->tag, pd->map);
870 return EBUSY;
871 }
872 atomic_store_rel_int(&wq->pkt_desc_head,
873 (wq->pkt_desc_head + 1) % \
874 OCE_WQ_PACKET_ARRAY_SIZE);
875 bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_PREWRITE);
876 pd->mbuf = m;
877
878 nichdr =
879 RING_GET_PRODUCER_ITEM_VA(wq->ring, struct oce_nic_hdr_wqe);
880 nichdr->u0.dw[0] = 0;
881 nichdr->u0.dw[1] = 0;
882 nichdr->u0.dw[2] = 0;
883 nichdr->u0.dw[3] = 0;
884
885 nichdr->u0.s.complete = complete;
886 nichdr->u0.s.event = 1;
887 nichdr->u0.s.crc = 1;
888 nichdr->u0.s.forward = 0;
889 nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0;
890 nichdr->u0.s.udpcs =
891 (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
892 nichdr->u0.s.tcpcs =
893 (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
894 nichdr->u0.s.num_wqe = num_wqes;
895 nichdr->u0.s.total_length = m->m_pkthdr.len;
896 #if 0 /* XXX swildner: ETHER_VTAG */
897 if (m->m_flags & M_VLANTAG) {
898 nichdr->u0.s.vlan = 1; /*Vlan present*/
899 nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag;
900 }
901 #endif
902 if (m->m_pkthdr.csum_flags & CSUM_TSO) {
903 if (m->m_pkthdr.tso_segsz) {
904 nichdr->u0.s.lso = 1;
905 nichdr->u0.s.lso_mss = m->m_pkthdr.tso_segsz;
906 }
907 if (!IS_BE(sc) || !IS_SH(sc))
908 nichdr->u0.s.ipcs = 1;
909 }
910
911 RING_PUT(wq->ring, 1);
912 atomic_add_int(&wq->ring->num_used, 1);
913
914 for (i = 0; i < pd->nsegs; i++) {
915 nicfrag =
916 RING_GET_PRODUCER_ITEM_VA(wq->ring,
917 struct oce_nic_frag_wqe);
918 nicfrag->u0.s.rsvd0 = 0;
919 nicfrag->u0.s.frag_pa_hi = ADDR_HI(segs[i].ds_addr);
920 nicfrag->u0.s.frag_pa_lo = ADDR_LO(segs[i].ds_addr);
921 nicfrag->u0.s.frag_len = segs[i].ds_len;
922 pd->wqe_idx = wq->ring->pidx;
923 RING_PUT(wq->ring, 1);
924 atomic_add_int(&wq->ring->num_used, 1);
925 }
926 if (num_wqes > (pd->nsegs + 1)) {
927 nicfrag =
928 RING_GET_PRODUCER_ITEM_VA(wq->ring,
929 struct oce_nic_frag_wqe);
930 nicfrag->u0.dw[0] = 0;
931 nicfrag->u0.dw[1] = 0;
932 nicfrag->u0.dw[2] = 0;
933 nicfrag->u0.dw[3] = 0;
934 pd->wqe_idx = wq->ring->pidx;
935 RING_PUT(wq->ring, 1);
936 atomic_add_int(&wq->ring->num_used, 1);
937 pd->nsegs++;
938 }
939
940 sc->ifp->if_opackets++;
941 wq->tx_stats.tx_reqs++;
942 wq->tx_stats.tx_wrbs += num_wqes;
943 wq->tx_stats.tx_bytes += m->m_pkthdr.len;
944 wq->tx_stats.tx_pkts++;
945
946 bus_dmamap_sync(wq->ring->dma.tag, wq->ring->dma.map,
947 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
948 reg_value = (num_wqes << 16) | wq->wq_id;
949 OCE_WRITE_REG32(sc, db, wq->db_offset, reg_value);
950
951 } else if (rc == EFBIG) {
952 if (retry_cnt == 0) {
953 m_temp = m_defrag(m, M_NOWAIT);
954 if (m_temp == NULL)
955 goto free_ret;
956 m = m_temp;
957 *mpp = m_temp;
958 retry_cnt = retry_cnt + 1;
959 goto retry;
960 } else
961 goto free_ret;
962 } else if (rc == ENOMEM)
963 return rc;
964 else
965 goto free_ret;
966
967 return 0;
968
969 free_ret:
970 m_freem(*mpp);
971 *mpp = NULL;
972 return rc;
973 }
974
975
976 static void
oce_tx_complete(struct oce_wq * wq,uint32_t wqe_idx,uint32_t status)977 oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, uint32_t status)
978 {
979 struct oce_packet_desc *pd;
980 POCE_SOFTC sc = (POCE_SOFTC) wq->parent;
981 struct mbuf *m;
982
983 pd = &wq->pckts[wq->pkt_desc_tail];
984 atomic_store_rel_int(&wq->pkt_desc_tail,
985 (wq->pkt_desc_tail + 1) % OCE_WQ_PACKET_ARRAY_SIZE);
986 atomic_subtract_int(&wq->ring->num_used, pd->nsegs + 1);
987 bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
988 bus_dmamap_unload(wq->tag, pd->map);
989
990 m = pd->mbuf;
991 m_freem(m);
992 pd->mbuf = NULL;
993
994 if (ifq_is_oactive(&sc->ifp->if_snd)) {
995 if (wq->ring->num_used < (wq->ring->num_items / 2)) {
996 ifq_clr_oactive(&sc->ifp->if_snd);
997 oce_tx_restart(sc, wq);
998 }
999 }
1000 }
1001
1002
1003 static void
oce_tx_restart(POCE_SOFTC sc,struct oce_wq * wq)1004 oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq)
1005 {
1006
1007 if ((sc->ifp->if_flags & IFF_RUNNING) != IFF_RUNNING)
1008 return;
1009
1010 #if 0 /* __FreeBSD_version >= 800000 */
1011 if (!drbr_empty(sc->ifp, wq->br))
1012 #else
1013 if (!ifq_is_empty(&sc->ifp->if_snd))
1014 #endif
1015 taskqueue_enqueue(taskqueue_swi, &wq->txtask);
1016
1017 }
1018
1019
1020 #if defined(INET6) || defined(INET)
1021 static struct mbuf *
oce_tso_setup(POCE_SOFTC sc,struct mbuf ** mpp)1022 oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp)
1023 {
1024 struct mbuf *m;
1025 #ifdef INET
1026 struct ip *ip;
1027 #endif
1028 #ifdef INET6
1029 struct ip6_hdr *ip6;
1030 #endif
1031 struct ether_vlan_header *eh;
1032 struct tcphdr *th;
1033 uint16_t etype;
1034 int total_len = 0, ehdrlen = 0;
1035
1036 m = *mpp;
1037
1038 if (M_WRITABLE(m) == 0) {
1039 m = m_dup(*mpp, M_NOWAIT);
1040 if (!m)
1041 return NULL;
1042 m_freem(*mpp);
1043 *mpp = m;
1044 }
1045
1046 eh = mtod(m, struct ether_vlan_header *);
1047 if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
1048 etype = ntohs(eh->evl_proto);
1049 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
1050 } else {
1051 etype = ntohs(eh->evl_encap_proto);
1052 ehdrlen = ETHER_HDR_LEN;
1053 }
1054
1055 switch (etype) {
1056 #ifdef INET
1057 case ETHERTYPE_IP:
1058 ip = (struct ip *)(m->m_data + ehdrlen);
1059 if (ip->ip_p != IPPROTO_TCP)
1060 return NULL;
1061 th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
1062
1063 total_len = ehdrlen + (ip->ip_hl << 2) + (th->th_off << 2);
1064 break;
1065 #endif
1066 #ifdef INET6
1067 case ETHERTYPE_IPV6:
1068 ip6 = (struct ip6_hdr *)(m->m_data + ehdrlen);
1069 if (ip6->ip6_nxt != IPPROTO_TCP)
1070 return NULL;
1071 th = (struct tcphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr));
1072
1073 total_len = ehdrlen + sizeof(struct ip6_hdr) + (th->th_off << 2);
1074 break;
1075 #endif
1076 default:
1077 return NULL;
1078 }
1079
1080 m = m_pullup(m, total_len);
1081 if (!m)
1082 return NULL;
1083 *mpp = m;
1084 return m;
1085
1086 }
1087 #endif /* INET6 || INET */
1088
1089 void
oce_tx_task(void * arg,int npending)1090 oce_tx_task(void *arg, int npending)
1091 {
1092 struct oce_wq *wq = arg;
1093 POCE_SOFTC sc = wq->parent;
1094 struct ifnet *ifp = sc->ifp;
1095 #if 0 /* XXX swildner: MULTIQUEUE */
1096 int rc = 0;
1097
1098 LOCK(&wq->tx_lock);
1099 rc = oce_multiq_transmit(ifp, NULL, wq);
1100 if (rc) {
1101 device_printf(sc->dev,
1102 "TX[%d] restart failed\n", wq->queue_index);
1103 }
1104 UNLOCK(&wq->tx_lock);
1105 #else
1106 lwkt_serialize_enter(ifp->if_serializer);
1107 oce_start_locked(ifp);
1108 lwkt_serialize_exit(ifp->if_serializer);
1109 #endif
1110 }
1111
1112
1113 void
oce_start_locked(struct ifnet * ifp)1114 oce_start_locked(struct ifnet *ifp)
1115 {
1116 POCE_SOFTC sc = ifp->if_softc;
1117 struct mbuf *m;
1118 int rc = 0;
1119 int def_q = 0; /* Default tx queue is 0 */
1120
1121 if (!((ifp->if_flags & IFF_RUNNING) && !ifq_is_oactive(&ifp->if_snd)))
1122 return;
1123
1124 if (!sc->link_status) {
1125 ifq_purge(&ifp->if_snd);
1126 return;
1127 }
1128
1129 do {
1130 m = ifq_dequeue(&sc->ifp->if_snd);
1131 if (m == NULL)
1132 break;
1133
1134 rc = oce_tx(sc, &m, def_q);
1135 if (rc) {
1136 if (m != NULL) {
1137 sc->wq[def_q]->tx_stats.tx_stops ++;
1138 ifq_set_oactive(&ifp->if_snd);
1139 ifq_prepend(&ifp->if_snd, m);
1140 m = NULL;
1141 }
1142 break;
1143 }
1144 if (m != NULL)
1145 ETHER_BPF_MTAP(ifp, m);
1146
1147 } while (TRUE);
1148
1149 return;
1150 }
1151
1152 void
oce_start(struct ifnet * ifp,struct ifaltq_subque * ifsq)1153 oce_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
1154 {
1155 ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
1156 oce_start_locked(ifp);
1157 }
1158
1159
1160 /* Handle the Completion Queue for transmit */
1161 uint16_t
oce_wq_handler(void * arg)1162 oce_wq_handler(void *arg)
1163 {
1164 struct oce_wq *wq = (struct oce_wq *)arg;
1165 POCE_SOFTC sc = wq->parent;
1166 struct oce_cq *cq = wq->cq;
1167 struct oce_nic_tx_cqe *cqe;
1168 int num_cqes = 0;
1169
1170 bus_dmamap_sync(cq->ring->dma.tag,
1171 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1172 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
1173 while (cqe->u0.dw[3]) {
1174 DW_SWAP((uint32_t *) cqe, sizeof(oce_wq_cqe));
1175
1176 wq->ring->cidx = cqe->u0.s.wqe_index + 1;
1177 if (wq->ring->cidx >= wq->ring->num_items)
1178 wq->ring->cidx -= wq->ring->num_items;
1179
1180 oce_tx_complete(wq, cqe->u0.s.wqe_index, cqe->u0.s.status);
1181 wq->tx_stats.tx_compl++;
1182 cqe->u0.dw[3] = 0;
1183 RING_GET(cq->ring, 1);
1184 bus_dmamap_sync(cq->ring->dma.tag,
1185 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1186 cqe =
1187 RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
1188 num_cqes++;
1189 }
1190
1191 if (num_cqes)
1192 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
1193
1194 return 0;
1195 }
1196
1197
1198 #if 0 /* XXX swildner: MULTIQUEUE */
1199 static int
1200 oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
1201 {
1202 POCE_SOFTC sc = ifp->if_softc;
1203 int status = 0, queue_index = 0;
1204 struct mbuf *next = NULL;
1205 struct buf_ring *br = NULL;
1206
1207 br = wq->br;
1208 queue_index = wq->queue_index;
1209
1210 if (!((ifp->if_flags & IFF_RUNNING) && !ifq_is_oactive(&ifp->if_snd))) {
1211 if (m != NULL)
1212 status = drbr_enqueue(ifp, br, m);
1213 return status;
1214 }
1215
1216 if (m != NULL) {
1217 if ((status = drbr_enqueue(ifp, br, m)) != 0)
1218 return status;
1219 }
1220 while ((next = drbr_peek(ifp, br)) != NULL) {
1221 if (oce_tx(sc, &next, queue_index)) {
1222 if (next == NULL) {
1223 drbr_advance(ifp, br);
1224 } else {
1225 drbr_putback(ifp, br, next);
1226 wq->tx_stats.tx_stops ++;
1227 ifp_set_oactive(&ifp->if_snd);
1228 status = drbr_enqueue(ifp, br, next);
1229 }
1230 break;
1231 }
1232 drbr_advance(ifp, br);
1233 ifp->if_obytes += next->m_pkthdr.len;
1234 if (next->m_flags & M_MCAST)
1235 ifp->if_omcasts++;
1236 ETHER_BPF_MTAP(ifp, next);
1237 }
1238
1239 return status;
1240 }
1241 #endif
1242
1243
1244
1245
1246 /*****************************************************************************
1247 * Receive routines functions *
1248 *****************************************************************************/
1249
1250 static void
oce_rx(struct oce_rq * rq,uint32_t rqe_idx,struct oce_nic_rx_cqe * cqe)1251 oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe)
1252 {
1253 uint32_t out;
1254 struct oce_packet_desc *pd;
1255 POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1256 int i, len, frag_len;
1257 struct mbuf *m = NULL, *tail = NULL;
1258 uint16_t vtag;
1259
1260 len = cqe->u0.s.pkt_size;
1261 if (!len) {
1262 /*partial DMA workaround for Lancer*/
1263 oce_discard_rx_comp(rq, cqe);
1264 goto exit;
1265 }
1266
1267 /* Get vlan_tag value */
1268 if(IS_BE(sc) || IS_SH(sc))
1269 vtag = BSWAP_16(cqe->u0.s.vlan_tag);
1270 else
1271 vtag = cqe->u0.s.vlan_tag;
1272
1273
1274 for (i = 0; i < cqe->u0.s.num_fragments; i++) {
1275
1276 if (rq->packets_out == rq->packets_in) {
1277 device_printf(sc->dev,
1278 "RQ transmit descriptor missing\n");
1279 }
1280 out = rq->packets_out + 1;
1281 if (out == OCE_RQ_PACKET_ARRAY_SIZE)
1282 out = 0;
1283 pd = &rq->pckts[rq->packets_out];
1284 rq->packets_out = out;
1285
1286 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1287 bus_dmamap_unload(rq->tag, pd->map);
1288 rq->pending--;
1289
1290 frag_len = (len > rq->cfg.frag_size) ? rq->cfg.frag_size : len;
1291 pd->mbuf->m_len = frag_len;
1292
1293 if (tail != NULL) {
1294 /* additional fragments */
1295 tail->m_next = pd->mbuf;
1296 tail = pd->mbuf;
1297 } else {
1298 /* first fragment, fill out much of the packet header */
1299 pd->mbuf->m_pkthdr.len = len;
1300 pd->mbuf->m_pkthdr.csum_flags = 0;
1301 if (IF_CSUM_ENABLED(sc)) {
1302 if (cqe->u0.s.l4_cksum_pass) {
1303 pd->mbuf->m_pkthdr.csum_flags |=
1304 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
1305 pd->mbuf->m_pkthdr.csum_data = 0xffff;
1306 }
1307 if (cqe->u0.s.ip_cksum_pass) {
1308 if (!cqe->u0.s.ip_ver) { /* IPV4 */
1309 pd->mbuf->m_pkthdr.csum_flags |=
1310 (CSUM_IP_CHECKED|CSUM_IP_VALID);
1311 }
1312 }
1313 }
1314 m = tail = pd->mbuf;
1315 }
1316 pd->mbuf = NULL;
1317 len -= frag_len;
1318 }
1319
1320 if (m) {
1321 if (!oce_cqe_portid_valid(sc, cqe)) {
1322 m_freem(m);
1323 goto exit;
1324 }
1325
1326 m->m_pkthdr.rcvif = sc->ifp;
1327 #if 0 /* __FreeBSD_version >= 800000 */
1328 if (rq->queue_index)
1329 m->m_pkthdr.flowid = (rq->queue_index - 1);
1330 else
1331 m->m_pkthdr.flowid = rq->queue_index;
1332 m->m_flags |= M_FLOWID;
1333 #endif
1334 #if 0 /* XXX swildner: ETHER_VTAG */
1335 /* This deternies if vlan tag is Valid */
1336 if (oce_cqe_vtp_valid(sc, cqe)) {
1337 if (sc->function_mode & FNM_FLEX10_MODE) {
1338 /* FLEX10. If QnQ is not set, neglect VLAN */
1339 if (cqe->u0.s.qnq) {
1340 m->m_pkthdr.ether_vtag = vtag;
1341 m->m_flags |= M_VLANTAG;
1342 }
1343 } else if (sc->pvid != (vtag & VLAN_VID_MASK)) {
1344 /* In UMC mode generally pvid will be striped by
1345 hw. But in some cases we have seen it comes
1346 with pvid. So if pvid == vlan, neglect vlan.
1347 */
1348 m->m_pkthdr.ether_vtag = vtag;
1349 m->m_flags |= M_VLANTAG;
1350 }
1351 }
1352 #endif
1353
1354 sc->ifp->if_ipackets++;
1355 #if defined(INET6) || defined(INET)
1356 #if 0 /* XXX swildner: LRO */
1357 /* Try to queue to LRO */
1358 if (IF_LRO_ENABLED(sc) &&
1359 (cqe->u0.s.ip_cksum_pass) &&
1360 (cqe->u0.s.l4_cksum_pass) &&
1361 (!cqe->u0.s.ip_ver) &&
1362 (rq->lro.lro_cnt != 0)) {
1363
1364 if (tcp_lro_rx(&rq->lro, m, 0) == 0) {
1365 rq->lro_pkts_queued ++;
1366 goto post_done;
1367 }
1368 /* If LRO posting fails then try to post to STACK */
1369 }
1370 #endif
1371 #endif
1372
1373 sc->ifp->if_input(sc->ifp, m, NULL, -1);
1374 #if defined(INET6) || defined(INET)
1375 #if 0 /* XXX swildner: LRO */
1376 post_done:
1377 #endif
1378 #endif
1379 /* Update rx stats per queue */
1380 rq->rx_stats.rx_pkts++;
1381 rq->rx_stats.rx_bytes += cqe->u0.s.pkt_size;
1382 rq->rx_stats.rx_frags += cqe->u0.s.num_fragments;
1383 if (cqe->u0.s.pkt_type == OCE_MULTICAST_PACKET)
1384 rq->rx_stats.rx_mcast_pkts++;
1385 if (cqe->u0.s.pkt_type == OCE_UNICAST_PACKET)
1386 rq->rx_stats.rx_ucast_pkts++;
1387 }
1388 exit:
1389 return;
1390 }
1391
1392
1393 static void
oce_discard_rx_comp(struct oce_rq * rq,struct oce_nic_rx_cqe * cqe)1394 oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
1395 {
1396 uint32_t out, i = 0;
1397 struct oce_packet_desc *pd;
1398 POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1399 int num_frags = cqe->u0.s.num_fragments;
1400
1401 for (i = 0; i < num_frags; i++) {
1402 if (rq->packets_out == rq->packets_in) {
1403 device_printf(sc->dev,
1404 "RQ transmit descriptor missing\n");
1405 }
1406 out = rq->packets_out + 1;
1407 if (out == OCE_RQ_PACKET_ARRAY_SIZE)
1408 out = 0;
1409 pd = &rq->pckts[rq->packets_out];
1410 rq->packets_out = out;
1411
1412 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
1413 bus_dmamap_unload(rq->tag, pd->map);
1414 rq->pending--;
1415 m_freem(pd->mbuf);
1416 }
1417
1418 }
1419
1420
1421 #if 0 /* XXX swildner: ETHER_VTAG */
1422 static int
1423 oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
1424 {
1425 struct oce_nic_rx_cqe_v1 *cqe_v1;
1426 int vtp = 0;
1427
1428 if (sc->be3_native) {
1429 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1430 vtp = cqe_v1->u0.s.vlan_tag_present;
1431 } else
1432 vtp = cqe->u0.s.vlan_tag_present;
1433
1434 return vtp;
1435
1436 }
1437 #endif
1438
1439
1440 static int
oce_cqe_portid_valid(POCE_SOFTC sc,struct oce_nic_rx_cqe * cqe)1441 oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
1442 {
1443 struct oce_nic_rx_cqe_v1 *cqe_v1;
1444 int port_id = 0;
1445
1446 if (sc->be3_native && (IS_BE(sc) || IS_SH(sc))) {
1447 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
1448 port_id = cqe_v1->u0.s.port;
1449 if (sc->port_id != port_id)
1450 return 0;
1451 } else {
1452 ;/* For BE3 legacy and Lancer this is dummy */
1453 }
1454
1455 return 1;
1456
1457 }
1458
1459 #if defined(INET6) || defined(INET)
1460 #if 0 /* XXX swildner: LRO */
1461 static void
1462 oce_rx_flush_lro(struct oce_rq *rq)
1463 {
1464 struct lro_ctrl *lro = &rq->lro;
1465 struct lro_entry *queued;
1466 POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1467
1468 if (!IF_LRO_ENABLED(sc))
1469 return;
1470
1471 while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) {
1472 SLIST_REMOVE_HEAD(&lro->lro_active, next);
1473 tcp_lro_flush(lro, queued);
1474 }
1475 rq->lro_pkts_queued = 0;
1476
1477 return;
1478 }
1479
1480
1481 static int
1482 oce_init_lro(POCE_SOFTC sc)
1483 {
1484 struct lro_ctrl *lro = NULL;
1485 int i = 0, rc = 0;
1486
1487 for (i = 0; i < sc->nrqs; i++) {
1488 lro = &sc->rq[i]->lro;
1489 rc = tcp_lro_init(lro);
1490 if (rc != 0) {
1491 device_printf(sc->dev, "LRO init failed\n");
1492 return rc;
1493 }
1494 lro->ifp = sc->ifp;
1495 }
1496
1497 return rc;
1498 }
1499
1500
1501 void
1502 oce_free_lro(POCE_SOFTC sc)
1503 {
1504 struct lro_ctrl *lro = NULL;
1505 int i = 0;
1506
1507 for (i = 0; i < sc->nrqs; i++) {
1508 lro = &sc->rq[i]->lro;
1509 if (lro)
1510 tcp_lro_free(lro);
1511 }
1512 }
1513 #endif
1514 #endif
1515
1516 int
oce_alloc_rx_bufs(struct oce_rq * rq,int count)1517 oce_alloc_rx_bufs(struct oce_rq *rq, int count)
1518 {
1519 POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
1520 int i, in, rc;
1521 struct oce_packet_desc *pd;
1522 bus_dma_segment_t segs[6];
1523 int nsegs, added = 0;
1524 struct oce_nic_rqe *rqe;
1525 pd_rxulp_db_t rxdb_reg;
1526
1527 bzero(&rxdb_reg, sizeof(pd_rxulp_db_t));
1528 for (i = 0; i < count; i++) {
1529 in = rq->packets_in + 1;
1530 if (in == OCE_RQ_PACKET_ARRAY_SIZE)
1531 in = 0;
1532 if (in == rq->packets_out)
1533 break; /* no more room */
1534
1535 pd = &rq->pckts[rq->packets_in];
1536 pd->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1537 if (pd->mbuf == NULL)
1538 break;
1539
1540 pd->mbuf->m_len = pd->mbuf->m_pkthdr.len = MCLBYTES;
1541 rc = bus_dmamap_load_mbuf_segment(rq->tag,
1542 pd->map,
1543 pd->mbuf,
1544 segs, 1,
1545 &nsegs, BUS_DMA_NOWAIT);
1546 if (rc) {
1547 m_free(pd->mbuf);
1548 break;
1549 }
1550
1551 if (nsegs != 1) {
1552 i--;
1553 continue;
1554 }
1555
1556 rq->packets_in = in;
1557 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_PREREAD);
1558
1559 rqe = RING_GET_PRODUCER_ITEM_VA(rq->ring, struct oce_nic_rqe);
1560 rqe->u0.s.frag_pa_hi = ADDR_HI(segs[0].ds_addr);
1561 rqe->u0.s.frag_pa_lo = ADDR_LO(segs[0].ds_addr);
1562 DW_SWAP(u32ptr(rqe), sizeof(struct oce_nic_rqe));
1563 RING_PUT(rq->ring, 1);
1564 added++;
1565 rq->pending++;
1566 }
1567 if (added != 0) {
1568 for (i = added / OCE_MAX_RQ_POSTS; i > 0; i--) {
1569 rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS;
1570 rxdb_reg.bits.qid = rq->rq_id;
1571 OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
1572 added -= OCE_MAX_RQ_POSTS;
1573 }
1574 if (added > 0) {
1575 rxdb_reg.bits.qid = rq->rq_id;
1576 rxdb_reg.bits.num_posted = added;
1577 OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
1578 }
1579 }
1580
1581 return 0;
1582 }
1583
1584
1585 /* Handle the Completion Queue for receive */
1586 uint16_t
oce_rq_handler(void * arg)1587 oce_rq_handler(void *arg)
1588 {
1589 struct oce_rq *rq = (struct oce_rq *)arg;
1590 struct oce_cq *cq = rq->cq;
1591 POCE_SOFTC sc = rq->parent;
1592 struct oce_nic_rx_cqe *cqe;
1593 int num_cqes = 0, rq_buffers_used = 0;
1594
1595 bus_dmamap_sync(cq->ring->dma.tag,
1596 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1597 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
1598 while (cqe->u0.dw[2]) {
1599 DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe));
1600
1601 RING_GET(rq->ring, 1);
1602 if (cqe->u0.s.error == 0) {
1603 oce_rx(rq, cqe->u0.s.frag_index, cqe);
1604 } else {
1605 rq->rx_stats.rxcp_err++;
1606 sc->ifp->if_ierrors++;
1607 /* Post L3/L4 errors to stack.*/
1608 oce_rx(rq, cqe->u0.s.frag_index, cqe);
1609 }
1610 rq->rx_stats.rx_compl++;
1611 cqe->u0.dw[2] = 0;
1612
1613 #if defined(INET6) || defined(INET)
1614 #if 0 /* XXX swildner: LRO */
1615 if (IF_LRO_ENABLED(sc) && rq->lro_pkts_queued >= 16) {
1616 oce_rx_flush_lro(rq);
1617 }
1618 #endif
1619 #endif
1620
1621 RING_GET(cq->ring, 1);
1622 bus_dmamap_sync(cq->ring->dma.tag,
1623 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
1624 cqe =
1625 RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
1626 num_cqes++;
1627 if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
1628 break;
1629 }
1630
1631 #if defined(INET6) || defined(INET)
1632 #if 0 /* XXX swildner: LRO */
1633 if (IF_LRO_ENABLED(sc))
1634 oce_rx_flush_lro(rq);
1635 #endif
1636 #endif
1637
1638 if (num_cqes) {
1639 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
1640 rq_buffers_used = OCE_RQ_PACKET_ARRAY_SIZE - rq->pending;
1641 if (rq_buffers_used > 1)
1642 oce_alloc_rx_bufs(rq, (rq_buffers_used - 1));
1643 }
1644
1645 return 0;
1646
1647 }
1648
1649
1650
1651
1652 /*****************************************************************************
1653 * Helper function prototypes in this file *
1654 *****************************************************************************/
1655
1656 static int
oce_attach_ifp(POCE_SOFTC sc)1657 oce_attach_ifp(POCE_SOFTC sc)
1658 {
1659
1660 sc->ifp = if_alloc(IFT_ETHER);
1661 if (!sc->ifp)
1662 return ENOMEM;
1663
1664 ifmedia_init(&sc->media, IFM_IMASK, oce_media_change, oce_media_status);
1665 ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
1666 ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
1667
1668 sc->ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
1669 sc->ifp->if_ioctl = oce_ioctl;
1670 sc->ifp->if_start = oce_start;
1671 sc->ifp->if_init = oce_init;
1672 sc->ifp->if_mtu = ETHERMTU;
1673 sc->ifp->if_softc = sc;
1674 #if 0 /* XXX swildner: MULTIQUEUE */
1675 sc->ifp->if_transmit = oce_multiq_start;
1676 sc->ifp->if_qflush = oce_multiq_flush;
1677 #endif
1678
1679 if_initname(sc->ifp,
1680 device_get_name(sc->dev), device_get_unit(sc->dev));
1681
1682 sc->ifp->if_nmbclusters = sc->nrqs * sc->rq[0]->cfg.q_len;
1683
1684 ifq_set_maxlen(&sc->ifp->if_snd, OCE_MAX_TX_DESC - 1);
1685 ifq_set_ready(&sc->ifp->if_snd);
1686
1687 sc->ifp->if_hwassist = OCE_IF_HWASSIST;
1688 sc->ifp->if_hwassist |= CSUM_TSO;
1689 sc->ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP);
1690
1691 sc->ifp->if_capabilities = OCE_IF_CAPABILITIES;
1692 sc->ifp->if_capabilities |= IFCAP_HWCSUM;
1693 #if 0 /* XXX swildner: VLAN_HWFILTER */
1694 sc->ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
1695 #endif
1696
1697 #if defined(INET6) || defined(INET)
1698 sc->ifp->if_capabilities |= IFCAP_TSO;
1699 #if 0 /* XXX swildner: LRO */
1700 sc->ifp->if_capabilities |= IFCAP_LRO;
1701 #endif
1702 #if 0 /* XXX swildner: VLAN_HWTSO */
1703 sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
1704 #endif
1705 #endif
1706
1707 sc->ifp->if_capenable = sc->ifp->if_capabilities;
1708 sc->ifp->if_baudrate = IF_Gbps(10UL);
1709
1710 ether_ifattach(sc->ifp, sc->macaddr.mac_addr, NULL);
1711
1712 return 0;
1713 }
1714
1715
1716 static void
oce_add_vlan(void * arg,struct ifnet * ifp,uint16_t vtag)1717 oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
1718 {
1719 POCE_SOFTC sc = ifp->if_softc;
1720
1721 if (ifp->if_softc != arg)
1722 return;
1723 if ((vtag == 0) || (vtag > 4095))
1724 return;
1725
1726 sc->vlan_tag[vtag] = 1;
1727 sc->vlans_added++;
1728 oce_vid_config(sc);
1729 }
1730
1731
1732 static void
oce_del_vlan(void * arg,struct ifnet * ifp,uint16_t vtag)1733 oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
1734 {
1735 POCE_SOFTC sc = ifp->if_softc;
1736
1737 if (ifp->if_softc != arg)
1738 return;
1739 if ((vtag == 0) || (vtag > 4095))
1740 return;
1741
1742 sc->vlan_tag[vtag] = 0;
1743 sc->vlans_added--;
1744 oce_vid_config(sc);
1745 }
1746
1747
1748 /*
1749 * A max of 64 vlans can be configured in BE. If the user configures
1750 * more, place the card in vlan promiscuous mode.
1751 */
1752 static int
oce_vid_config(POCE_SOFTC sc)1753 oce_vid_config(POCE_SOFTC sc)
1754 {
1755 #if 0 /* XXX swildner: VLAN_HWFILTER */
1756 struct normal_vlan vtags[MAX_VLANFILTER_SIZE];
1757 uint16_t ntags = 0, i;
1758 #endif
1759 int status = 0;
1760
1761 #if 0 /* XXX swildner: VLAN_HWFILTER */
1762 if ((sc->vlans_added <= MAX_VLANFILTER_SIZE) &&
1763 (sc->ifp->if_capenable & IFCAP_VLAN_HWFILTER)) {
1764 for (i = 0; i < MAX_VLANS; i++) {
1765 if (sc->vlan_tag[i]) {
1766 vtags[ntags].vtag = i;
1767 ntags++;
1768 }
1769 }
1770 if (ntags)
1771 status = oce_config_vlan(sc, (uint8_t) sc->if_id,
1772 vtags, ntags, 1, 0);
1773 } else
1774 #endif
1775 status = oce_config_vlan(sc, (uint8_t) sc->if_id,
1776 NULL, 0, 1, 1);
1777 return status;
1778 }
1779
1780
1781 static void
oce_mac_addr_set(POCE_SOFTC sc)1782 oce_mac_addr_set(POCE_SOFTC sc)
1783 {
1784 uint32_t old_pmac_id = sc->pmac_id;
1785 int status = 0;
1786
1787
1788 status = bcmp((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
1789 sc->macaddr.size_of_struct);
1790 if (!status)
1791 return;
1792
1793 status = oce_mbox_macaddr_add(sc, (uint8_t *)(IF_LLADDR(sc->ifp)),
1794 sc->if_id, &sc->pmac_id);
1795 if (!status) {
1796 status = oce_mbox_macaddr_del(sc, sc->if_id, old_pmac_id);
1797 bcopy((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
1798 sc->macaddr.size_of_struct);
1799 }
1800 if (status)
1801 device_printf(sc->dev, "Failed update macaddress\n");
1802
1803 }
1804
1805
1806 static int
oce_handle_passthrough(struct ifnet * ifp,caddr_t data)1807 oce_handle_passthrough(struct ifnet *ifp, caddr_t data)
1808 {
1809 POCE_SOFTC sc = ifp->if_softc;
1810 struct ifreq *ifr = (struct ifreq *)data;
1811 int rc = ENXIO;
1812 char cookie[32] = {0};
1813 void *priv_data = (void *)ifr->ifr_data;
1814 void *ioctl_ptr;
1815 uint32_t req_size;
1816 struct mbx_hdr req;
1817 OCE_DMA_MEM dma_mem;
1818 struct mbx_common_get_cntl_attr *fw_cmd;
1819
1820 if (copyin(priv_data, cookie, strlen(IOCTL_COOKIE)))
1821 return EFAULT;
1822
1823 if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE)))
1824 return EINVAL;
1825
1826 ioctl_ptr = (char *)priv_data + strlen(IOCTL_COOKIE);
1827 if (copyin(ioctl_ptr, &req, sizeof(struct mbx_hdr)))
1828 return EFAULT;
1829
1830 req_size = le32toh(req.u0.req.request_length);
1831 if (req_size > 65536)
1832 return EINVAL;
1833
1834 req_size += sizeof(struct mbx_hdr);
1835 rc = oce_dma_alloc(sc, req_size, &dma_mem, 0);
1836 if (rc)
1837 return ENOMEM;
1838
1839 if (copyin(ioctl_ptr, OCE_DMAPTR(&dma_mem,char), req_size)) {
1840 rc = EFAULT;
1841 goto dma_free;
1842 }
1843
1844 rc = oce_pass_through_mbox(sc, &dma_mem, req_size);
1845 if (rc) {
1846 rc = EIO;
1847 goto dma_free;
1848 }
1849
1850 if (copyout(OCE_DMAPTR(&dma_mem,char), ioctl_ptr, req_size))
1851 rc = EFAULT;
1852
1853 /*
1854 firmware is filling all the attributes for this ioctl except
1855 the driver version..so fill it
1856 */
1857 if(req.u0.rsp.opcode == OPCODE_COMMON_GET_CNTL_ATTRIBUTES) {
1858 fw_cmd = (struct mbx_common_get_cntl_attr *) ioctl_ptr;
1859 strncpy(fw_cmd->params.rsp.cntl_attr_info.hba_attr.drv_ver_str,
1860 COMPONENT_REVISION, strlen(COMPONENT_REVISION));
1861 }
1862
1863 dma_free:
1864 oce_dma_free(sc, &dma_mem);
1865 return rc;
1866
1867 }
1868
1869 static void
oce_eqd_set_periodic(POCE_SOFTC sc)1870 oce_eqd_set_periodic(POCE_SOFTC sc)
1871 {
1872 struct oce_set_eqd set_eqd[OCE_MAX_EQ];
1873 struct oce_aic_obj *aic;
1874 struct oce_eq *eqo;
1875 uint64_t now = 0, delta;
1876 int eqd, i, num = 0;
1877 uint32_t ips = 0;
1878 int tps;
1879
1880 for (i = 0 ; i < sc->neqs; i++) {
1881 eqo = sc->eq[i];
1882 aic = &sc->aic_obj[i];
1883 /* When setting the static eq delay from the user space */
1884 if (!aic->enable) {
1885 eqd = aic->et_eqd;
1886 goto modify_eqd;
1887 }
1888
1889 now = ticks;
1890
1891 /* Over flow check */
1892 if ((now < aic->ticks) || (eqo->intr < aic->intr_prev))
1893 goto done;
1894
1895 delta = now - aic->ticks;
1896 tps = delta/hz;
1897
1898 /* Interrupt rate based on elapsed ticks */
1899 if(tps)
1900 ips = (uint32_t)(eqo->intr - aic->intr_prev) / tps;
1901
1902 if (ips > INTR_RATE_HWM)
1903 eqd = aic->cur_eqd + 20;
1904 else if (ips < INTR_RATE_LWM)
1905 eqd = aic->cur_eqd / 2;
1906 else
1907 goto done;
1908
1909 if (eqd < 10)
1910 eqd = 0;
1911
1912 /* Make sure that the eq delay is in the known range */
1913 eqd = min(eqd, aic->max_eqd);
1914 eqd = max(eqd, aic->min_eqd);
1915
1916 modify_eqd:
1917 if (eqd != aic->cur_eqd) {
1918 set_eqd[num].delay_multiplier = (eqd * 65)/100;
1919 set_eqd[num].eq_id = eqo->eq_id;
1920 aic->cur_eqd = eqd;
1921 num++;
1922 }
1923 done:
1924 aic->intr_prev = eqo->intr;
1925 aic->ticks = now;
1926 }
1927
1928 /* Is there atleast one eq that needs to be modified? */
1929 if(num)
1930 oce_mbox_eqd_modify_periodic(sc, set_eqd, num);
1931
1932 }
1933
1934 static void
oce_local_timer(void * arg)1935 oce_local_timer(void *arg)
1936 {
1937 POCE_SOFTC sc = arg;
1938 int i = 0;
1939
1940 lwkt_serialize_enter(sc->ifp->if_serializer);
1941 oce_refresh_nic_stats(sc);
1942 oce_refresh_queue_stats(sc);
1943 oce_mac_addr_set(sc);
1944
1945 /* TX Watch Dog*/
1946 for (i = 0; i < sc->nwqs; i++)
1947 oce_tx_restart(sc, sc->wq[i]);
1948
1949 /* calculate and set the eq delay for optimal interrupt rate */
1950 if (IS_BE(sc) || IS_SH(sc))
1951 oce_eqd_set_periodic(sc);
1952
1953 callout_reset(&sc->timer, hz, oce_local_timer, sc);
1954 lwkt_serialize_exit(sc->ifp->if_serializer);
1955 }
1956
1957
1958 /* NOTE : This should only be called holding
1959 * DEVICE_LOCK.
1960 */
1961 static void
oce_if_deactivate(POCE_SOFTC sc)1962 oce_if_deactivate(POCE_SOFTC sc)
1963 {
1964 int i, mtime = 0;
1965 int wait_req = 0;
1966 struct oce_rq *rq;
1967 struct oce_wq *wq;
1968 struct oce_eq *eq;
1969
1970 sc->ifp->if_flags &= ~IFF_RUNNING;
1971 ifq_clr_oactive(&sc->ifp->if_snd);
1972
1973 /*Wait for max of 400ms for TX completions to be done */
1974 while (mtime < 400) {
1975 wait_req = 0;
1976 for_all_wq_queues(sc, wq, i) {
1977 if (wq->ring->num_used) {
1978 wait_req = 1;
1979 DELAY(1);
1980 break;
1981 }
1982 }
1983 mtime += 1;
1984 if (!wait_req)
1985 break;
1986 }
1987
1988 /* Stop intrs and finish any bottom halves pending */
1989 oce_hw_intr_disable(sc);
1990
1991 /* Since taskqueue_drain takes a Gaint Lock, We should not acquire
1992 any other lock. So unlock device lock and require after
1993 completing taskqueue_drain.
1994 */
1995 UNLOCK(&sc->dev_lock);
1996 for (i = 0; i < sc->intr_count; i++) {
1997 if (sc->intrs[i].tq != NULL) {
1998 taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task);
1999 }
2000 }
2001 LOCK(&sc->dev_lock);
2002
2003 /* Delete RX queue in card with flush param */
2004 oce_stop_rx(sc);
2005
2006 /* Invalidate any pending cq and eq entries*/
2007 for_all_evnt_queues(sc, eq, i)
2008 oce_drain_eq(eq);
2009 for_all_rq_queues(sc, rq, i)
2010 oce_drain_rq_cq(rq);
2011 for_all_wq_queues(sc, wq, i)
2012 oce_drain_wq_cq(wq);
2013
2014 /* But still we need to get MCC aync events.
2015 So enable intrs and also arm first EQ
2016 */
2017 oce_hw_intr_enable(sc);
2018 oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
2019
2020 DELAY(10);
2021 }
2022
2023
2024 static void
oce_if_activate(POCE_SOFTC sc)2025 oce_if_activate(POCE_SOFTC sc)
2026 {
2027 struct oce_eq *eq;
2028 struct oce_rq *rq;
2029 struct oce_wq *wq;
2030 int i, rc = 0;
2031
2032 sc->ifp->if_flags |= IFF_RUNNING;
2033
2034 oce_hw_intr_disable(sc);
2035
2036 oce_start_rx(sc);
2037
2038 for_all_rq_queues(sc, rq, i) {
2039 rc = oce_start_rq(rq);
2040 if (rc)
2041 device_printf(sc->dev, "Unable to start RX\n");
2042 }
2043
2044 for_all_wq_queues(sc, wq, i) {
2045 rc = oce_start_wq(wq);
2046 if (rc)
2047 device_printf(sc->dev, "Unable to start TX\n");
2048 }
2049
2050
2051 for_all_evnt_queues(sc, eq, i)
2052 oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
2053
2054 oce_hw_intr_enable(sc);
2055
2056 }
2057
2058 static void
process_link_state(POCE_SOFTC sc,struct oce_async_cqe_link_state * acqe)2059 process_link_state(POCE_SOFTC sc, struct oce_async_cqe_link_state *acqe)
2060 {
2061 /* Update Link status */
2062 if ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) ==
2063 ASYNC_EVENT_LINK_UP) {
2064 sc->link_status = ASYNC_EVENT_LINK_UP;
2065 if_link_state_change(sc->ifp);
2066 } else {
2067 sc->link_status = ASYNC_EVENT_LINK_DOWN;
2068 if_link_state_change(sc->ifp);
2069 }
2070
2071 /* Update speed */
2072 sc->link_speed = acqe->u0.s.speed;
2073 sc->qos_link_speed = (uint32_t) acqe->u0.s.qos_link_speed * 10;
2074
2075 }
2076
2077
2078 /* Handle the Completion Queue for the Mailbox/Async notifications */
2079 uint16_t
oce_mq_handler(void * arg)2080 oce_mq_handler(void *arg)
2081 {
2082 struct oce_mq *mq = (struct oce_mq *)arg;
2083 POCE_SOFTC sc = mq->parent;
2084 struct oce_cq *cq = mq->cq;
2085 int num_cqes = 0, evt_type = 0, optype = 0;
2086 struct oce_mq_cqe *cqe;
2087 struct oce_async_cqe_link_state *acqe;
2088 struct oce_async_event_grp5_pvid_state *gcqe;
2089 struct oce_async_event_qnq *dbgcqe;
2090
2091
2092 bus_dmamap_sync(cq->ring->dma.tag,
2093 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2094 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
2095
2096 while (cqe->u0.dw[3]) {
2097 DW_SWAP((uint32_t *) cqe, sizeof(oce_mq_cqe));
2098 if (cqe->u0.s.async_event) {
2099 evt_type = cqe->u0.s.event_type;
2100 optype = cqe->u0.s.async_type;
2101 if (evt_type == ASYNC_EVENT_CODE_LINK_STATE) {
2102 /* Link status evt */
2103 acqe = (struct oce_async_cqe_link_state *)cqe;
2104 process_link_state(sc, acqe);
2105 } else if ((evt_type == ASYNC_EVENT_GRP5) &&
2106 (optype == ASYNC_EVENT_PVID_STATE)) {
2107 /* GRP5 PVID */
2108 gcqe =
2109 (struct oce_async_event_grp5_pvid_state *)cqe;
2110 if (gcqe->enabled)
2111 sc->pvid = gcqe->tag & VLAN_VID_MASK;
2112 else
2113 sc->pvid = 0;
2114
2115 }
2116 else if(evt_type == ASYNC_EVENT_CODE_DEBUG &&
2117 optype == ASYNC_EVENT_DEBUG_QNQ) {
2118 dbgcqe =
2119 (struct oce_async_event_qnq *)cqe;
2120 if(dbgcqe->valid)
2121 sc->qnqid = dbgcqe->vlan_tag;
2122 sc->qnq_debug_event = TRUE;
2123 }
2124 }
2125 cqe->u0.dw[3] = 0;
2126 RING_GET(cq->ring, 1);
2127 bus_dmamap_sync(cq->ring->dma.tag,
2128 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
2129 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
2130 num_cqes++;
2131 }
2132
2133 if (num_cqes)
2134 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
2135
2136 return 0;
2137 }
2138
2139
2140 static void
setup_max_queues_want(POCE_SOFTC sc)2141 setup_max_queues_want(POCE_SOFTC sc)
2142 {
2143 /* Check if it is FLEX machine. Is so dont use RSS */
2144 if ((sc->function_mode & FNM_FLEX10_MODE) ||
2145 (sc->function_mode & FNM_UMC_MODE) ||
2146 (sc->function_mode & FNM_VNIC_MODE) ||
2147 (!is_rss_enabled(sc)) ||
2148 (sc->flags & OCE_FLAGS_BE2)) {
2149 sc->nrqs = 1;
2150 sc->nwqs = 1;
2151 }
2152 }
2153
2154
2155 static void
update_queues_got(POCE_SOFTC sc)2156 update_queues_got(POCE_SOFTC sc)
2157 {
2158 if (is_rss_enabled(sc)) {
2159 sc->nrqs = sc->intr_count + 1;
2160 sc->nwqs = sc->intr_count;
2161 } else {
2162 sc->nrqs = 1;
2163 sc->nwqs = 1;
2164 }
2165 }
2166
2167 static int
oce_check_ipv6_ext_hdr(struct mbuf * m)2168 oce_check_ipv6_ext_hdr(struct mbuf *m)
2169 {
2170 struct ether_header *eh = mtod(m, struct ether_header *);
2171 caddr_t m_datatemp = m->m_data;
2172
2173 if (eh->ether_type == htons(ETHERTYPE_IPV6)) {
2174 m->m_data += sizeof(struct ether_header);
2175 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
2176
2177 if((ip6->ip6_nxt != IPPROTO_TCP) && \
2178 (ip6->ip6_nxt != IPPROTO_UDP)){
2179 struct ip6_ext *ip6e = NULL;
2180 m->m_data += sizeof(struct ip6_hdr);
2181
2182 ip6e = (struct ip6_ext *) mtod(m, struct ip6_ext *);
2183 if(ip6e->ip6e_len == 0xff) {
2184 m->m_data = m_datatemp;
2185 return TRUE;
2186 }
2187 }
2188 m->m_data = m_datatemp;
2189 }
2190 return FALSE;
2191 }
2192
2193 static int
is_be3_a1(POCE_SOFTC sc)2194 is_be3_a1(POCE_SOFTC sc)
2195 {
2196 if((sc->flags & OCE_FLAGS_BE3) && ((sc->asic_revision & 0xFF) < 2)) {
2197 return TRUE;
2198 }
2199 return FALSE;
2200 }
2201
2202 static struct mbuf *
oce_insert_vlan_tag(POCE_SOFTC sc,struct mbuf * m,boolean_t * complete)2203 oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete)
2204 {
2205 uint16_t vlan_tag = 0;
2206
2207 if(!M_WRITABLE(m))
2208 return NULL;
2209
2210 #if 0 /* XXX swildner: ETHER_VTAG */
2211 /* Embed vlan tag in the packet if it is not part of it */
2212 if(m->m_flags & M_VLANTAG) {
2213 vlan_tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
2214 m->m_flags &= ~M_VLANTAG;
2215 }
2216 #endif
2217
2218 /* if UMC, ignore vlan tag insertion and instead insert pvid */
2219 if(sc->pvid) {
2220 if(!vlan_tag)
2221 vlan_tag = sc->pvid;
2222 *complete = FALSE;
2223 }
2224
2225 #if 0 /* XXX swildner: ETHER_VTAG */
2226 if(vlan_tag) {
2227 m = ether_vlanencap(m, vlan_tag);
2228 }
2229
2230 if(sc->qnqid) {
2231 m = ether_vlanencap(m, sc->qnqid);
2232 *complete = FALSE;
2233 }
2234 #endif
2235 return m;
2236 }
2237
2238 static int
oce_tx_asic_stall_verify(POCE_SOFTC sc,struct mbuf * m)2239 oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m)
2240 {
2241 if(is_be3_a1(sc) && IS_QNQ_OR_UMC(sc) && \
2242 oce_check_ipv6_ext_hdr(m)) {
2243 return TRUE;
2244 }
2245 return FALSE;
2246 }
2247
2248 static void
oce_get_config(POCE_SOFTC sc)2249 oce_get_config(POCE_SOFTC sc)
2250 {
2251 int rc = 0;
2252 uint32_t max_rss = 0;
2253
2254 if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
2255 max_rss = OCE_LEGACY_MODE_RSS;
2256 else
2257 max_rss = OCE_MAX_RSS;
2258
2259 if (!IS_BE(sc)) {
2260 rc = oce_get_func_config(sc);
2261 if (rc) {
2262 sc->nwqs = OCE_MAX_WQ;
2263 sc->nrssqs = max_rss;
2264 sc->nrqs = sc->nrssqs + 1;
2265 }
2266 }
2267 else {
2268 rc = oce_get_profile_config(sc);
2269 sc->nrssqs = max_rss;
2270 sc->nrqs = sc->nrssqs + 1;
2271 if (rc)
2272 sc->nwqs = OCE_MAX_WQ;
2273 }
2274 }
2275