1/* $OpenBSD: if_oce.c,v 1.109 2024/05/24 06:02:56 jsg Exp $ */ 2 3/* 4 * Copyright (c) 2012 Mike Belopuhov 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19/*- 20 * Copyright (C) 2012 Emulex 21 * All rights reserved. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions are met: 25 * 26 * 1. Redistributions of source code must retain the above copyright notice, 27 * this list of conditions and the following disclaimer. 28 * 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 33 * 3. Neither the name of the Emulex Corporation nor the names of its 34 * contributors may be used to endorse or promote products derived from 35 * this software without specific prior written permission. 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 41 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 * POSSIBILITY OF SUCH DAMAGE. 48 * 49 * Contact Information: 50 * freebsd-drivers@emulex.com 51 * 52 * Emulex 53 * 3333 Susan Street 54 * Costa Mesa, CA 92626 55 */ 56 57#include "bpfilter.h" 58#include "vlan.h" 59 60#include <sys/param.h> 61#include <sys/systm.h> 62#include <sys/sockio.h> 63#include <sys/mbuf.h> 64#include <sys/malloc.h> 65#include <sys/device.h> 66#include <sys/socket.h> 67#include <sys/queue.h> 68#include <sys/timeout.h> 69#include <sys/pool.h> 70 71#include <net/if.h> 72#include <net/if_media.h> 73 74#include <netinet/in.h> 75#include <netinet/if_ether.h> 76 77#if NBPFILTER > 0 78#include <net/bpf.h> 79#endif 80 81#include <dev/pci/pcireg.h> 82#include <dev/pci/pcivar.h> 83#include <dev/pci/pcidevs.h> 84 85#include <dev/pci/if_ocereg.h> 86 87#ifndef TRUE 88#define TRUE 1 89#endif 90#ifndef FALSE 91#define FALSE 0 92#endif 93 94#define OCE_MBX_TIMEOUT 5 95 96#define OCE_MAX_PAYLOAD 65536 97 98#define OCE_TX_RING_SIZE 512 99#define OCE_RX_RING_SIZE 1024 100 101/* This should be powers of 2. Like 2,4,8 & 16 */ 102#define OCE_MAX_RSS 4 /* TODO: 8 */ 103#define OCE_MAX_RQ OCE_MAX_RSS + 1 /* one default queue */ 104#define OCE_MAX_WQ 8 105 106#define OCE_MAX_EQ 32 107#define OCE_MAX_CQ OCE_MAX_RQ + OCE_MAX_WQ + 1 /* one MCC queue */ 108#define OCE_MAX_CQ_EQ 8 /* Max CQ that can attached to an EQ */ 109 110#define OCE_DEFAULT_EQD 80 111 112#define OCE_MIN_MTU 256 113#define OCE_MAX_MTU 9000 114 115#define OCE_MAX_RQ_COMPL 64 116#define OCE_MAX_RQ_POSTS 255 117#define OCE_RX_BUF_SIZE 2048 118 119#define OCE_MAX_TX_ELEMENTS 29 120#define OCE_MAX_TX_DESC 1024 121#define OCE_MAX_TX_SIZE 65535 122 123#define OCE_MEM_KVA(_m) ((void *)((_m)->vaddr)) 124#define OCE_MEM_DVA(_m) ((_m)->paddr) 125 126#define OCE_WQ_FOREACH(sc, wq, i) \ 127 for (i = 0, wq = sc->sc_wq[0]; i < sc->sc_nwq; i++, wq = sc->sc_wq[i]) 128#define OCE_RQ_FOREACH(sc, rq, i) \ 129 for (i = 0, rq = sc->sc_rq[0]; i < sc->sc_nrq; i++, rq = sc->sc_rq[i]) 130#define OCE_EQ_FOREACH(sc, eq, i) \ 131 for (i = 0, eq = sc->sc_eq[0]; i < sc->sc_neq; i++, eq = sc->sc_eq[i]) 132#define OCE_CQ_FOREACH(sc, cq, i) \ 133 for (i = 0, cq = sc->sc_cq[0]; i < sc->sc_ncq; i++, cq = sc->sc_cq[i]) 134#define OCE_RING_FOREACH(_r, _v, _c) \ 135 for ((_v) = oce_ring_first(_r); _c; (_v) = oce_ring_next(_r)) 136 137static inline int 138ilog2(unsigned int v) 139{ 140 int r = 0; 141 142 while (v >>= 1) 143 r++; 144 return (r); 145} 146 147struct oce_pkt { 148 struct mbuf * mbuf; 149 bus_dmamap_t map; 150 int nsegs; 151 SIMPLEQ_ENTRY(oce_pkt) entry; 152}; 153SIMPLEQ_HEAD(oce_pkt_list, oce_pkt); 154 155struct oce_dma_mem { 156 bus_dma_tag_t tag; 157 bus_dmamap_t map; 158 bus_dma_segment_t segs; 159 int nsegs; 160 bus_size_t size; 161 caddr_t vaddr; 162 bus_addr_t paddr; 163}; 164 165struct oce_ring { 166 int index; 167 int nitems; 168 int nused; 169 int isize; 170 struct oce_dma_mem dma; 171}; 172 173struct oce_softc; 174 175enum cq_len { 176 CQ_LEN_256 = 256, 177 CQ_LEN_512 = 512, 178 CQ_LEN_1024 = 1024 179}; 180 181enum eq_len { 182 EQ_LEN_256 = 256, 183 EQ_LEN_512 = 512, 184 EQ_LEN_1024 = 1024, 185 EQ_LEN_2048 = 2048, 186 EQ_LEN_4096 = 4096 187}; 188 189enum eqe_size { 190 EQE_SIZE_4 = 4, 191 EQE_SIZE_16 = 16 192}; 193 194enum qtype { 195 QTYPE_EQ, 196 QTYPE_MQ, 197 QTYPE_WQ, 198 QTYPE_RQ, 199 QTYPE_CQ, 200 QTYPE_RSS 201}; 202 203struct oce_eq { 204 struct oce_softc * sc; 205 struct oce_ring * ring; 206 enum qtype type; 207 int id; 208 209 struct oce_cq * cq[OCE_MAX_CQ_EQ]; 210 int cq_valid; 211 212 int nitems; 213 int isize; 214 int delay; 215}; 216 217struct oce_cq { 218 struct oce_softc * sc; 219 struct oce_ring * ring; 220 enum qtype type; 221 int id; 222 223 struct oce_eq * eq; 224 225 void (*cq_intr)(void *); 226 void * cb_arg; 227 228 int nitems; 229 int nodelay; 230 int eventable; 231 int ncoalesce; 232}; 233 234struct oce_mq { 235 struct oce_softc * sc; 236 struct oce_ring * ring; 237 enum qtype type; 238 int id; 239 240 struct oce_cq * cq; 241 242 int nitems; 243}; 244 245struct oce_wq { 246 struct oce_softc * sc; 247 struct oce_ring * ring; 248 enum qtype type; 249 int id; 250 251 struct oce_cq * cq; 252 253 struct oce_pkt_list pkt_list; 254 struct oce_pkt_list pkt_free; 255 256 int nitems; 257}; 258 259struct oce_rq { 260 struct oce_softc * sc; 261 struct oce_ring * ring; 262 enum qtype type; 263 int id; 264 265 struct oce_cq * cq; 266 267 struct if_rxring rxring; 268 struct oce_pkt_list pkt_list; 269 struct oce_pkt_list pkt_free; 270 271 uint32_t rss_cpuid; 272 273#ifdef OCE_LRO 274 struct lro_ctrl lro; 275 int lro_pkts_queued; 276#endif 277 278 int nitems; 279 int fragsize; 280 int mtu; 281 int rss; 282}; 283 284struct oce_softc { 285 struct device sc_dev; 286 287 uint sc_flags; 288#define OCE_F_BE2 0x00000001 289#define OCE_F_BE3 0x00000002 290#define OCE_F_XE201 0x00000008 291#define OCE_F_BE3_NATIVE 0x00000100 292#define OCE_F_RESET_RQD 0x00001000 293#define OCE_F_MBOX_ENDIAN_RQD 0x00002000 294 295 bus_dma_tag_t sc_dmat; 296 297 bus_space_tag_t sc_cfg_iot; 298 bus_space_handle_t sc_cfg_ioh; 299 bus_size_t sc_cfg_size; 300 301 bus_space_tag_t sc_csr_iot; 302 bus_space_handle_t sc_csr_ioh; 303 bus_size_t sc_csr_size; 304 305 bus_space_tag_t sc_db_iot; 306 bus_space_handle_t sc_db_ioh; 307 bus_size_t sc_db_size; 308 309 void * sc_ih; 310 311 struct arpcom sc_ac; 312 struct ifmedia sc_media; 313 ushort sc_link_up; 314 ushort sc_link_speed; 315 uint64_t sc_fc; 316 317 struct oce_dma_mem sc_mbx; 318 struct oce_dma_mem sc_pld; 319 320 uint sc_port; 321 uint sc_fmode; 322 323 struct oce_wq * sc_wq[OCE_MAX_WQ]; /* TX work queues */ 324 struct oce_rq * sc_rq[OCE_MAX_RQ]; /* RX work queues */ 325 struct oce_cq * sc_cq[OCE_MAX_CQ]; /* Completion queues */ 326 struct oce_eq * sc_eq[OCE_MAX_EQ]; /* Event queues */ 327 struct oce_mq * sc_mq; /* Mailbox queue */ 328 329 ushort sc_neq; 330 ushort sc_ncq; 331 ushort sc_nrq; 332 ushort sc_nwq; 333 ushort sc_nintr; 334 335 ushort sc_tx_ring_size; 336 ushort sc_rx_ring_size; 337 ushort sc_rss_enable; 338 339 uint32_t sc_if_id; /* interface ID */ 340 uint32_t sc_pmac_id; /* PMAC id */ 341 char sc_macaddr[ETHER_ADDR_LEN]; 342 343 uint32_t sc_pvid; 344 345 uint64_t sc_rx_errors; 346 uint64_t sc_tx_errors; 347 348 struct timeout sc_tick; 349 struct timeout sc_rxrefill; 350 351 void * sc_statcmd; 352}; 353 354#define IS_BE(sc) ISSET((sc)->sc_flags, OCE_F_BE2 | OCE_F_BE3) 355#define IS_XE201(sc) ISSET((sc)->sc_flags, OCE_F_XE201) 356 357#define ADDR_HI(x) ((uint32_t)((uint64_t)(x) >> 32)) 358#define ADDR_LO(x) ((uint32_t)((uint64_t)(x) & 0xffffffff)) 359 360#define IF_LRO_ENABLED(ifp) ISSET((ifp)->if_capabilities, IFCAP_LRO) 361 362int oce_match(struct device *, void *, void *); 363void oce_attach(struct device *, struct device *, void *); 364int oce_pci_alloc(struct oce_softc *, struct pci_attach_args *); 365void oce_attachhook(struct device *); 366void oce_attach_ifp(struct oce_softc *); 367int oce_ioctl(struct ifnet *, u_long, caddr_t); 368int oce_rxrinfo(struct oce_softc *, struct if_rxrinfo *); 369void oce_iff(struct oce_softc *); 370void oce_link_status(struct oce_softc *); 371void oce_media_status(struct ifnet *, struct ifmediareq *); 372int oce_media_change(struct ifnet *); 373void oce_tick(void *); 374void oce_init(void *); 375void oce_stop(struct oce_softc *); 376void oce_watchdog(struct ifnet *); 377void oce_start(struct ifnet *); 378int oce_encap(struct oce_softc *, struct mbuf **, int wqidx); 379#ifdef OCE_TSO 380struct mbuf * 381 oce_tso(struct oce_softc *, struct mbuf **); 382#endif 383int oce_intr(void *); 384void oce_intr_wq(void *); 385void oce_txeof(struct oce_wq *); 386void oce_intr_rq(void *); 387void oce_rxeof(struct oce_rq *, struct oce_nic_rx_cqe *); 388void oce_rxeoc(struct oce_rq *, struct oce_nic_rx_cqe *); 389int oce_vtp_valid(struct oce_softc *, struct oce_nic_rx_cqe *); 390int oce_port_valid(struct oce_softc *, struct oce_nic_rx_cqe *); 391#ifdef OCE_LRO 392void oce_flush_lro(struct oce_rq *); 393int oce_init_lro(struct oce_softc *); 394void oce_free_lro(struct oce_softc *); 395#endif 396int oce_get_buf(struct oce_rq *); 397int oce_alloc_rx_bufs(struct oce_rq *); 398void oce_refill_rx(void *); 399void oce_free_posted_rxbuf(struct oce_rq *); 400void oce_intr_mq(void *); 401void oce_link_event(struct oce_softc *, 402 struct oce_async_cqe_link_state *); 403 404int oce_init_queues(struct oce_softc *); 405void oce_release_queues(struct oce_softc *); 406struct oce_wq *oce_create_wq(struct oce_softc *, struct oce_eq *); 407void oce_drain_wq(struct oce_wq *); 408void oce_destroy_wq(struct oce_wq *); 409struct oce_rq * 410 oce_create_rq(struct oce_softc *, struct oce_eq *, int rss); 411void oce_drain_rq(struct oce_rq *); 412void oce_destroy_rq(struct oce_rq *); 413struct oce_eq * 414 oce_create_eq(struct oce_softc *); 415static inline void 416 oce_arm_eq(struct oce_eq *, int neqe, int rearm, int clearint); 417void oce_drain_eq(struct oce_eq *); 418void oce_destroy_eq(struct oce_eq *); 419struct oce_mq * 420 oce_create_mq(struct oce_softc *, struct oce_eq *); 421void oce_drain_mq(struct oce_mq *); 422void oce_destroy_mq(struct oce_mq *); 423struct oce_cq * 424 oce_create_cq(struct oce_softc *, struct oce_eq *, int nitems, 425 int isize, int eventable, int nodelay, int ncoalesce); 426static inline void 427 oce_arm_cq(struct oce_cq *, int ncqe, int rearm); 428void oce_destroy_cq(struct oce_cq *); 429 430int oce_dma_alloc(struct oce_softc *, bus_size_t, struct oce_dma_mem *); 431void oce_dma_free(struct oce_softc *, struct oce_dma_mem *); 432#define oce_dma_sync(d, f) \ 433 bus_dmamap_sync((d)->tag, (d)->map, 0, (d)->map->dm_mapsize, f) 434 435struct oce_ring * 436 oce_create_ring(struct oce_softc *, int nitems, int isize, int maxseg); 437void oce_destroy_ring(struct oce_softc *, struct oce_ring *); 438int oce_load_ring(struct oce_softc *, struct oce_ring *, 439 struct oce_pa *, int max_segs); 440static inline void * 441 oce_ring_get(struct oce_ring *); 442static inline void * 443 oce_ring_first(struct oce_ring *); 444static inline void * 445 oce_ring_next(struct oce_ring *); 446struct oce_pkt * 447 oce_pkt_alloc(struct oce_softc *, size_t size, int nsegs, 448 int maxsegsz); 449void oce_pkt_free(struct oce_softc *, struct oce_pkt *); 450static inline struct oce_pkt * 451 oce_pkt_get(struct oce_pkt_list *); 452static inline void 453 oce_pkt_put(struct oce_pkt_list *, struct oce_pkt *); 454 455int oce_init_fw(struct oce_softc *); 456int oce_mbox_init(struct oce_softc *); 457int oce_mbox_dispatch(struct oce_softc *); 458int oce_cmd(struct oce_softc *, int subsys, int opcode, int version, 459 void *payload, int length); 460void oce_first_mcc(struct oce_softc *); 461 462int oce_get_fw_config(struct oce_softc *); 463int oce_check_native_mode(struct oce_softc *); 464int oce_create_iface(struct oce_softc *, uint8_t *macaddr); 465int oce_config_vlan(struct oce_softc *, struct normal_vlan *vtags, 466 int nvtags, int untagged, int promisc); 467int oce_set_flow_control(struct oce_softc *, uint64_t); 468int oce_config_rss(struct oce_softc *, int enable); 469int oce_update_mcast(struct oce_softc *, uint8_t multi[][ETHER_ADDR_LEN], 470 int naddr); 471int oce_set_promisc(struct oce_softc *, int enable); 472int oce_get_link_status(struct oce_softc *); 473 474void oce_macaddr_set(struct oce_softc *); 475int oce_macaddr_get(struct oce_softc *, uint8_t *macaddr); 476int oce_macaddr_add(struct oce_softc *, uint8_t *macaddr, uint32_t *pmac); 477int oce_macaddr_del(struct oce_softc *, uint32_t pmac); 478 479int oce_new_rq(struct oce_softc *, struct oce_rq *); 480int oce_new_wq(struct oce_softc *, struct oce_wq *); 481int oce_new_mq(struct oce_softc *, struct oce_mq *); 482int oce_new_eq(struct oce_softc *, struct oce_eq *); 483int oce_new_cq(struct oce_softc *, struct oce_cq *); 484 485int oce_init_stats(struct oce_softc *); 486int oce_update_stats(struct oce_softc *); 487int oce_stats_be2(struct oce_softc *, uint64_t *, uint64_t *); 488int oce_stats_be3(struct oce_softc *, uint64_t *, uint64_t *); 489int oce_stats_xe(struct oce_softc *, uint64_t *, uint64_t *); 490 491struct pool *oce_pkt_pool; 492 493struct cfdriver oce_cd = { 494 NULL, "oce", DV_IFNET 495}; 496 497const struct cfattach oce_ca = { 498 sizeof(struct oce_softc), oce_match, oce_attach, NULL, NULL 499}; 500 501const struct pci_matchid oce_devices[] = { 502 { PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_BE2 }, 503 { PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_BE3 }, 504 { PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_OCBE2 }, 505 { PCI_VENDOR_SERVERENGINES, PCI_PRODUCT_SERVERENGINES_OCBE3 }, 506 { PCI_VENDOR_EMULEX, PCI_PRODUCT_EMULEX_XE201 }, 507}; 508 509int 510oce_match(struct device *parent, void *match, void *aux) 511{ 512 return (pci_matchbyid(aux, oce_devices, nitems(oce_devices))); 513} 514 515void 516oce_attach(struct device *parent, struct device *self, void *aux) 517{ 518 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 519 struct oce_softc *sc = (struct oce_softc *)self; 520 const char *intrstr = NULL; 521 pci_intr_handle_t ih; 522 523 switch (PCI_PRODUCT(pa->pa_id)) { 524 case PCI_PRODUCT_SERVERENGINES_BE2: 525 case PCI_PRODUCT_SERVERENGINES_OCBE2: 526 SET(sc->sc_flags, OCE_F_BE2); 527 break; 528 case PCI_PRODUCT_SERVERENGINES_BE3: 529 case PCI_PRODUCT_SERVERENGINES_OCBE3: 530 SET(sc->sc_flags, OCE_F_BE3); 531 break; 532 case PCI_PRODUCT_EMULEX_XE201: 533 SET(sc->sc_flags, OCE_F_XE201); 534 break; 535 } 536 537 sc->sc_dmat = pa->pa_dmat; 538 if (oce_pci_alloc(sc, pa)) 539 return; 540 541 sc->sc_tx_ring_size = OCE_TX_RING_SIZE; 542 sc->sc_rx_ring_size = OCE_RX_RING_SIZE; 543 544 /* create the bootstrap mailbox */ 545 if (oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->sc_mbx)) { 546 printf(": failed to allocate mailbox memory\n"); 547 return; 548 } 549 if (oce_dma_alloc(sc, OCE_MAX_PAYLOAD, &sc->sc_pld)) { 550 printf(": failed to allocate payload memory\n"); 551 goto fail_1; 552 } 553 554 if (oce_init_fw(sc)) 555 goto fail_2; 556 557 if (oce_mbox_init(sc)) { 558 printf(": failed to initialize mailbox\n"); 559 goto fail_2; 560 } 561 562 if (oce_get_fw_config(sc)) { 563 printf(": failed to get firmware configuration\n"); 564 goto fail_2; 565 } 566 567 if (ISSET(sc->sc_flags, OCE_F_BE3)) { 568 if (oce_check_native_mode(sc)) 569 goto fail_2; 570 } 571 572 if (oce_macaddr_get(sc, sc->sc_macaddr)) { 573 printf(": failed to fetch MAC address\n"); 574 goto fail_2; 575 } 576 memcpy(sc->sc_ac.ac_enaddr, sc->sc_macaddr, ETHER_ADDR_LEN); 577 578 if (oce_pkt_pool == NULL) { 579 oce_pkt_pool = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT); 580 if (oce_pkt_pool == NULL) { 581 printf(": unable to allocate descriptor pool\n"); 582 goto fail_2; 583 } 584 pool_init(oce_pkt_pool, sizeof(struct oce_pkt), 0, IPL_NET, 585 0, "ocepkts", NULL); 586 } 587 588 /* We allocate a single interrupt resource */ 589 sc->sc_nintr = 1; 590 if (pci_intr_map_msi(pa, &ih) != 0 && 591 pci_intr_map(pa, &ih) != 0) { 592 printf(": couldn't map interrupt\n"); 593 goto fail_2; 594 } 595 596 intrstr = pci_intr_string(pa->pa_pc, ih); 597 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, oce_intr, sc, 598 sc->sc_dev.dv_xname); 599 if (sc->sc_ih == NULL) { 600 printf(": couldn't establish interrupt\n"); 601 if (intrstr != NULL) 602 printf(" at %s", intrstr); 603 printf("\n"); 604 goto fail_2; 605 } 606 printf(": %s", intrstr); 607 608 if (oce_init_stats(sc)) 609 goto fail_3; 610 611 if (oce_init_queues(sc)) 612 goto fail_3; 613 614 oce_attach_ifp(sc); 615 616#ifdef OCE_LRO 617 if (oce_init_lro(sc)) 618 goto fail_4; 619#endif 620 621 timeout_set(&sc->sc_tick, oce_tick, sc); 622 timeout_set(&sc->sc_rxrefill, oce_refill_rx, sc); 623 624 config_mountroot(self, oce_attachhook); 625 626 printf(", address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr)); 627 628 return; 629 630#ifdef OCE_LRO 631fail_4: 632 oce_free_lro(sc); 633 ether_ifdetach(&sc->sc_ac.ac_if); 634 if_detach(&sc->sc_ac.ac_if); 635 oce_release_queues(sc); 636#endif 637fail_3: 638 pci_intr_disestablish(pa->pa_pc, sc->sc_ih); 639fail_2: 640 oce_dma_free(sc, &sc->sc_pld); 641fail_1: 642 oce_dma_free(sc, &sc->sc_mbx); 643} 644 645int 646oce_pci_alloc(struct oce_softc *sc, struct pci_attach_args *pa) 647{ 648 pcireg_t memtype, reg; 649 650 /* setup the device config region */ 651 if (ISSET(sc->sc_flags, OCE_F_BE2)) 652 reg = OCE_BAR_CFG_BE2; 653 else 654 reg = OCE_BAR_CFG; 655 656 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg); 657 if (pci_mapreg_map(pa, reg, memtype, 0, &sc->sc_cfg_iot, 658 &sc->sc_cfg_ioh, NULL, &sc->sc_cfg_size, 659 IS_BE(sc) ? 0 : 32768)) { 660 printf(": can't find cfg mem space\n"); 661 return (ENXIO); 662 } 663 664 /* 665 * Read the SLI_INTF register and determine whether we 666 * can use this port and its features 667 */ 668 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, OCE_INTF_REG_OFFSET); 669 if (OCE_SLI_SIGNATURE(reg) != OCE_INTF_VALID_SIG) { 670 printf(": invalid signature\n"); 671 goto fail_1; 672 } 673 if (OCE_SLI_REVISION(reg) != OCE_INTF_SLI_REV4) { 674 printf(": unsupported SLI revision\n"); 675 goto fail_1; 676 } 677 if (OCE_SLI_IFTYPE(reg) == OCE_INTF_IF_TYPE_1) 678 SET(sc->sc_flags, OCE_F_MBOX_ENDIAN_RQD); 679 if (OCE_SLI_HINT1(reg) == OCE_INTF_FUNC_RESET_REQD) 680 SET(sc->sc_flags, OCE_F_RESET_RQD); 681 682 /* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */ 683 if (IS_BE(sc)) { 684 /* set up CSR region */ 685 reg = OCE_BAR_CSR; 686 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg); 687 if (pci_mapreg_map(pa, reg, memtype, 0, &sc->sc_csr_iot, 688 &sc->sc_csr_ioh, NULL, &sc->sc_csr_size, 0)) { 689 printf(": can't find csr mem space\n"); 690 goto fail_1; 691 } 692 693 /* set up DB doorbell region */ 694 reg = OCE_BAR_DB; 695 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg); 696 if (pci_mapreg_map(pa, reg, memtype, 0, &sc->sc_db_iot, 697 &sc->sc_db_ioh, NULL, &sc->sc_db_size, 0)) { 698 printf(": can't find csr mem space\n"); 699 goto fail_2; 700 } 701 } else { 702 sc->sc_csr_iot = sc->sc_db_iot = sc->sc_cfg_iot; 703 sc->sc_csr_ioh = sc->sc_db_ioh = sc->sc_cfg_ioh; 704 } 705 706 return (0); 707 708fail_2: 709 bus_space_unmap(sc->sc_csr_iot, sc->sc_csr_ioh, sc->sc_csr_size); 710fail_1: 711 bus_space_unmap(sc->sc_cfg_iot, sc->sc_cfg_ioh, sc->sc_cfg_size); 712 return (ENXIO); 713} 714 715static inline uint32_t 716oce_read_cfg(struct oce_softc *sc, bus_size_t off) 717{ 718 bus_space_barrier(sc->sc_cfg_iot, sc->sc_cfg_ioh, off, 4, 719 BUS_SPACE_BARRIER_READ); 720 return (bus_space_read_4(sc->sc_cfg_iot, sc->sc_cfg_ioh, off)); 721} 722 723static inline uint32_t 724oce_read_csr(struct oce_softc *sc, bus_size_t off) 725{ 726 bus_space_barrier(sc->sc_csr_iot, sc->sc_csr_ioh, off, 4, 727 BUS_SPACE_BARRIER_READ); 728 return (bus_space_read_4(sc->sc_csr_iot, sc->sc_csr_ioh, off)); 729} 730 731static inline uint32_t 732oce_read_db(struct oce_softc *sc, bus_size_t off) 733{ 734 bus_space_barrier(sc->sc_db_iot, sc->sc_db_ioh, off, 4, 735 BUS_SPACE_BARRIER_READ); 736 return (bus_space_read_4(sc->sc_db_iot, sc->sc_db_ioh, off)); 737} 738 739static inline void 740oce_write_cfg(struct oce_softc *sc, bus_size_t off, uint32_t val) 741{ 742 bus_space_write_4(sc->sc_cfg_iot, sc->sc_cfg_ioh, off, val); 743 bus_space_barrier(sc->sc_cfg_iot, sc->sc_cfg_ioh, off, 4, 744 BUS_SPACE_BARRIER_WRITE); 745} 746 747static inline void 748oce_write_csr(struct oce_softc *sc, bus_size_t off, uint32_t val) 749{ 750 bus_space_write_4(sc->sc_csr_iot, sc->sc_csr_ioh, off, val); 751 bus_space_barrier(sc->sc_csr_iot, sc->sc_csr_ioh, off, 4, 752 BUS_SPACE_BARRIER_WRITE); 753} 754 755static inline void 756oce_write_db(struct oce_softc *sc, bus_size_t off, uint32_t val) 757{ 758 bus_space_write_4(sc->sc_db_iot, sc->sc_db_ioh, off, val); 759 bus_space_barrier(sc->sc_db_iot, sc->sc_db_ioh, off, 4, 760 BUS_SPACE_BARRIER_WRITE); 761} 762 763static inline void 764oce_intr_enable(struct oce_softc *sc) 765{ 766 uint32_t reg; 767 768 reg = oce_read_cfg(sc, PCI_INTR_CTRL); 769 oce_write_cfg(sc, PCI_INTR_CTRL, reg | HOSTINTR_MASK); 770} 771 772static inline void 773oce_intr_disable(struct oce_softc *sc) 774{ 775 uint32_t reg; 776 777 reg = oce_read_cfg(sc, PCI_INTR_CTRL); 778 oce_write_cfg(sc, PCI_INTR_CTRL, reg & ~HOSTINTR_MASK); 779} 780 781void 782oce_attachhook(struct device *self) 783{ 784 struct oce_softc *sc = (struct oce_softc *)self; 785 786 oce_get_link_status(sc); 787 788 oce_arm_cq(sc->sc_mq->cq, 0, TRUE); 789 790 /* 791 * We need to get MCC async events. So enable intrs and arm 792 * first EQ, Other EQs will be armed after interface is UP 793 */ 794 oce_intr_enable(sc); 795 oce_arm_eq(sc->sc_eq[0], 0, TRUE, FALSE); 796 797 /* 798 * Send first mcc cmd and after that we get gracious 799 * MCC notifications from FW 800 */ 801 oce_first_mcc(sc); 802} 803 804void 805oce_attach_ifp(struct oce_softc *sc) 806{ 807 struct ifnet *ifp = &sc->sc_ac.ac_if; 808 809 ifmedia_init(&sc->sc_media, IFM_IMASK, oce_media_change, 810 oce_media_status); 811 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 812 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 813 814 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); 815 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 816 ifp->if_ioctl = oce_ioctl; 817 ifp->if_start = oce_start; 818 ifp->if_watchdog = oce_watchdog; 819 ifp->if_hardmtu = OCE_MAX_MTU; 820 ifp->if_softc = sc; 821 ifq_init_maxlen(&ifp->if_snd, sc->sc_tx_ring_size - 1); 822 823 ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 | 824 IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4; 825 826#if NVLAN > 0 827 ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; 828#endif 829 830#ifdef OCE_TSO 831 ifp->if_capabilities |= IFCAP_TSO; 832 ifp->if_capabilities |= IFCAP_VLAN_HWTSO; 833#endif 834#ifdef OCE_LRO 835 ifp->if_capabilities |= IFCAP_LRO; 836#endif 837 838 if_attach(ifp); 839 ether_ifattach(ifp); 840} 841 842int 843oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 844{ 845 struct oce_softc *sc = ifp->if_softc; 846 struct ifreq *ifr = (struct ifreq *)data; 847 int s, error = 0; 848 849 s = splnet(); 850 851 switch (command) { 852 case SIOCSIFADDR: 853 ifp->if_flags |= IFF_UP; 854 if (!(ifp->if_flags & IFF_RUNNING)) 855 oce_init(sc); 856 break; 857 case SIOCSIFFLAGS: 858 if (ifp->if_flags & IFF_UP) { 859 if (ifp->if_flags & IFF_RUNNING) 860 error = ENETRESET; 861 else 862 oce_init(sc); 863 } else { 864 if (ifp->if_flags & IFF_RUNNING) 865 oce_stop(sc); 866 } 867 break; 868 case SIOCGIFMEDIA: 869 case SIOCSIFMEDIA: 870 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command); 871 break; 872 case SIOCGIFRXR: 873 error = oce_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_data); 874 break; 875 default: 876 error = ether_ioctl(ifp, &sc->sc_ac, command, data); 877 break; 878 } 879 880 if (error == ENETRESET) { 881 if (ifp->if_flags & IFF_RUNNING) 882 oce_iff(sc); 883 error = 0; 884 } 885 886 splx(s); 887 888 return (error); 889} 890 891int 892oce_rxrinfo(struct oce_softc *sc, struct if_rxrinfo *ifri) 893{ 894 struct if_rxring_info *ifr, ifr1; 895 struct oce_rq *rq; 896 int error, i; 897 u_int n = 0; 898 899 if (sc->sc_nrq > 1) { 900 ifr = mallocarray(sc->sc_nrq, sizeof(*ifr), M_DEVBUF, 901 M_WAITOK | M_ZERO); 902 } else 903 ifr = &ifr1; 904 905 OCE_RQ_FOREACH(sc, rq, i) { 906 ifr[n].ifr_size = MCLBYTES; 907 snprintf(ifr[n].ifr_name, sizeof(ifr[n].ifr_name), "/%d", i); 908 ifr[n].ifr_info = rq->rxring; 909 n++; 910 } 911 912 error = if_rxr_info_ioctl(ifri, sc->sc_nrq, ifr); 913 914 if (sc->sc_nrq > 1) 915 free(ifr, M_DEVBUF, sc->sc_nrq * sizeof(*ifr)); 916 return (error); 917} 918 919 920void 921oce_iff(struct oce_softc *sc) 922{ 923 uint8_t multi[OCE_MAX_MC_FILTER_SIZE][ETHER_ADDR_LEN]; 924 struct arpcom *ac = &sc->sc_ac; 925 struct ifnet *ifp = &ac->ac_if; 926 struct ether_multi *enm; 927 struct ether_multistep step; 928 int naddr = 0, promisc = 0; 929 930 ifp->if_flags &= ~IFF_ALLMULTI; 931 932 if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0 || 933 ac->ac_multicnt >= OCE_MAX_MC_FILTER_SIZE) { 934 ifp->if_flags |= IFF_ALLMULTI; 935 promisc = 1; 936 } else { 937 ETHER_FIRST_MULTI(step, &sc->sc_ac, enm); 938 while (enm != NULL) { 939 memcpy(multi[naddr++], enm->enm_addrlo, ETHER_ADDR_LEN); 940 ETHER_NEXT_MULTI(step, enm); 941 } 942 oce_update_mcast(sc, multi, naddr); 943 } 944 945 oce_set_promisc(sc, promisc); 946} 947 948void 949oce_link_status(struct oce_softc *sc) 950{ 951 struct ifnet *ifp = &sc->sc_ac.ac_if; 952 int link_state = LINK_STATE_DOWN; 953 954 ifp->if_baudrate = 0; 955 if (sc->sc_link_up) { 956 link_state = LINK_STATE_FULL_DUPLEX; 957 958 switch (sc->sc_link_speed) { 959 case 1: 960 ifp->if_baudrate = IF_Mbps(10); 961 break; 962 case 2: 963 ifp->if_baudrate = IF_Mbps(100); 964 break; 965 case 3: 966 ifp->if_baudrate = IF_Gbps(1); 967 break; 968 case 4: 969 ifp->if_baudrate = IF_Gbps(10); 970 break; 971 } 972 } 973 if (ifp->if_link_state != link_state) { 974 ifp->if_link_state = link_state; 975 if_link_state_change(ifp); 976 } 977} 978 979void 980oce_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 981{ 982 struct oce_softc *sc = ifp->if_softc; 983 984 ifmr->ifm_status = IFM_AVALID; 985 ifmr->ifm_active = IFM_ETHER; 986 987 if (oce_get_link_status(sc) == 0) 988 oce_link_status(sc); 989 990 if (!sc->sc_link_up) { 991 ifmr->ifm_active |= IFM_NONE; 992 return; 993 } 994 995 ifmr->ifm_status |= IFM_ACTIVE; 996 997 switch (sc->sc_link_speed) { 998 case 1: /* 10 Mbps */ 999 ifmr->ifm_active |= IFM_10_T | IFM_FDX; 1000 break; 1001 case 2: /* 100 Mbps */ 1002 ifmr->ifm_active |= IFM_100_TX | IFM_FDX; 1003 break; 1004 case 3: /* 1 Gbps */ 1005 ifmr->ifm_active |= IFM_1000_T | IFM_FDX; 1006 break; 1007 case 4: /* 10 Gbps */ 1008 ifmr->ifm_active |= IFM_10G_SR | IFM_FDX; 1009 break; 1010 } 1011 1012 if (sc->sc_fc & IFM_ETH_RXPAUSE) 1013 ifmr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE; 1014 if (sc->sc_fc & IFM_ETH_TXPAUSE) 1015 ifmr->ifm_active |= IFM_FLOW | IFM_ETH_TXPAUSE; 1016} 1017 1018int 1019oce_media_change(struct ifnet *ifp) 1020{ 1021 return (0); 1022} 1023 1024void 1025oce_tick(void *arg) 1026{ 1027 struct oce_softc *sc = arg; 1028 int s; 1029 1030 s = splnet(); 1031 1032 if (oce_update_stats(sc) == 0) 1033 timeout_add_sec(&sc->sc_tick, 1); 1034 1035 splx(s); 1036} 1037 1038void 1039oce_init(void *arg) 1040{ 1041 struct oce_softc *sc = arg; 1042 struct ifnet *ifp = &sc->sc_ac.ac_if; 1043 struct oce_eq *eq; 1044 struct oce_rq *rq; 1045 struct oce_wq *wq; 1046 int i; 1047 1048 oce_stop(sc); 1049 1050 DELAY(10); 1051 1052 oce_macaddr_set(sc); 1053 1054 oce_iff(sc); 1055 1056 /* Enable VLAN promiscuous mode */ 1057 if (oce_config_vlan(sc, NULL, 0, 1, 1)) 1058 goto error; 1059 1060 if (oce_set_flow_control(sc, IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE)) 1061 goto error; 1062 1063 OCE_RQ_FOREACH(sc, rq, i) { 1064 rq->mtu = ifp->if_hardmtu + ETHER_HDR_LEN + ETHER_CRC_LEN + 1065 ETHER_VLAN_ENCAP_LEN; 1066 if (oce_new_rq(sc, rq)) { 1067 printf("%s: failed to create rq\n", 1068 sc->sc_dev.dv_xname); 1069 goto error; 1070 } 1071 rq->ring->index = 0; 1072 1073 /* oce splits jumbos into 2k chunks... */ 1074 if_rxr_init(&rq->rxring, 8, rq->nitems); 1075 1076 if (!oce_alloc_rx_bufs(rq)) { 1077 printf("%s: failed to allocate rx buffers\n", 1078 sc->sc_dev.dv_xname); 1079 goto error; 1080 } 1081 } 1082 1083#ifdef OCE_RSS 1084 /* RSS config */ 1085 if (sc->sc_rss_enable) { 1086 if (oce_config_rss(sc, (uint8_t)sc->sc_if_id, 1)) { 1087 printf("%s: failed to configure RSS\n", 1088 sc->sc_dev.dv_xname); 1089 goto error; 1090 } 1091 } 1092#endif 1093 1094 OCE_RQ_FOREACH(sc, rq, i) 1095 oce_arm_cq(rq->cq, 0, TRUE); 1096 1097 OCE_WQ_FOREACH(sc, wq, i) 1098 oce_arm_cq(wq->cq, 0, TRUE); 1099 1100 oce_arm_cq(sc->sc_mq->cq, 0, TRUE); 1101 1102 OCE_EQ_FOREACH(sc, eq, i) 1103 oce_arm_eq(eq, 0, TRUE, FALSE); 1104 1105 if (oce_get_link_status(sc) == 0) 1106 oce_link_status(sc); 1107 1108 ifp->if_flags |= IFF_RUNNING; 1109 ifq_clr_oactive(&ifp->if_snd); 1110 1111 timeout_add_sec(&sc->sc_tick, 1); 1112 1113 oce_intr_enable(sc); 1114 1115 return; 1116error: 1117 oce_stop(sc); 1118} 1119 1120void 1121oce_stop(struct oce_softc *sc) 1122{ 1123 struct mbx_delete_nic_rq cmd; 1124 struct ifnet *ifp = &sc->sc_ac.ac_if; 1125 struct oce_rq *rq; 1126 struct oce_wq *wq; 1127 struct oce_eq *eq; 1128 int i; 1129 1130 timeout_del(&sc->sc_tick); 1131 timeout_del(&sc->sc_rxrefill); 1132 1133 ifp->if_flags &= ~IFF_RUNNING; 1134 ifq_clr_oactive(&ifp->if_snd); 1135 1136 /* Stop intrs and finish any bottom halves pending */ 1137 oce_intr_disable(sc); 1138 1139 /* Invalidate any pending cq and eq entries */ 1140 OCE_EQ_FOREACH(sc, eq, i) 1141 oce_drain_eq(eq); 1142 OCE_RQ_FOREACH(sc, rq, i) { 1143 /* destroy the work queue in the firmware */ 1144 memset(&cmd, 0, sizeof(cmd)); 1145 cmd.params.req.rq_id = htole16(rq->id); 1146 oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_DELETE_RQ, 1147 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 1148 DELAY(1000); 1149 oce_drain_rq(rq); 1150 oce_free_posted_rxbuf(rq); 1151 } 1152 OCE_WQ_FOREACH(sc, wq, i) 1153 oce_drain_wq(wq); 1154} 1155 1156void 1157oce_watchdog(struct ifnet *ifp) 1158{ 1159 printf("%s: watchdog timeout -- resetting\n", ifp->if_xname); 1160 1161 oce_init(ifp->if_softc); 1162 1163 ifp->if_oerrors++; 1164} 1165 1166void 1167oce_start(struct ifnet *ifp) 1168{ 1169 struct oce_softc *sc = ifp->if_softc; 1170 struct mbuf *m; 1171 int pkts = 0; 1172 1173 if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) 1174 return; 1175 1176 for (;;) { 1177 m = ifq_dequeue(&ifp->if_snd); 1178 if (m == NULL) 1179 break; 1180 1181 if (oce_encap(sc, &m, 0)) { 1182 ifq_set_oactive(&ifp->if_snd); 1183 break; 1184 } 1185 1186#if NBPFILTER > 0 1187 if (ifp->if_bpf) 1188 bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); 1189#endif 1190 pkts++; 1191 } 1192 1193 /* Set a timeout in case the chip goes out to lunch */ 1194 if (pkts) 1195 ifp->if_timer = 5; 1196} 1197 1198int 1199oce_encap(struct oce_softc *sc, struct mbuf **mpp, int wqidx) 1200{ 1201 struct mbuf *m = *mpp; 1202 struct oce_wq *wq = sc->sc_wq[wqidx]; 1203 struct oce_pkt *pkt = NULL; 1204 struct oce_nic_hdr_wqe *nhe; 1205 struct oce_nic_frag_wqe *nfe; 1206 int i, nwqe, err; 1207 1208#ifdef OCE_TSO 1209 if (m->m_pkthdr.csum_flags & CSUM_TSO) { 1210 /* consolidate packet buffers for TSO/LSO segment offload */ 1211 m = oce_tso(sc, mpp); 1212 if (m == NULL) 1213 goto error; 1214 } 1215#endif 1216 1217 if ((pkt = oce_pkt_get(&wq->pkt_free)) == NULL) 1218 goto error; 1219 1220 err = bus_dmamap_load_mbuf(sc->sc_dmat, pkt->map, m, BUS_DMA_NOWAIT); 1221 if (err == EFBIG) { 1222 if (m_defrag(m, M_DONTWAIT) || 1223 bus_dmamap_load_mbuf(sc->sc_dmat, pkt->map, m, 1224 BUS_DMA_NOWAIT)) 1225 goto error; 1226 *mpp = m; 1227 } else if (err != 0) 1228 goto error; 1229 1230 pkt->nsegs = pkt->map->dm_nsegs; 1231 1232 nwqe = pkt->nsegs + 1; 1233 if (IS_BE(sc)) { 1234 /* BE2 and BE3 require even number of WQEs */ 1235 if (nwqe & 1) 1236 nwqe++; 1237 } 1238 1239 /* Fail if there's not enough free WQEs */ 1240 if (nwqe >= wq->ring->nitems - wq->ring->nused) { 1241 bus_dmamap_unload(sc->sc_dmat, pkt->map); 1242 goto error; 1243 } 1244 1245 bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize, 1246 BUS_DMASYNC_PREWRITE); 1247 pkt->mbuf = m; 1248 1249 /* TX work queue entry for the header */ 1250 nhe = oce_ring_get(wq->ring); 1251 memset(nhe, 0, sizeof(*nhe)); 1252 1253 nhe->u0.s.complete = 1; 1254 nhe->u0.s.event = 1; 1255 nhe->u0.s.crc = 1; 1256 nhe->u0.s.forward = 0; 1257 nhe->u0.s.ipcs = (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT) ? 1 : 0; 1258 nhe->u0.s.udpcs = (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) ? 1 : 0; 1259 nhe->u0.s.tcpcs = (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT) ? 1 : 0; 1260 nhe->u0.s.num_wqe = nwqe; 1261 nhe->u0.s.total_length = m->m_pkthdr.len; 1262 1263#if NVLAN > 0 1264 if (m->m_flags & M_VLANTAG) { 1265 nhe->u0.s.vlan = 1; /* Vlan present */ 1266 nhe->u0.s.vlan_tag = m->m_pkthdr.ether_vtag; 1267 } 1268#endif 1269 1270#ifdef OCE_TSO 1271 if (m->m_pkthdr.csum_flags & CSUM_TSO) { 1272 if (m->m_pkthdr.tso_segsz) { 1273 nhe->u0.s.lso = 1; 1274 nhe->u0.s.lso_mss = m->m_pkthdr.tso_segsz; 1275 } 1276 if (!IS_BE(sc)) 1277 nhe->u0.s.ipcs = 1; 1278 } 1279#endif 1280 1281 oce_dma_sync(&wq->ring->dma, BUS_DMASYNC_PREREAD | 1282 BUS_DMASYNC_PREWRITE); 1283 1284 wq->ring->nused++; 1285 1286 /* TX work queue entries for data chunks */ 1287 for (i = 0; i < pkt->nsegs; i++) { 1288 nfe = oce_ring_get(wq->ring); 1289 memset(nfe, 0, sizeof(*nfe)); 1290 nfe->u0.s.frag_pa_hi = ADDR_HI(pkt->map->dm_segs[i].ds_addr); 1291 nfe->u0.s.frag_pa_lo = ADDR_LO(pkt->map->dm_segs[i].ds_addr); 1292 nfe->u0.s.frag_len = pkt->map->dm_segs[i].ds_len; 1293 wq->ring->nused++; 1294 } 1295 if (nwqe > (pkt->nsegs + 1)) { 1296 nfe = oce_ring_get(wq->ring); 1297 memset(nfe, 0, sizeof(*nfe)); 1298 wq->ring->nused++; 1299 pkt->nsegs++; 1300 } 1301 1302 oce_pkt_put(&wq->pkt_list, pkt); 1303 1304 oce_dma_sync(&wq->ring->dma, BUS_DMASYNC_POSTREAD | 1305 BUS_DMASYNC_POSTWRITE); 1306 1307 oce_write_db(sc, PD_TXULP_DB, wq->id | (nwqe << 16)); 1308 1309 return (0); 1310 1311error: 1312 if (pkt) 1313 oce_pkt_put(&wq->pkt_free, pkt); 1314 m_freem(*mpp); 1315 *mpp = NULL; 1316 return (1); 1317} 1318 1319#ifdef OCE_TSO 1320struct mbuf * 1321oce_tso(struct oce_softc *sc, struct mbuf **mpp) 1322{ 1323 struct mbuf *m; 1324 struct ip *ip; 1325#ifdef INET6 1326 struct ip6_hdr *ip6; 1327#endif 1328 struct ether_vlan_header *eh; 1329 struct tcphdr *th; 1330 uint16_t etype; 1331 int total_len = 0, ehdrlen = 0; 1332 1333 m = *mpp; 1334 1335 if (M_WRITABLE(m) == 0) { 1336 m = m_dup(*mpp, M_DONTWAIT); 1337 if (!m) 1338 return (NULL); 1339 m_freem(*mpp); 1340 *mpp = m; 1341 } 1342 1343 eh = mtod(m, struct ether_vlan_header *); 1344 if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 1345 etype = ntohs(eh->evl_proto); 1346 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 1347 } else { 1348 etype = ntohs(eh->evl_encap_proto); 1349 ehdrlen = ETHER_HDR_LEN; 1350 } 1351 1352 switch (etype) { 1353 case ETHERTYPE_IP: 1354 ip = (struct ip *)(m->m_data + ehdrlen); 1355 if (ip->ip_p != IPPROTO_TCP) 1356 return (NULL); 1357 th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 1358 1359 total_len = ehdrlen + (ip->ip_hl << 2) + (th->th_off << 2); 1360 break; 1361#ifdef INET6 1362 case ETHERTYPE_IPV6: 1363 ip6 = (struct ip6_hdr *)(m->m_data + ehdrlen); 1364 if (ip6->ip6_nxt != IPPROTO_TCP) 1365 return NULL; 1366 th = (struct tcphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr)); 1367 1368 total_len = ehdrlen + sizeof(struct ip6_hdr) + 1369 (th->th_off << 2); 1370 break; 1371#endif 1372 default: 1373 return (NULL); 1374 } 1375 1376 m = m_pullup(m, total_len); 1377 if (!m) 1378 return (NULL); 1379 *mpp = m; 1380 return (m); 1381 1382} 1383#endif /* OCE_TSO */ 1384 1385int 1386oce_intr(void *arg) 1387{ 1388 struct oce_softc *sc = arg; 1389 struct oce_eq *eq = sc->sc_eq[0]; 1390 struct oce_eqe *eqe; 1391 struct oce_cq *cq = NULL; 1392 int i, neqe = 0; 1393 1394 oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_POSTREAD); 1395 1396 OCE_RING_FOREACH(eq->ring, eqe, eqe->evnt != 0) { 1397 eqe->evnt = 0; 1398 neqe++; 1399 } 1400 1401 /* Spurious? */ 1402 if (!neqe) { 1403 oce_arm_eq(eq, 0, TRUE, FALSE); 1404 return (0); 1405 } 1406 1407 oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_PREWRITE); 1408 1409 /* Clear EQ entries, but dont arm */ 1410 oce_arm_eq(eq, neqe, FALSE, TRUE); 1411 1412 /* Process TX, RX and MCC completion queues */ 1413 for (i = 0; i < eq->cq_valid; i++) { 1414 cq = eq->cq[i]; 1415 (*cq->cq_intr)(cq->cb_arg); 1416 oce_arm_cq(cq, 0, TRUE); 1417 } 1418 1419 oce_arm_eq(eq, 0, TRUE, FALSE); 1420 return (1); 1421} 1422 1423/* Handle the Completion Queue for transmit */ 1424void 1425oce_intr_wq(void *arg) 1426{ 1427 struct oce_wq *wq = (struct oce_wq *)arg; 1428 struct oce_cq *cq = wq->cq; 1429 struct oce_nic_tx_cqe *cqe; 1430 struct oce_softc *sc = wq->sc; 1431 struct ifnet *ifp = &sc->sc_ac.ac_if; 1432 int ncqe = 0; 1433 1434 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD); 1435 OCE_RING_FOREACH(cq->ring, cqe, WQ_CQE_VALID(cqe)) { 1436 oce_txeof(wq); 1437 WQ_CQE_INVALIDATE(cqe); 1438 ncqe++; 1439 } 1440 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE); 1441 1442 if (ifq_is_oactive(&ifp->if_snd)) { 1443 if (wq->ring->nused < (wq->ring->nitems / 2)) { 1444 ifq_clr_oactive(&ifp->if_snd); 1445 oce_start(ifp); 1446 } 1447 } 1448 if (wq->ring->nused == 0) 1449 ifp->if_timer = 0; 1450 1451 if (ncqe) 1452 oce_arm_cq(cq, ncqe, FALSE); 1453} 1454 1455void 1456oce_txeof(struct oce_wq *wq) 1457{ 1458 struct oce_softc *sc = wq->sc; 1459 struct oce_pkt *pkt; 1460 struct mbuf *m; 1461 1462 if ((pkt = oce_pkt_get(&wq->pkt_list)) == NULL) { 1463 printf("%s: missing descriptor in txeof\n", 1464 sc->sc_dev.dv_xname); 1465 return; 1466 } 1467 1468 wq->ring->nused -= pkt->nsegs + 1; 1469 bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize, 1470 BUS_DMASYNC_POSTWRITE); 1471 bus_dmamap_unload(sc->sc_dmat, pkt->map); 1472 1473 m = pkt->mbuf; 1474 m_freem(m); 1475 pkt->mbuf = NULL; 1476 oce_pkt_put(&wq->pkt_free, pkt); 1477} 1478 1479/* Handle the Completion Queue for receive */ 1480void 1481oce_intr_rq(void *arg) 1482{ 1483 struct oce_rq *rq = (struct oce_rq *)arg; 1484 struct oce_cq *cq = rq->cq; 1485 struct oce_softc *sc = rq->sc; 1486 struct oce_nic_rx_cqe *cqe; 1487 struct ifnet *ifp = &sc->sc_ac.ac_if; 1488 int maxrx, ncqe = 0; 1489 1490 maxrx = IS_XE201(sc) ? 8 : OCE_MAX_RQ_COMPL; 1491 1492 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD); 1493 1494 OCE_RING_FOREACH(cq->ring, cqe, RQ_CQE_VALID(cqe) && ncqe <= maxrx) { 1495 if (cqe->u0.s.error == 0) { 1496 if (cqe->u0.s.pkt_size == 0) 1497 /* partial DMA workaround for Lancer */ 1498 oce_rxeoc(rq, cqe); 1499 else 1500 oce_rxeof(rq, cqe); 1501 } else { 1502 ifp->if_ierrors++; 1503 if (IS_XE201(sc)) 1504 /* Lancer A0 no buffer workaround */ 1505 oce_rxeoc(rq, cqe); 1506 else 1507 /* Post L3/L4 errors to stack.*/ 1508 oce_rxeof(rq, cqe); 1509 } 1510#ifdef OCE_LRO 1511 if (IF_LRO_ENABLED(ifp) && rq->lro_pkts_queued >= 16) 1512 oce_flush_lro(rq); 1513#endif 1514 RQ_CQE_INVALIDATE(cqe); 1515 ncqe++; 1516 } 1517 1518 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE); 1519 1520#ifdef OCE_LRO 1521 if (IF_LRO_ENABLED(ifp)) 1522 oce_flush_lro(rq); 1523#endif 1524 1525 if (ncqe) { 1526 oce_arm_cq(cq, ncqe, FALSE); 1527 if (!oce_alloc_rx_bufs(rq)) 1528 timeout_add(&sc->sc_rxrefill, 1); 1529 } 1530} 1531 1532void 1533oce_rxeof(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe) 1534{ 1535 struct oce_softc *sc = rq->sc; 1536 struct oce_pkt *pkt = NULL; 1537 struct ifnet *ifp = &sc->sc_ac.ac_if; 1538 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 1539 struct mbuf *m = NULL, *tail = NULL; 1540 int i, len, frag_len; 1541 uint16_t vtag; 1542 1543 len = cqe->u0.s.pkt_size; 1544 1545 /* Get vlan_tag value */ 1546 if (IS_BE(sc)) 1547 vtag = ntohs(cqe->u0.s.vlan_tag); 1548 else 1549 vtag = cqe->u0.s.vlan_tag; 1550 1551 for (i = 0; i < cqe->u0.s.num_fragments; i++) { 1552 if ((pkt = oce_pkt_get(&rq->pkt_list)) == NULL) { 1553 printf("%s: missing descriptor in rxeof\n", 1554 sc->sc_dev.dv_xname); 1555 goto exit; 1556 } 1557 1558 bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize, 1559 BUS_DMASYNC_POSTREAD); 1560 bus_dmamap_unload(sc->sc_dmat, pkt->map); 1561 if_rxr_put(&rq->rxring, 1); 1562 1563 frag_len = (len > rq->fragsize) ? rq->fragsize : len; 1564 pkt->mbuf->m_len = frag_len; 1565 1566 if (tail != NULL) { 1567 /* additional fragments */ 1568 pkt->mbuf->m_flags &= ~M_PKTHDR; 1569 tail->m_next = pkt->mbuf; 1570 tail = pkt->mbuf; 1571 } else { 1572 /* first fragment, fill out most of the header */ 1573 pkt->mbuf->m_pkthdr.len = len; 1574 pkt->mbuf->m_pkthdr.csum_flags = 0; 1575 if (cqe->u0.s.ip_cksum_pass) { 1576 if (!cqe->u0.s.ip_ver) { /* IPV4 */ 1577 pkt->mbuf->m_pkthdr.csum_flags = 1578 M_IPV4_CSUM_IN_OK; 1579 } 1580 } 1581 if (cqe->u0.s.l4_cksum_pass) { 1582 pkt->mbuf->m_pkthdr.csum_flags |= 1583 M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK; 1584 } 1585 m = tail = pkt->mbuf; 1586 } 1587 pkt->mbuf = NULL; 1588 oce_pkt_put(&rq->pkt_free, pkt); 1589 len -= frag_len; 1590 } 1591 1592 if (m) { 1593 if (!oce_port_valid(sc, cqe)) { 1594 m_freem(m); 1595 goto exit; 1596 } 1597 1598#if NVLAN > 0 1599 /* This determines if vlan tag is valid */ 1600 if (oce_vtp_valid(sc, cqe)) { 1601 if (sc->sc_fmode & FNM_FLEX10_MODE) { 1602 /* FLEX10. If QnQ is not set, neglect VLAN */ 1603 if (cqe->u0.s.qnq) { 1604 m->m_pkthdr.ether_vtag = vtag; 1605 m->m_flags |= M_VLANTAG; 1606 } 1607 } else if (sc->sc_pvid != (vtag & VLAN_VID_MASK)) { 1608 /* 1609 * In UMC mode generally pvid will be striped. 1610 * But in some cases we have seen it comes 1611 * with pvid. So if pvid == vlan, neglect vlan. 1612 */ 1613 m->m_pkthdr.ether_vtag = vtag; 1614 m->m_flags |= M_VLANTAG; 1615 } 1616 } 1617#endif 1618 1619#ifdef OCE_LRO 1620 /* Try to queue to LRO */ 1621 if (IF_LRO_ENABLED(ifp) && !(m->m_flags & M_VLANTAG) && 1622 cqe->u0.s.ip_cksum_pass && cqe->u0.s.l4_cksum_pass && 1623 !cqe->u0.s.ip_ver && rq->lro.lro_cnt != 0) { 1624 1625 if (tcp_lro_rx(&rq->lro, m, 0) == 0) { 1626 rq->lro_pkts_queued ++; 1627 goto exit; 1628 } 1629 /* If LRO posting fails then try to post to STACK */ 1630 } 1631#endif 1632 1633 ml_enqueue(&ml, m); 1634 } 1635exit: 1636 if (ifiq_input(&ifp->if_rcv, &ml)) 1637 if_rxr_livelocked(&rq->rxring); 1638} 1639 1640void 1641oce_rxeoc(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe) 1642{ 1643 struct oce_softc *sc = rq->sc; 1644 struct oce_pkt *pkt; 1645 int i, num_frags = cqe->u0.s.num_fragments; 1646 1647 if (IS_XE201(sc) && cqe->u0.s.error) { 1648 /* 1649 * Lancer A0 workaround: 1650 * num_frags will be 1 more than actual in case of error 1651 */ 1652 if (num_frags) 1653 num_frags--; 1654 } 1655 for (i = 0; i < num_frags; i++) { 1656 if ((pkt = oce_pkt_get(&rq->pkt_list)) == NULL) { 1657 printf("%s: missing descriptor in rxeoc\n", 1658 sc->sc_dev.dv_xname); 1659 return; 1660 } 1661 bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize, 1662 BUS_DMASYNC_POSTREAD); 1663 bus_dmamap_unload(sc->sc_dmat, pkt->map); 1664 if_rxr_put(&rq->rxring, 1); 1665 m_freem(pkt->mbuf); 1666 oce_pkt_put(&rq->pkt_free, pkt); 1667 } 1668} 1669 1670int 1671oce_vtp_valid(struct oce_softc *sc, struct oce_nic_rx_cqe *cqe) 1672{ 1673 struct oce_nic_rx_cqe_v1 *cqe_v1; 1674 1675 if (IS_BE(sc) && ISSET(sc->sc_flags, OCE_F_BE3_NATIVE)) { 1676 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe; 1677 return (cqe_v1->u0.s.vlan_tag_present); 1678 } 1679 return (cqe->u0.s.vlan_tag_present); 1680} 1681 1682int 1683oce_port_valid(struct oce_softc *sc, struct oce_nic_rx_cqe *cqe) 1684{ 1685 struct oce_nic_rx_cqe_v1 *cqe_v1; 1686 1687 if (IS_BE(sc) && ISSET(sc->sc_flags, OCE_F_BE3_NATIVE)) { 1688 cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe; 1689 if (sc->sc_port != cqe_v1->u0.s.port) 1690 return (0); 1691 } 1692 return (1); 1693} 1694 1695#ifdef OCE_LRO 1696void 1697oce_flush_lro(struct oce_rq *rq) 1698{ 1699 struct oce_softc *sc = rq->sc; 1700 struct ifnet *ifp = &sc->sc_ac.ac_if; 1701 struct lro_ctrl *lro = &rq->lro; 1702 struct lro_entry *queued; 1703 1704 if (!IF_LRO_ENABLED(ifp)) 1705 return; 1706 1707 while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) { 1708 SLIST_REMOVE_HEAD(&lro->lro_active, next); 1709 tcp_lro_flush(lro, queued); 1710 } 1711 rq->lro_pkts_queued = 0; 1712} 1713 1714int 1715oce_init_lro(struct oce_softc *sc) 1716{ 1717 struct lro_ctrl *lro = NULL; 1718 int i = 0, rc = 0; 1719 1720 for (i = 0; i < sc->sc_nrq; i++) { 1721 lro = &sc->sc_rq[i]->lro; 1722 rc = tcp_lro_init(lro); 1723 if (rc != 0) { 1724 printf("%s: LRO init failed\n", 1725 sc->sc_dev.dv_xname); 1726 return rc; 1727 } 1728 lro->ifp = &sc->sc_ac.ac_if; 1729 } 1730 1731 return (rc); 1732} 1733 1734void 1735oce_free_lro(struct oce_softc *sc) 1736{ 1737 struct lro_ctrl *lro = NULL; 1738 int i = 0; 1739 1740 for (i = 0; i < sc->sc_nrq; i++) { 1741 lro = &sc->sc_rq[i]->lro; 1742 if (lro) 1743 tcp_lro_free(lro); 1744 } 1745} 1746#endif /* OCE_LRO */ 1747 1748int 1749oce_get_buf(struct oce_rq *rq) 1750{ 1751 struct oce_softc *sc = rq->sc; 1752 struct oce_pkt *pkt; 1753 struct oce_nic_rqe *rqe; 1754 1755 if ((pkt = oce_pkt_get(&rq->pkt_free)) == NULL) 1756 return (0); 1757 1758 pkt->mbuf = MCLGETL(NULL, M_DONTWAIT, MCLBYTES); 1759 if (pkt->mbuf == NULL) { 1760 oce_pkt_put(&rq->pkt_free, pkt); 1761 return (0); 1762 } 1763 1764 pkt->mbuf->m_len = pkt->mbuf->m_pkthdr.len = MCLBYTES; 1765#ifdef __STRICT_ALIGNMENT 1766 m_adj(pkt->mbuf, ETHER_ALIGN); 1767#endif 1768 1769 if (bus_dmamap_load_mbuf(sc->sc_dmat, pkt->map, pkt->mbuf, 1770 BUS_DMA_NOWAIT)) { 1771 m_freem(pkt->mbuf); 1772 pkt->mbuf = NULL; 1773 oce_pkt_put(&rq->pkt_free, pkt); 1774 return (0); 1775 } 1776 1777 bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize, 1778 BUS_DMASYNC_PREREAD); 1779 1780 oce_dma_sync(&rq->ring->dma, BUS_DMASYNC_PREREAD | 1781 BUS_DMASYNC_PREWRITE); 1782 1783 rqe = oce_ring_get(rq->ring); 1784 rqe->u0.s.frag_pa_hi = ADDR_HI(pkt->map->dm_segs[0].ds_addr); 1785 rqe->u0.s.frag_pa_lo = ADDR_LO(pkt->map->dm_segs[0].ds_addr); 1786 1787 oce_dma_sync(&rq->ring->dma, BUS_DMASYNC_POSTREAD | 1788 BUS_DMASYNC_POSTWRITE); 1789 1790 oce_pkt_put(&rq->pkt_list, pkt); 1791 1792 return (1); 1793} 1794 1795int 1796oce_alloc_rx_bufs(struct oce_rq *rq) 1797{ 1798 struct oce_softc *sc = rq->sc; 1799 int i, nbufs = 0; 1800 u_int slots; 1801 1802 for (slots = if_rxr_get(&rq->rxring, rq->nitems); slots > 0; slots--) { 1803 if (oce_get_buf(rq) == 0) 1804 break; 1805 1806 nbufs++; 1807 } 1808 if_rxr_put(&rq->rxring, slots); 1809 1810 if (!nbufs) 1811 return (0); 1812 for (i = nbufs / OCE_MAX_RQ_POSTS; i > 0; i--) { 1813 oce_write_db(sc, PD_RXULP_DB, rq->id | 1814 (OCE_MAX_RQ_POSTS << 24)); 1815 nbufs -= OCE_MAX_RQ_POSTS; 1816 } 1817 if (nbufs > 0) 1818 oce_write_db(sc, PD_RXULP_DB, rq->id | (nbufs << 24)); 1819 return (1); 1820} 1821 1822void 1823oce_refill_rx(void *arg) 1824{ 1825 struct oce_softc *sc = arg; 1826 struct oce_rq *rq; 1827 int i, s; 1828 1829 s = splnet(); 1830 OCE_RQ_FOREACH(sc, rq, i) { 1831 if (!oce_alloc_rx_bufs(rq)) 1832 timeout_add(&sc->sc_rxrefill, 5); 1833 } 1834 splx(s); 1835} 1836 1837/* Handle the Completion Queue for the Mailbox/Async notifications */ 1838void 1839oce_intr_mq(void *arg) 1840{ 1841 struct oce_mq *mq = (struct oce_mq *)arg; 1842 struct oce_softc *sc = mq->sc; 1843 struct oce_cq *cq = mq->cq; 1844 struct oce_mq_cqe *cqe; 1845 struct oce_async_cqe_link_state *acqe; 1846 struct oce_async_event_grp5_pvid_state *gcqe; 1847 int evtype, optype, ncqe = 0; 1848 1849 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD); 1850 1851 OCE_RING_FOREACH(cq->ring, cqe, MQ_CQE_VALID(cqe)) { 1852 if (cqe->u0.s.async_event) { 1853 evtype = cqe->u0.s.event_type; 1854 optype = cqe->u0.s.async_type; 1855 if (evtype == ASYNC_EVENT_CODE_LINK_STATE) { 1856 /* Link status evt */ 1857 acqe = (struct oce_async_cqe_link_state *)cqe; 1858 oce_link_event(sc, acqe); 1859 } else if ((evtype == ASYNC_EVENT_GRP5) && 1860 (optype == ASYNC_EVENT_PVID_STATE)) { 1861 /* GRP5 PVID */ 1862 gcqe = 1863 (struct oce_async_event_grp5_pvid_state *)cqe; 1864 if (gcqe->enabled) 1865 sc->sc_pvid = 1866 gcqe->tag & VLAN_VID_MASK; 1867 else 1868 sc->sc_pvid = 0; 1869 } 1870 } 1871 MQ_CQE_INVALIDATE(cqe); 1872 ncqe++; 1873 } 1874 1875 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE); 1876 1877 if (ncqe) 1878 oce_arm_cq(cq, ncqe, FALSE); 1879} 1880 1881void 1882oce_link_event(struct oce_softc *sc, struct oce_async_cqe_link_state *acqe) 1883{ 1884 /* Update Link status */ 1885 sc->sc_link_up = ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) == 1886 ASYNC_EVENT_LINK_UP); 1887 /* Update speed */ 1888 sc->sc_link_speed = acqe->u0.s.speed; 1889 oce_link_status(sc); 1890} 1891 1892int 1893oce_init_queues(struct oce_softc *sc) 1894{ 1895 struct oce_wq *wq; 1896 struct oce_rq *rq; 1897 int i; 1898 1899 sc->sc_nrq = 1; 1900 sc->sc_nwq = 1; 1901 1902 /* Create network interface on card */ 1903 if (oce_create_iface(sc, sc->sc_macaddr)) 1904 goto error; 1905 1906 /* create all of the event queues */ 1907 for (i = 0; i < sc->sc_nintr; i++) { 1908 sc->sc_eq[i] = oce_create_eq(sc); 1909 if (!sc->sc_eq[i]) 1910 goto error; 1911 } 1912 1913 /* alloc tx queues */ 1914 OCE_WQ_FOREACH(sc, wq, i) { 1915 sc->sc_wq[i] = oce_create_wq(sc, sc->sc_eq[i]); 1916 if (!sc->sc_wq[i]) 1917 goto error; 1918 } 1919 1920 /* alloc rx queues */ 1921 OCE_RQ_FOREACH(sc, rq, i) { 1922 sc->sc_rq[i] = oce_create_rq(sc, sc->sc_eq[i > 0 ? i - 1 : 0], 1923 i > 0 ? sc->sc_rss_enable : 0); 1924 if (!sc->sc_rq[i]) 1925 goto error; 1926 } 1927 1928 /* alloc mailbox queue */ 1929 sc->sc_mq = oce_create_mq(sc, sc->sc_eq[0]); 1930 if (!sc->sc_mq) 1931 goto error; 1932 1933 return (0); 1934error: 1935 oce_release_queues(sc); 1936 return (1); 1937} 1938 1939void 1940oce_release_queues(struct oce_softc *sc) 1941{ 1942 struct oce_wq *wq; 1943 struct oce_rq *rq; 1944 struct oce_eq *eq; 1945 int i; 1946 1947 OCE_RQ_FOREACH(sc, rq, i) { 1948 if (rq) 1949 oce_destroy_rq(sc->sc_rq[i]); 1950 } 1951 1952 OCE_WQ_FOREACH(sc, wq, i) { 1953 if (wq) 1954 oce_destroy_wq(sc->sc_wq[i]); 1955 } 1956 1957 if (sc->sc_mq) 1958 oce_destroy_mq(sc->sc_mq); 1959 1960 OCE_EQ_FOREACH(sc, eq, i) { 1961 if (eq) 1962 oce_destroy_eq(sc->sc_eq[i]); 1963 } 1964} 1965 1966/** 1967 * @brief Function to create a WQ for NIC Tx 1968 * @param sc software handle to the device 1969 * @returns the pointer to the WQ created or NULL on failure 1970 */ 1971struct oce_wq * 1972oce_create_wq(struct oce_softc *sc, struct oce_eq *eq) 1973{ 1974 struct oce_wq *wq; 1975 struct oce_cq *cq; 1976 struct oce_pkt *pkt; 1977 int i; 1978 1979 if (sc->sc_tx_ring_size < 256 || sc->sc_tx_ring_size > 2048) 1980 return (NULL); 1981 1982 wq = malloc(sizeof(struct oce_wq), M_DEVBUF, M_NOWAIT | M_ZERO); 1983 if (!wq) 1984 return (NULL); 1985 1986 wq->ring = oce_create_ring(sc, sc->sc_tx_ring_size, NIC_WQE_SIZE, 8); 1987 if (!wq->ring) { 1988 free(wq, M_DEVBUF, 0); 1989 return (NULL); 1990 } 1991 1992 cq = oce_create_cq(sc, eq, CQ_LEN_512, sizeof(struct oce_nic_tx_cqe), 1993 1, 0, 3); 1994 if (!cq) { 1995 oce_destroy_ring(sc, wq->ring); 1996 free(wq, M_DEVBUF, 0); 1997 return (NULL); 1998 } 1999 2000 wq->id = -1; 2001 wq->sc = sc; 2002 2003 wq->cq = cq; 2004 wq->nitems = sc->sc_tx_ring_size; 2005 2006 SIMPLEQ_INIT(&wq->pkt_free); 2007 SIMPLEQ_INIT(&wq->pkt_list); 2008 2009 for (i = 0; i < sc->sc_tx_ring_size / 2; i++) { 2010 pkt = oce_pkt_alloc(sc, OCE_MAX_TX_SIZE, OCE_MAX_TX_ELEMENTS, 2011 PAGE_SIZE); 2012 if (pkt == NULL) { 2013 oce_destroy_wq(wq); 2014 return (NULL); 2015 } 2016 oce_pkt_put(&wq->pkt_free, pkt); 2017 } 2018 2019 if (oce_new_wq(sc, wq)) { 2020 oce_destroy_wq(wq); 2021 return (NULL); 2022 } 2023 2024 eq->cq[eq->cq_valid] = cq; 2025 eq->cq_valid++; 2026 cq->cb_arg = wq; 2027 cq->cq_intr = oce_intr_wq; 2028 2029 return (wq); 2030} 2031 2032void 2033oce_drain_wq(struct oce_wq *wq) 2034{ 2035 struct oce_cq *cq = wq->cq; 2036 struct oce_nic_tx_cqe *cqe; 2037 int ncqe = 0; 2038 2039 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD); 2040 OCE_RING_FOREACH(cq->ring, cqe, WQ_CQE_VALID(cqe)) { 2041 WQ_CQE_INVALIDATE(cqe); 2042 ncqe++; 2043 } 2044 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE); 2045 oce_arm_cq(cq, ncqe, FALSE); 2046} 2047 2048void 2049oce_destroy_wq(struct oce_wq *wq) 2050{ 2051 struct mbx_delete_nic_wq cmd; 2052 struct oce_softc *sc = wq->sc; 2053 struct oce_pkt *pkt; 2054 2055 if (wq->id >= 0) { 2056 memset(&cmd, 0, sizeof(cmd)); 2057 cmd.params.req.wq_id = htole16(wq->id); 2058 oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_DELETE_WQ, OCE_MBX_VER_V0, 2059 &cmd, sizeof(cmd)); 2060 } 2061 if (wq->cq != NULL) 2062 oce_destroy_cq(wq->cq); 2063 if (wq->ring != NULL) 2064 oce_destroy_ring(sc, wq->ring); 2065 while ((pkt = oce_pkt_get(&wq->pkt_free)) != NULL) 2066 oce_pkt_free(sc, pkt); 2067 free(wq, M_DEVBUF, 0); 2068} 2069 2070/** 2071 * @brief function to allocate receive queue resources 2072 * @param sc software handle to the device 2073 * @param eq pointer to associated event queue 2074 * @param rss is-rss-queue flag 2075 * @returns the pointer to the RQ created or NULL on failure 2076 */ 2077struct oce_rq * 2078oce_create_rq(struct oce_softc *sc, struct oce_eq *eq, int rss) 2079{ 2080 struct oce_rq *rq; 2081 struct oce_cq *cq; 2082 struct oce_pkt *pkt; 2083 int i; 2084 2085 /* Hardware doesn't support any other value */ 2086 if (sc->sc_rx_ring_size != 1024) 2087 return (NULL); 2088 2089 rq = malloc(sizeof(struct oce_rq), M_DEVBUF, M_NOWAIT | M_ZERO); 2090 if (!rq) 2091 return (NULL); 2092 2093 rq->ring = oce_create_ring(sc, sc->sc_rx_ring_size, 2094 sizeof(struct oce_nic_rqe), 2); 2095 if (!rq->ring) { 2096 free(rq, M_DEVBUF, 0); 2097 return (NULL); 2098 } 2099 2100 cq = oce_create_cq(sc, eq, CQ_LEN_1024, sizeof(struct oce_nic_rx_cqe), 2101 1, 0, 3); 2102 if (!cq) { 2103 oce_destroy_ring(sc, rq->ring); 2104 free(rq, M_DEVBUF, 0); 2105 return (NULL); 2106 } 2107 2108 rq->id = -1; 2109 rq->sc = sc; 2110 2111 rq->nitems = sc->sc_rx_ring_size; 2112 rq->fragsize = OCE_RX_BUF_SIZE; 2113 rq->rss = rss; 2114 2115 SIMPLEQ_INIT(&rq->pkt_free); 2116 SIMPLEQ_INIT(&rq->pkt_list); 2117 2118 for (i = 0; i < sc->sc_rx_ring_size; i++) { 2119 pkt = oce_pkt_alloc(sc, OCE_RX_BUF_SIZE, 1, OCE_RX_BUF_SIZE); 2120 if (pkt == NULL) { 2121 oce_destroy_rq(rq); 2122 return (NULL); 2123 } 2124 oce_pkt_put(&rq->pkt_free, pkt); 2125 } 2126 2127 rq->cq = cq; 2128 eq->cq[eq->cq_valid] = cq; 2129 eq->cq_valid++; 2130 cq->cb_arg = rq; 2131 cq->cq_intr = oce_intr_rq; 2132 2133 /* RX queue is created in oce_init */ 2134 2135 return (rq); 2136} 2137 2138void 2139oce_drain_rq(struct oce_rq *rq) 2140{ 2141 struct oce_nic_rx_cqe *cqe; 2142 struct oce_cq *cq = rq->cq; 2143 int ncqe = 0; 2144 2145 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD); 2146 OCE_RING_FOREACH(cq->ring, cqe, RQ_CQE_VALID(cqe)) { 2147 RQ_CQE_INVALIDATE(cqe); 2148 ncqe++; 2149 } 2150 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE); 2151 oce_arm_cq(cq, ncqe, FALSE); 2152} 2153 2154void 2155oce_destroy_rq(struct oce_rq *rq) 2156{ 2157 struct mbx_delete_nic_rq cmd; 2158 struct oce_softc *sc = rq->sc; 2159 struct oce_pkt *pkt; 2160 2161 if (rq->id >= 0) { 2162 memset(&cmd, 0, sizeof(cmd)); 2163 cmd.params.req.rq_id = htole16(rq->id); 2164 oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_DELETE_RQ, OCE_MBX_VER_V0, 2165 &cmd, sizeof(cmd)); 2166 } 2167 if (rq->cq != NULL) 2168 oce_destroy_cq(rq->cq); 2169 if (rq->ring != NULL) 2170 oce_destroy_ring(sc, rq->ring); 2171 while ((pkt = oce_pkt_get(&rq->pkt_free)) != NULL) 2172 oce_pkt_free(sc, pkt); 2173 free(rq, M_DEVBUF, 0); 2174} 2175 2176struct oce_eq * 2177oce_create_eq(struct oce_softc *sc) 2178{ 2179 struct oce_eq *eq; 2180 2181 /* allocate an eq */ 2182 eq = malloc(sizeof(struct oce_eq), M_DEVBUF, M_NOWAIT | M_ZERO); 2183 if (eq == NULL) 2184 return (NULL); 2185 2186 eq->ring = oce_create_ring(sc, EQ_LEN_1024, EQE_SIZE_4, 8); 2187 if (!eq->ring) { 2188 free(eq, M_DEVBUF, 0); 2189 return (NULL); 2190 } 2191 2192 eq->id = -1; 2193 eq->sc = sc; 2194 eq->nitems = EQ_LEN_1024; /* length of event queue */ 2195 eq->isize = EQE_SIZE_4; /* size of a queue item */ 2196 eq->delay = OCE_DEFAULT_EQD; /* event queue delay */ 2197 2198 if (oce_new_eq(sc, eq)) { 2199 oce_destroy_ring(sc, eq->ring); 2200 free(eq, M_DEVBUF, 0); 2201 return (NULL); 2202 } 2203 2204 return (eq); 2205} 2206 2207/** 2208 * @brief Function to arm an EQ so that it can generate events 2209 * @param eq pointer to event queue structure 2210 * @param neqe number of EQEs to arm 2211 * @param rearm rearm bit enable/disable 2212 * @param clearint bit to clear the interrupt condition because of which 2213 * EQEs are generated 2214 */ 2215static inline void 2216oce_arm_eq(struct oce_eq *eq, int neqe, int rearm, int clearint) 2217{ 2218 oce_write_db(eq->sc, PD_EQ_DB, eq->id | PD_EQ_DB_EVENT | 2219 (clearint << 9) | (neqe << 16) | (rearm << 29)); 2220} 2221 2222void 2223oce_drain_eq(struct oce_eq *eq) 2224{ 2225 struct oce_eqe *eqe; 2226 int neqe = 0; 2227 2228 oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_POSTREAD); 2229 OCE_RING_FOREACH(eq->ring, eqe, eqe->evnt != 0) { 2230 eqe->evnt = 0; 2231 neqe++; 2232 } 2233 oce_dma_sync(&eq->ring->dma, BUS_DMASYNC_PREWRITE); 2234 oce_arm_eq(eq, neqe, FALSE, TRUE); 2235} 2236 2237void 2238oce_destroy_eq(struct oce_eq *eq) 2239{ 2240 struct mbx_destroy_common_eq cmd; 2241 struct oce_softc *sc = eq->sc; 2242 2243 if (eq->id >= 0) { 2244 memset(&cmd, 0, sizeof(cmd)); 2245 cmd.params.req.id = htole16(eq->id); 2246 oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DESTROY_EQ, 2247 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 2248 } 2249 if (eq->ring != NULL) 2250 oce_destroy_ring(sc, eq->ring); 2251 free(eq, M_DEVBUF, 0); 2252} 2253 2254struct oce_mq * 2255oce_create_mq(struct oce_softc *sc, struct oce_eq *eq) 2256{ 2257 struct oce_mq *mq = NULL; 2258 struct oce_cq *cq; 2259 2260 /* allocate the mq */ 2261 mq = malloc(sizeof(struct oce_mq), M_DEVBUF, M_NOWAIT | M_ZERO); 2262 if (!mq) 2263 return (NULL); 2264 2265 mq->ring = oce_create_ring(sc, 128, sizeof(struct oce_mbx), 8); 2266 if (!mq->ring) { 2267 free(mq, M_DEVBUF, 0); 2268 return (NULL); 2269 } 2270 2271 cq = oce_create_cq(sc, eq, CQ_LEN_256, sizeof(struct oce_mq_cqe), 2272 1, 0, 0); 2273 if (!cq) { 2274 oce_destroy_ring(sc, mq->ring); 2275 free(mq, M_DEVBUF, 0); 2276 return (NULL); 2277 } 2278 2279 mq->id = -1; 2280 mq->sc = sc; 2281 mq->cq = cq; 2282 2283 mq->nitems = 128; 2284 2285 if (oce_new_mq(sc, mq)) { 2286 oce_destroy_cq(mq->cq); 2287 oce_destroy_ring(sc, mq->ring); 2288 free(mq, M_DEVBUF, 0); 2289 return (NULL); 2290 } 2291 2292 eq->cq[eq->cq_valid] = cq; 2293 eq->cq_valid++; 2294 mq->cq->eq = eq; 2295 mq->cq->cb_arg = mq; 2296 mq->cq->cq_intr = oce_intr_mq; 2297 2298 return (mq); 2299} 2300 2301void 2302oce_drain_mq(struct oce_mq *mq) 2303{ 2304 struct oce_cq *cq = mq->cq; 2305 struct oce_mq_cqe *cqe; 2306 int ncqe = 0; 2307 2308 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_POSTREAD); 2309 OCE_RING_FOREACH(cq->ring, cqe, MQ_CQE_VALID(cqe)) { 2310 MQ_CQE_INVALIDATE(cqe); 2311 ncqe++; 2312 } 2313 oce_dma_sync(&cq->ring->dma, BUS_DMASYNC_PREWRITE); 2314 oce_arm_cq(cq, ncqe, FALSE); 2315} 2316 2317void 2318oce_destroy_mq(struct oce_mq *mq) 2319{ 2320 struct mbx_destroy_common_mq cmd; 2321 struct oce_softc *sc = mq->sc; 2322 2323 if (mq->id >= 0) { 2324 memset(&cmd, 0, sizeof(cmd)); 2325 cmd.params.req.id = htole16(mq->id); 2326 oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DESTROY_MQ, 2327 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 2328 } 2329 if (mq->ring != NULL) 2330 oce_destroy_ring(sc, mq->ring); 2331 if (mq->cq != NULL) 2332 oce_destroy_cq(mq->cq); 2333 free(mq, M_DEVBUF, 0); 2334} 2335 2336/** 2337 * @brief Function to create a completion queue 2338 * @param sc software handle to the device 2339 * @param eq optional eq to be associated with to the cq 2340 * @param nitems length of completion queue 2341 * @param isize size of completion queue items 2342 * @param eventable event table 2343 * @param nodelay no delay flag 2344 * @param ncoalesce no coalescence flag 2345 * @returns pointer to the cq created, NULL on failure 2346 */ 2347struct oce_cq * 2348oce_create_cq(struct oce_softc *sc, struct oce_eq *eq, int nitems, int isize, 2349 int eventable, int nodelay, int ncoalesce) 2350{ 2351 struct oce_cq *cq = NULL; 2352 2353 cq = malloc(sizeof(struct oce_cq), M_DEVBUF, M_NOWAIT | M_ZERO); 2354 if (!cq) 2355 return (NULL); 2356 2357 cq->ring = oce_create_ring(sc, nitems, isize, 4); 2358 if (!cq->ring) { 2359 free(cq, M_DEVBUF, 0); 2360 return (NULL); 2361 } 2362 2363 cq->sc = sc; 2364 cq->eq = eq; 2365 cq->nitems = nitems; 2366 cq->nodelay = nodelay; 2367 cq->ncoalesce = ncoalesce; 2368 cq->eventable = eventable; 2369 2370 if (oce_new_cq(sc, cq)) { 2371 oce_destroy_ring(sc, cq->ring); 2372 free(cq, M_DEVBUF, 0); 2373 return (NULL); 2374 } 2375 2376 sc->sc_cq[sc->sc_ncq++] = cq; 2377 2378 return (cq); 2379} 2380 2381void 2382oce_destroy_cq(struct oce_cq *cq) 2383{ 2384 struct mbx_destroy_common_cq cmd; 2385 struct oce_softc *sc = cq->sc; 2386 2387 if (cq->id >= 0) { 2388 memset(&cmd, 0, sizeof(cmd)); 2389 cmd.params.req.id = htole16(cq->id); 2390 oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DESTROY_CQ, 2391 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 2392 } 2393 if (cq->ring != NULL) 2394 oce_destroy_ring(sc, cq->ring); 2395 free(cq, M_DEVBUF, 0); 2396} 2397 2398/** 2399 * @brief Function to arm a CQ with CQEs 2400 * @param cq pointer to the completion queue structure 2401 * @param ncqe number of CQEs to arm 2402 * @param rearm rearm bit enable/disable 2403 */ 2404static inline void 2405oce_arm_cq(struct oce_cq *cq, int ncqe, int rearm) 2406{ 2407 oce_write_db(cq->sc, PD_CQ_DB, cq->id | (ncqe << 16) | (rearm << 29)); 2408} 2409 2410void 2411oce_free_posted_rxbuf(struct oce_rq *rq) 2412{ 2413 struct oce_softc *sc = rq->sc; 2414 struct oce_pkt *pkt; 2415 2416 while ((pkt = oce_pkt_get(&rq->pkt_list)) != NULL) { 2417 bus_dmamap_sync(sc->sc_dmat, pkt->map, 0, pkt->map->dm_mapsize, 2418 BUS_DMASYNC_POSTREAD); 2419 bus_dmamap_unload(sc->sc_dmat, pkt->map); 2420 if (pkt->mbuf != NULL) { 2421 m_freem(pkt->mbuf); 2422 pkt->mbuf = NULL; 2423 } 2424 oce_pkt_put(&rq->pkt_free, pkt); 2425 if_rxr_put(&rq->rxring, 1); 2426 } 2427} 2428 2429int 2430oce_dma_alloc(struct oce_softc *sc, bus_size_t size, struct oce_dma_mem *dma) 2431{ 2432 int rc; 2433 2434 memset(dma, 0, sizeof(struct oce_dma_mem)); 2435 2436 dma->tag = sc->sc_dmat; 2437 rc = bus_dmamap_create(dma->tag, size, 1, size, 0, BUS_DMA_NOWAIT, 2438 &dma->map); 2439 if (rc != 0) { 2440 printf("%s: failed to allocate DMA handle", 2441 sc->sc_dev.dv_xname); 2442 goto fail_0; 2443 } 2444 2445 rc = bus_dmamem_alloc(dma->tag, size, PAGE_SIZE, 0, &dma->segs, 1, 2446 &dma->nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO); 2447 if (rc != 0) { 2448 printf("%s: failed to allocate DMA memory", 2449 sc->sc_dev.dv_xname); 2450 goto fail_1; 2451 } 2452 2453 rc = bus_dmamem_map(dma->tag, &dma->segs, dma->nsegs, size, 2454 &dma->vaddr, BUS_DMA_NOWAIT); 2455 if (rc != 0) { 2456 printf("%s: failed to map DMA memory", sc->sc_dev.dv_xname); 2457 goto fail_2; 2458 } 2459 2460 rc = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size, NULL, 2461 BUS_DMA_NOWAIT); 2462 if (rc != 0) { 2463 printf("%s: failed to load DMA memory", sc->sc_dev.dv_xname); 2464 goto fail_3; 2465 } 2466 2467 bus_dmamap_sync(dma->tag, dma->map, 0, dma->map->dm_mapsize, 2468 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2469 2470 dma->paddr = dma->map->dm_segs[0].ds_addr; 2471 dma->size = size; 2472 2473 return (0); 2474 2475fail_3: 2476 bus_dmamem_unmap(dma->tag, dma->vaddr, size); 2477fail_2: 2478 bus_dmamem_free(dma->tag, &dma->segs, dma->nsegs); 2479fail_1: 2480 bus_dmamap_destroy(dma->tag, dma->map); 2481fail_0: 2482 return (rc); 2483} 2484 2485void 2486oce_dma_free(struct oce_softc *sc, struct oce_dma_mem *dma) 2487{ 2488 if (dma->tag == NULL) 2489 return; 2490 2491 if (dma->map != NULL) { 2492 oce_dma_sync(dma, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2493 bus_dmamap_unload(dma->tag, dma->map); 2494 2495 if (dma->vaddr != 0) { 2496 bus_dmamem_free(dma->tag, &dma->segs, dma->nsegs); 2497 dma->vaddr = 0; 2498 } 2499 2500 bus_dmamap_destroy(dma->tag, dma->map); 2501 dma->map = NULL; 2502 dma->tag = NULL; 2503 } 2504} 2505 2506struct oce_ring * 2507oce_create_ring(struct oce_softc *sc, int nitems, int isize, int maxsegs) 2508{ 2509 struct oce_dma_mem *dma; 2510 struct oce_ring *ring; 2511 bus_size_t size = nitems * isize; 2512 int rc; 2513 2514 if (size > maxsegs * PAGE_SIZE) 2515 return (NULL); 2516 2517 ring = malloc(sizeof(struct oce_ring), M_DEVBUF, M_NOWAIT | M_ZERO); 2518 if (ring == NULL) 2519 return (NULL); 2520 2521 ring->isize = isize; 2522 ring->nitems = nitems; 2523 2524 dma = &ring->dma; 2525 dma->tag = sc->sc_dmat; 2526 rc = bus_dmamap_create(dma->tag, size, maxsegs, PAGE_SIZE, 0, 2527 BUS_DMA_NOWAIT, &dma->map); 2528 if (rc != 0) { 2529 printf("%s: failed to allocate DMA handle", 2530 sc->sc_dev.dv_xname); 2531 goto fail_0; 2532 } 2533 2534 rc = bus_dmamem_alloc(dma->tag, size, 0, 0, &dma->segs, maxsegs, 2535 &dma->nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO); 2536 if (rc != 0) { 2537 printf("%s: failed to allocate DMA memory", 2538 sc->sc_dev.dv_xname); 2539 goto fail_1; 2540 } 2541 2542 rc = bus_dmamem_map(dma->tag, &dma->segs, dma->nsegs, size, 2543 &dma->vaddr, BUS_DMA_NOWAIT); 2544 if (rc != 0) { 2545 printf("%s: failed to map DMA memory", sc->sc_dev.dv_xname); 2546 goto fail_2; 2547 } 2548 2549 bus_dmamap_sync(dma->tag, dma->map, 0, dma->map->dm_mapsize, 2550 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2551 2552 dma->paddr = 0; 2553 dma->size = size; 2554 2555 return (ring); 2556 2557fail_2: 2558 bus_dmamem_free(dma->tag, &dma->segs, dma->nsegs); 2559fail_1: 2560 bus_dmamap_destroy(dma->tag, dma->map); 2561fail_0: 2562 free(ring, M_DEVBUF, 0); 2563 return (NULL); 2564} 2565 2566void 2567oce_destroy_ring(struct oce_softc *sc, struct oce_ring *ring) 2568{ 2569 oce_dma_free(sc, &ring->dma); 2570 free(ring, M_DEVBUF, 0); 2571} 2572 2573int 2574oce_load_ring(struct oce_softc *sc, struct oce_ring *ring, 2575 struct oce_pa *pa, int maxsegs) 2576{ 2577 struct oce_dma_mem *dma = &ring->dma; 2578 int i; 2579 2580 if (bus_dmamap_load(dma->tag, dma->map, dma->vaddr, 2581 ring->isize * ring->nitems, NULL, BUS_DMA_NOWAIT)) { 2582 printf("%s: failed to load a ring map\n", sc->sc_dev.dv_xname); 2583 return (0); 2584 } 2585 2586 if (dma->map->dm_nsegs > maxsegs) { 2587 printf("%s: too many segments\n", sc->sc_dev.dv_xname); 2588 return (0); 2589 } 2590 2591 bus_dmamap_sync(dma->tag, dma->map, 0, dma->map->dm_mapsize, 2592 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2593 2594 for (i = 0; i < dma->map->dm_nsegs; i++) 2595 pa[i].addr = dma->map->dm_segs[i].ds_addr; 2596 2597 return (dma->map->dm_nsegs); 2598} 2599 2600static inline void * 2601oce_ring_get(struct oce_ring *ring) 2602{ 2603 int index = ring->index; 2604 2605 if (++ring->index == ring->nitems) 2606 ring->index = 0; 2607 return ((void *)(ring->dma.vaddr + index * ring->isize)); 2608} 2609 2610static inline void * 2611oce_ring_first(struct oce_ring *ring) 2612{ 2613 return ((void *)(ring->dma.vaddr + ring->index * ring->isize)); 2614} 2615 2616static inline void * 2617oce_ring_next(struct oce_ring *ring) 2618{ 2619 if (++ring->index == ring->nitems) 2620 ring->index = 0; 2621 return ((void *)(ring->dma.vaddr + ring->index * ring->isize)); 2622} 2623 2624struct oce_pkt * 2625oce_pkt_alloc(struct oce_softc *sc, size_t size, int nsegs, int maxsegsz) 2626{ 2627 struct oce_pkt *pkt; 2628 2629 if ((pkt = pool_get(oce_pkt_pool, PR_NOWAIT | PR_ZERO)) == NULL) 2630 return (NULL); 2631 2632 if (bus_dmamap_create(sc->sc_dmat, size, nsegs, maxsegsz, 0, 2633 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &pkt->map)) { 2634 pool_put(oce_pkt_pool, pkt); 2635 return (NULL); 2636 } 2637 2638 return (pkt); 2639} 2640 2641void 2642oce_pkt_free(struct oce_softc *sc, struct oce_pkt *pkt) 2643{ 2644 if (pkt->map) { 2645 bus_dmamap_unload(sc->sc_dmat, pkt->map); 2646 bus_dmamap_destroy(sc->sc_dmat, pkt->map); 2647 } 2648 pool_put(oce_pkt_pool, pkt); 2649} 2650 2651static inline struct oce_pkt * 2652oce_pkt_get(struct oce_pkt_list *lst) 2653{ 2654 struct oce_pkt *pkt; 2655 2656 pkt = SIMPLEQ_FIRST(lst); 2657 if (pkt == NULL) 2658 return (NULL); 2659 2660 SIMPLEQ_REMOVE_HEAD(lst, entry); 2661 2662 return (pkt); 2663} 2664 2665static inline void 2666oce_pkt_put(struct oce_pkt_list *lst, struct oce_pkt *pkt) 2667{ 2668 SIMPLEQ_INSERT_TAIL(lst, pkt, entry); 2669} 2670 2671/** 2672 * @brief Wait for FW to become ready and reset it 2673 * @param sc software handle to the device 2674 */ 2675int 2676oce_init_fw(struct oce_softc *sc) 2677{ 2678 struct ioctl_common_function_reset cmd; 2679 uint32_t reg; 2680 int err = 0, tmo = 60000; 2681 2682 /* read semaphore CSR */ 2683 reg = oce_read_csr(sc, MPU_EP_SEMAPHORE(sc)); 2684 2685 /* if host is ready then wait for fw ready else send POST */ 2686 if ((reg & MPU_EP_SEM_STAGE_MASK) <= POST_STAGE_AWAITING_HOST_RDY) { 2687 reg = (reg & ~MPU_EP_SEM_STAGE_MASK) | POST_STAGE_CHIP_RESET; 2688 oce_write_csr(sc, MPU_EP_SEMAPHORE(sc), reg); 2689 } 2690 2691 /* wait for FW to become ready */ 2692 for (;;) { 2693 if (--tmo == 0) 2694 break; 2695 2696 DELAY(1000); 2697 2698 reg = oce_read_csr(sc, MPU_EP_SEMAPHORE(sc)); 2699 if (reg & MPU_EP_SEM_ERROR) { 2700 printf(": POST failed: %#x\n", reg); 2701 return (ENXIO); 2702 } 2703 if ((reg & MPU_EP_SEM_STAGE_MASK) == POST_STAGE_ARMFW_READY) { 2704 /* reset FW */ 2705 if (ISSET(sc->sc_flags, OCE_F_RESET_RQD)) { 2706 memset(&cmd, 0, sizeof(cmd)); 2707 err = oce_cmd(sc, SUBSYS_COMMON, 2708 OPCODE_COMMON_FUNCTION_RESET, 2709 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 2710 } 2711 return (err); 2712 } 2713 } 2714 2715 printf(": POST timed out: %#x\n", reg); 2716 2717 return (ENXIO); 2718} 2719 2720static inline int 2721oce_mbox_wait(struct oce_softc *sc) 2722{ 2723 int i; 2724 2725 for (i = 0; i < 20000; i++) { 2726 if (oce_read_db(sc, PD_MPU_MBOX_DB) & PD_MPU_MBOX_DB_READY) 2727 return (0); 2728 DELAY(100); 2729 } 2730 return (ETIMEDOUT); 2731} 2732 2733/** 2734 * @brief Mailbox dispatch 2735 * @param sc software handle to the device 2736 */ 2737int 2738oce_mbox_dispatch(struct oce_softc *sc) 2739{ 2740 uint32_t pa, reg; 2741 int err; 2742 2743 pa = (uint32_t)((uint64_t)OCE_MEM_DVA(&sc->sc_mbx) >> 34); 2744 reg = PD_MPU_MBOX_DB_HI | (pa << PD_MPU_MBOX_DB_ADDR_SHIFT); 2745 2746 if ((err = oce_mbox_wait(sc)) != 0) 2747 goto out; 2748 2749 oce_write_db(sc, PD_MPU_MBOX_DB, reg); 2750 2751 pa = (uint32_t)((uint64_t)OCE_MEM_DVA(&sc->sc_mbx) >> 4) & 0x3fffffff; 2752 reg = pa << PD_MPU_MBOX_DB_ADDR_SHIFT; 2753 2754 if ((err = oce_mbox_wait(sc)) != 0) 2755 goto out; 2756 2757 oce_write_db(sc, PD_MPU_MBOX_DB, reg); 2758 2759 oce_dma_sync(&sc->sc_mbx, BUS_DMASYNC_POSTWRITE); 2760 2761 if ((err = oce_mbox_wait(sc)) != 0) 2762 goto out; 2763 2764out: 2765 oce_dma_sync(&sc->sc_mbx, BUS_DMASYNC_PREREAD); 2766 return (err); 2767} 2768 2769/** 2770 * @brief Function to initialize the hw with host endian information 2771 * @param sc software handle to the device 2772 * @returns 0 on success, ETIMEDOUT on failure 2773 */ 2774int 2775oce_mbox_init(struct oce_softc *sc) 2776{ 2777 struct oce_bmbx *bmbx = OCE_MEM_KVA(&sc->sc_mbx); 2778 uint8_t *ptr = (uint8_t *)&bmbx->mbx; 2779 2780 if (!ISSET(sc->sc_flags, OCE_F_MBOX_ENDIAN_RQD)) 2781 return (0); 2782 2783 /* Endian Signature */ 2784 *ptr++ = 0xff; 2785 *ptr++ = 0x12; 2786 *ptr++ = 0x34; 2787 *ptr++ = 0xff; 2788 *ptr++ = 0xff; 2789 *ptr++ = 0x56; 2790 *ptr++ = 0x78; 2791 *ptr = 0xff; 2792 2793 return (oce_mbox_dispatch(sc)); 2794} 2795 2796int 2797oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version, 2798 void *payload, int length) 2799{ 2800 struct oce_bmbx *bmbx = OCE_MEM_KVA(&sc->sc_mbx); 2801 struct oce_mbx *mbx = &bmbx->mbx; 2802 struct mbx_hdr *hdr; 2803 caddr_t epayload = NULL; 2804 int err; 2805 2806 if (length > OCE_MBX_PAYLOAD) 2807 epayload = OCE_MEM_KVA(&sc->sc_pld); 2808 if (length > OCE_MAX_PAYLOAD) 2809 return (EINVAL); 2810 2811 oce_dma_sync(&sc->sc_mbx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2812 2813 memset(mbx, 0, sizeof(struct oce_mbx)); 2814 2815 mbx->payload_length = length; 2816 2817 if (epayload) { 2818 mbx->flags = OCE_MBX_F_SGE; 2819 oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_PREREAD); 2820 memcpy(epayload, payload, length); 2821 mbx->pld.sgl[0].addr = OCE_MEM_DVA(&sc->sc_pld); 2822 mbx->pld.sgl[0].length = length; 2823 hdr = (struct mbx_hdr *)epayload; 2824 } else { 2825 mbx->flags = OCE_MBX_F_EMBED; 2826 memcpy(mbx->pld.data, payload, length); 2827 hdr = (struct mbx_hdr *)&mbx->pld.data; 2828 } 2829 2830 hdr->subsys = subsys; 2831 hdr->opcode = opcode; 2832 hdr->version = version; 2833 hdr->length = length - sizeof(*hdr); 2834 if (opcode == OPCODE_COMMON_FUNCTION_RESET) 2835 hdr->timeout = 2 * OCE_MBX_TIMEOUT; 2836 else 2837 hdr->timeout = OCE_MBX_TIMEOUT; 2838 2839 if (epayload) 2840 oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_PREWRITE); 2841 2842 err = oce_mbox_dispatch(sc); 2843 if (err == 0) { 2844 if (epayload) { 2845 oce_dma_sync(&sc->sc_pld, BUS_DMASYNC_POSTWRITE); 2846 memcpy(payload, epayload, length); 2847 } else 2848 memcpy(payload, &mbx->pld.data, length); 2849 } else 2850 printf("%s: mailbox timeout, subsys %d op %d ver %d " 2851 "%spayload length %d\n", sc->sc_dev.dv_xname, subsys, 2852 opcode, version, epayload ? "ext " : "", 2853 length); 2854 return (err); 2855} 2856 2857/** 2858 * @brief Firmware will send gracious notifications during 2859 * attach only after sending first mcc command. We 2860 * use MCC queue only for getting async and mailbox 2861 * for sending cmds. So to get gracious notifications 2862 * at least send one dummy command on mcc. 2863 */ 2864void 2865oce_first_mcc(struct oce_softc *sc) 2866{ 2867 struct oce_mbx *mbx; 2868 struct oce_mq *mq = sc->sc_mq; 2869 struct mbx_hdr *hdr; 2870 struct mbx_get_common_fw_version *cmd; 2871 2872 mbx = oce_ring_get(mq->ring); 2873 memset(mbx, 0, sizeof(struct oce_mbx)); 2874 2875 cmd = (struct mbx_get_common_fw_version *)&mbx->pld.data; 2876 2877 hdr = &cmd->hdr; 2878 hdr->subsys = SUBSYS_COMMON; 2879 hdr->opcode = OPCODE_COMMON_GET_FW_VERSION; 2880 hdr->version = OCE_MBX_VER_V0; 2881 hdr->timeout = OCE_MBX_TIMEOUT; 2882 hdr->length = sizeof(*cmd) - sizeof(*hdr); 2883 2884 mbx->flags = OCE_MBX_F_EMBED; 2885 mbx->payload_length = sizeof(*cmd); 2886 oce_dma_sync(&mq->ring->dma, BUS_DMASYNC_PREREAD | 2887 BUS_DMASYNC_PREWRITE); 2888 oce_write_db(sc, PD_MQ_DB, mq->id | (1 << 16)); 2889} 2890 2891int 2892oce_get_fw_config(struct oce_softc *sc) 2893{ 2894 struct mbx_common_query_fw_config cmd; 2895 int err; 2896 2897 memset(&cmd, 0, sizeof(cmd)); 2898 2899 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, 2900 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 2901 if (err) 2902 return (err); 2903 2904 sc->sc_port = cmd.params.rsp.port_id; 2905 sc->sc_fmode = cmd.params.rsp.function_mode; 2906 2907 return (0); 2908} 2909 2910int 2911oce_check_native_mode(struct oce_softc *sc) 2912{ 2913 struct mbx_common_set_function_cap cmd; 2914 int err; 2915 2916 memset(&cmd, 0, sizeof(cmd)); 2917 2918 cmd.params.req.valid_capability_flags = CAP_SW_TIMESTAMPS | 2919 CAP_BE3_NATIVE_ERX_API; 2920 cmd.params.req.capability_flags = CAP_BE3_NATIVE_ERX_API; 2921 2922 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_FUNCTIONAL_CAPS, 2923 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 2924 if (err) 2925 return (err); 2926 2927 if (cmd.params.rsp.capability_flags & CAP_BE3_NATIVE_ERX_API) 2928 SET(sc->sc_flags, OCE_F_BE3_NATIVE); 2929 2930 return (0); 2931} 2932 2933/** 2934 * @brief Function for creating a network interface. 2935 * @param sc software handle to the device 2936 * @returns 0 on success, error otherwise 2937 */ 2938int 2939oce_create_iface(struct oce_softc *sc, uint8_t *macaddr) 2940{ 2941 struct mbx_create_common_iface cmd; 2942 uint32_t caps, caps_en; 2943 int err = 0; 2944 2945 /* interface capabilities to give device when creating interface */ 2946 caps = MBX_RX_IFACE_BROADCAST | MBX_RX_IFACE_UNTAGGED | 2947 MBX_RX_IFACE_PROMISC | MBX_RX_IFACE_MCAST_PROMISC | 2948 MBX_RX_IFACE_RSS; 2949 2950 /* capabilities to enable by default (others set dynamically) */ 2951 caps_en = MBX_RX_IFACE_BROADCAST | MBX_RX_IFACE_UNTAGGED; 2952 2953 if (!IS_XE201(sc)) { 2954 /* LANCER A0 workaround */ 2955 caps |= MBX_RX_IFACE_PASS_L3L4_ERR; 2956 caps_en |= MBX_RX_IFACE_PASS_L3L4_ERR; 2957 } 2958 2959 /* enable capabilities controlled via driver startup parameters */ 2960 if (sc->sc_rss_enable) 2961 caps_en |= MBX_RX_IFACE_RSS; 2962 2963 memset(&cmd, 0, sizeof(cmd)); 2964 2965 cmd.params.req.version = 0; 2966 cmd.params.req.cap_flags = htole32(caps); 2967 cmd.params.req.enable_flags = htole32(caps_en); 2968 if (macaddr != NULL) { 2969 memcpy(&cmd.params.req.mac_addr[0], macaddr, ETHER_ADDR_LEN); 2970 cmd.params.req.mac_invalid = 0; 2971 } else 2972 cmd.params.req.mac_invalid = 1; 2973 2974 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_IFACE, 2975 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 2976 if (err) 2977 return (err); 2978 2979 sc->sc_if_id = letoh32(cmd.params.rsp.if_id); 2980 2981 if (macaddr != NULL) 2982 sc->sc_pmac_id = letoh32(cmd.params.rsp.pmac_id); 2983 2984 return (0); 2985} 2986 2987/** 2988 * @brief Function to send the mbx command to configure vlan 2989 * @param sc software handle to the device 2990 * @param vtags array of vlan tags 2991 * @param nvtags number of elements in array 2992 * @param untagged boolean TRUE/FLASE 2993 * @param promisc flag to enable/disable VLAN promiscuous mode 2994 * @returns 0 on success, EIO on failure 2995 */ 2996int 2997oce_config_vlan(struct oce_softc *sc, struct normal_vlan *vtags, int nvtags, 2998 int untagged, int promisc) 2999{ 3000 struct mbx_common_config_vlan cmd; 3001 3002 memset(&cmd, 0, sizeof(cmd)); 3003 3004 cmd.params.req.if_id = sc->sc_if_id; 3005 cmd.params.req.promisc = promisc; 3006 cmd.params.req.untagged = untagged; 3007 cmd.params.req.num_vlans = nvtags; 3008 3009 if (!promisc) 3010 memcpy(cmd.params.req.tags.normal_vlans, vtags, 3011 nvtags * sizeof(struct normal_vlan)); 3012 3013 return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CONFIG_IFACE_VLAN, 3014 OCE_MBX_VER_V0, &cmd, sizeof(cmd))); 3015} 3016 3017/** 3018 * @brief Function to set flow control capability in the hardware 3019 * @param sc software handle to the device 3020 * @param flags flow control flags to set 3021 * @returns 0 on success, EIO on failure 3022 */ 3023int 3024oce_set_flow_control(struct oce_softc *sc, uint64_t flags) 3025{ 3026 struct mbx_common_get_set_flow_control cmd; 3027 int err; 3028 3029 memset(&cmd, 0, sizeof(cmd)); 3030 3031 cmd.rx_flow_control = flags & IFM_ETH_RXPAUSE ? 1 : 0; 3032 cmd.tx_flow_control = flags & IFM_ETH_TXPAUSE ? 1 : 0; 3033 3034 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_FLOW_CONTROL, 3035 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 3036 if (err) 3037 return (err); 3038 3039 memset(&cmd, 0, sizeof(cmd)); 3040 3041 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_GET_FLOW_CONTROL, 3042 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 3043 if (err) 3044 return (err); 3045 3046 sc->sc_fc = cmd.rx_flow_control ? IFM_ETH_RXPAUSE : 0; 3047 sc->sc_fc |= cmd.tx_flow_control ? IFM_ETH_TXPAUSE : 0; 3048 3049 return (0); 3050} 3051 3052#ifdef OCE_RSS 3053/** 3054 * @brief Function to set flow control capability in the hardware 3055 * @param sc software handle to the device 3056 * @param enable 0=disable, OCE_RSS_xxx flags otherwise 3057 * @returns 0 on success, EIO on failure 3058 */ 3059int 3060oce_config_rss(struct oce_softc *sc, int enable) 3061{ 3062 struct mbx_config_nic_rss cmd; 3063 uint8_t *tbl = &cmd.params.req.cputable; 3064 int i, j; 3065 3066 memset(&cmd, 0, sizeof(cmd)); 3067 3068 if (enable) 3069 cmd.params.req.enable_rss = RSS_ENABLE_IPV4 | RSS_ENABLE_IPV6 | 3070 RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_TCP_IPV6; 3071 cmd.params.req.flush = OCE_FLUSH; 3072 cmd.params.req.if_id = htole32(sc->sc_if_id); 3073 3074 arc4random_buf(cmd.params.req.hash, sizeof(cmd.params.req.hash)); 3075 3076 /* 3077 * Initialize the RSS CPU indirection table. 3078 * 3079 * The table is used to choose the queue to place incoming packets. 3080 * Incoming packets are hashed. The lowest bits in the hash result 3081 * are used as the index into the CPU indirection table. 3082 * Each entry in the table contains the RSS CPU-ID returned by the NIC 3083 * create. Based on the CPU ID, the receive completion is routed to 3084 * the corresponding RSS CQs. (Non-RSS packets are always completed 3085 * on the default (0) CQ). 3086 */ 3087 for (i = 0, j = 0; j < sc->sc_nrq; j++) { 3088 if (sc->sc_rq[j]->cfg.is_rss_queue) 3089 tbl[i++] = sc->sc_rq[j]->rss_cpuid; 3090 } 3091 if (i > 0) 3092 cmd->params.req.cpu_tbl_sz_log2 = htole16(ilog2(i)); 3093 else 3094 return (ENXIO); 3095 3096 return (oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CONFIG_RSS, OCE_MBX_VER_V0, 3097 &cmd, sizeof(cmd))); 3098} 3099#endif /* OCE_RSS */ 3100 3101/** 3102 * @brief Function for hardware update multicast filter 3103 * @param sc software handle to the device 3104 * @param multi table of multicast addresses 3105 * @param naddr number of multicast addresses in the table 3106 */ 3107int 3108oce_update_mcast(struct oce_softc *sc, 3109 uint8_t multi[][ETHER_ADDR_LEN], int naddr) 3110{ 3111 struct mbx_set_common_iface_multicast cmd; 3112 3113 memset(&cmd, 0, sizeof(cmd)); 3114 3115 memcpy(&cmd.params.req.mac[0], &multi[0], naddr * ETHER_ADDR_LEN); 3116 cmd.params.req.num_mac = htole16(naddr); 3117 cmd.params.req.if_id = sc->sc_if_id; 3118 3119 return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_IFACE_MULTICAST, 3120 OCE_MBX_VER_V0, &cmd, sizeof(cmd))); 3121} 3122 3123/** 3124 * @brief RXF function to enable/disable device promiscuous mode 3125 * @param sc software handle to the device 3126 * @param enable enable/disable flag 3127 * @returns 0 on success, EIO on failure 3128 * @note 3129 * The OPCODE_NIC_CONFIG_PROMISCUOUS command deprecated for Lancer. 3130 * This function uses the COMMON_SET_IFACE_RX_FILTER command instead. 3131 */ 3132int 3133oce_set_promisc(struct oce_softc *sc, int enable) 3134{ 3135 struct mbx_set_common_iface_rx_filter cmd; 3136 struct iface_rx_filter_ctx *req; 3137 3138 memset(&cmd, 0, sizeof(cmd)); 3139 3140 req = &cmd.params.req; 3141 req->if_id = sc->sc_if_id; 3142 3143 if (enable) 3144 req->iface_flags = req->iface_flags_mask = 3145 MBX_RX_IFACE_PROMISC | MBX_RX_IFACE_VLAN_PROMISC; 3146 3147 return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_IFACE_RX_FILTER, 3148 OCE_MBX_VER_V0, &cmd, sizeof(cmd))); 3149} 3150 3151/** 3152 * @brief Function to query the link status from the hardware 3153 * @param sc software handle to the device 3154 * @param[out] link pointer to the structure returning link attributes 3155 * @returns 0 on success, EIO on failure 3156 */ 3157int 3158oce_get_link_status(struct oce_softc *sc) 3159{ 3160 struct mbx_query_common_link_config cmd; 3161 int err; 3162 3163 memset(&cmd, 0, sizeof(cmd)); 3164 3165 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_LINK_CONFIG, 3166 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 3167 if (err) 3168 return (err); 3169 3170 sc->sc_link_up = (letoh32(cmd.params.rsp.logical_link_status) == 3171 NTWK_LOGICAL_LINK_UP); 3172 3173 if (cmd.params.rsp.mac_speed < 5) 3174 sc->sc_link_speed = cmd.params.rsp.mac_speed; 3175 else 3176 sc->sc_link_speed = 0; 3177 3178 return (0); 3179} 3180 3181void 3182oce_macaddr_set(struct oce_softc *sc) 3183{ 3184 uint32_t old_pmac_id = sc->sc_pmac_id; 3185 int status = 0; 3186 3187 if (!memcmp(sc->sc_macaddr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN)) 3188 return; 3189 3190 status = oce_macaddr_add(sc, sc->sc_ac.ac_enaddr, &sc->sc_pmac_id); 3191 if (!status) 3192 status = oce_macaddr_del(sc, old_pmac_id); 3193 else 3194 printf("%s: failed to set MAC address\n", sc->sc_dev.dv_xname); 3195} 3196 3197int 3198oce_macaddr_get(struct oce_softc *sc, uint8_t *macaddr) 3199{ 3200 struct mbx_query_common_iface_mac cmd; 3201 int err; 3202 3203 memset(&cmd, 0, sizeof(cmd)); 3204 3205 cmd.params.req.type = MAC_ADDRESS_TYPE_NETWORK; 3206 cmd.params.req.permanent = 1; 3207 3208 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_IFACE_MAC, 3209 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 3210 if (err == 0) 3211 memcpy(macaddr, &cmd.params.rsp.mac.mac_addr[0], 3212 ETHER_ADDR_LEN); 3213 return (err); 3214} 3215 3216int 3217oce_macaddr_add(struct oce_softc *sc, uint8_t *enaddr, uint32_t *pmac) 3218{ 3219 struct mbx_add_common_iface_mac cmd; 3220 int err; 3221 3222 memset(&cmd, 0, sizeof(cmd)); 3223 3224 cmd.params.req.if_id = htole16(sc->sc_if_id); 3225 memcpy(cmd.params.req.mac_address, enaddr, ETHER_ADDR_LEN); 3226 3227 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_ADD_IFACE_MAC, 3228 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 3229 if (err == 0) 3230 *pmac = letoh32(cmd.params.rsp.pmac_id); 3231 return (err); 3232} 3233 3234int 3235oce_macaddr_del(struct oce_softc *sc, uint32_t pmac) 3236{ 3237 struct mbx_del_common_iface_mac cmd; 3238 3239 memset(&cmd, 0, sizeof(cmd)); 3240 3241 cmd.params.req.if_id = htole16(sc->sc_if_id); 3242 cmd.params.req.pmac_id = htole32(pmac); 3243 3244 return (oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DEL_IFACE_MAC, 3245 OCE_MBX_VER_V0, &cmd, sizeof(cmd))); 3246} 3247 3248int 3249oce_new_rq(struct oce_softc *sc, struct oce_rq *rq) 3250{ 3251 struct mbx_create_nic_rq cmd; 3252 int err, npages; 3253 3254 memset(&cmd, 0, sizeof(cmd)); 3255 3256 npages = oce_load_ring(sc, rq->ring, &cmd.params.req.pages[0], 3257 nitems(cmd.params.req.pages)); 3258 if (!npages) { 3259 printf("%s: failed to load the rq ring\n", __func__); 3260 return (1); 3261 } 3262 3263 if (IS_XE201(sc)) { 3264 cmd.params.req.frag_size = rq->fragsize / 2048; 3265 cmd.params.req.page_size = 1; 3266 } else 3267 cmd.params.req.frag_size = ilog2(rq->fragsize); 3268 cmd.params.req.num_pages = npages; 3269 cmd.params.req.cq_id = rq->cq->id; 3270 cmd.params.req.if_id = htole32(sc->sc_if_id); 3271 cmd.params.req.max_frame_size = htole16(rq->mtu); 3272 cmd.params.req.is_rss_queue = htole32(rq->rss); 3273 3274 err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CREATE_RQ, 3275 IS_XE201(sc) ? OCE_MBX_VER_V1 : OCE_MBX_VER_V0, &cmd, 3276 sizeof(cmd)); 3277 if (err) 3278 return (err); 3279 3280 rq->id = letoh16(cmd.params.rsp.rq_id); 3281 rq->rss_cpuid = cmd.params.rsp.rss_cpuid; 3282 3283 return (0); 3284} 3285 3286int 3287oce_new_wq(struct oce_softc *sc, struct oce_wq *wq) 3288{ 3289 struct mbx_create_nic_wq cmd; 3290 int err, npages; 3291 3292 memset(&cmd, 0, sizeof(cmd)); 3293 3294 npages = oce_load_ring(sc, wq->ring, &cmd.params.req.pages[0], 3295 nitems(cmd.params.req.pages)); 3296 if (!npages) { 3297 printf("%s: failed to load the wq ring\n", __func__); 3298 return (1); 3299 } 3300 3301 if (IS_XE201(sc)) 3302 cmd.params.req.if_id = sc->sc_if_id; 3303 cmd.params.req.nic_wq_type = NIC_WQ_TYPE_STANDARD; 3304 cmd.params.req.num_pages = npages; 3305 cmd.params.req.wq_size = ilog2(wq->nitems) + 1; 3306 cmd.params.req.cq_id = htole16(wq->cq->id); 3307 cmd.params.req.ulp_num = 1; 3308 3309 err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CREATE_WQ, 3310 IS_XE201(sc) ? OCE_MBX_VER_V1 : OCE_MBX_VER_V0, &cmd, 3311 sizeof(cmd)); 3312 if (err) 3313 return (err); 3314 3315 wq->id = letoh16(cmd.params.rsp.wq_id); 3316 3317 return (0); 3318} 3319 3320int 3321oce_new_mq(struct oce_softc *sc, struct oce_mq *mq) 3322{ 3323 struct mbx_create_common_mq_ex cmd; 3324 union oce_mq_ext_ctx *ctx; 3325 int err, npages; 3326 3327 memset(&cmd, 0, sizeof(cmd)); 3328 3329 npages = oce_load_ring(sc, mq->ring, &cmd.params.req.pages[0], 3330 nitems(cmd.params.req.pages)); 3331 if (!npages) { 3332 printf("%s: failed to load the mq ring\n", __func__); 3333 return (-1); 3334 } 3335 3336 ctx = &cmd.params.req.context; 3337 ctx->v0.num_pages = npages; 3338 ctx->v0.cq_id = mq->cq->id; 3339 ctx->v0.ring_size = ilog2(mq->nitems) + 1; 3340 ctx->v0.valid = 1; 3341 /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ 3342 ctx->v0.async_evt_bitmap = 0xffffffff; 3343 3344 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_MQ_EXT, 3345 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 3346 if (err) 3347 return (err); 3348 3349 mq->id = letoh16(cmd.params.rsp.mq_id); 3350 3351 return (0); 3352} 3353 3354int 3355oce_new_eq(struct oce_softc *sc, struct oce_eq *eq) 3356{ 3357 struct mbx_create_common_eq cmd; 3358 int err, npages; 3359 3360 memset(&cmd, 0, sizeof(cmd)); 3361 3362 npages = oce_load_ring(sc, eq->ring, &cmd.params.req.pages[0], 3363 nitems(cmd.params.req.pages)); 3364 if (!npages) { 3365 printf("%s: failed to load the eq ring\n", __func__); 3366 return (-1); 3367 } 3368 3369 cmd.params.req.ctx.num_pages = htole16(npages); 3370 cmd.params.req.ctx.valid = 1; 3371 cmd.params.req.ctx.size = (eq->isize == 4) ? 0 : 1; 3372 cmd.params.req.ctx.count = ilog2(eq->nitems / 256); 3373 cmd.params.req.ctx.armed = 0; 3374 cmd.params.req.ctx.delay_mult = htole32(eq->delay); 3375 3376 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_EQ, 3377 OCE_MBX_VER_V0, &cmd, sizeof(cmd)); 3378 if (err) 3379 return (err); 3380 3381 eq->id = letoh16(cmd.params.rsp.eq_id); 3382 3383 return (0); 3384} 3385 3386int 3387oce_new_cq(struct oce_softc *sc, struct oce_cq *cq) 3388{ 3389 struct mbx_create_common_cq cmd; 3390 union oce_cq_ctx *ctx; 3391 int err, npages; 3392 3393 memset(&cmd, 0, sizeof(cmd)); 3394 3395 npages = oce_load_ring(sc, cq->ring, &cmd.params.req.pages[0], 3396 nitems(cmd.params.req.pages)); 3397 if (!npages) { 3398 printf("%s: failed to load the cq ring\n", __func__); 3399 return (-1); 3400 } 3401 3402 ctx = &cmd.params.req.cq_ctx; 3403 3404 if (IS_XE201(sc)) { 3405 ctx->v2.num_pages = htole16(npages); 3406 ctx->v2.page_size = 1; /* for 4K */ 3407 ctx->v2.eventable = cq->eventable; 3408 ctx->v2.valid = 1; 3409 ctx->v2.count = ilog2(cq->nitems / 256); 3410 ctx->v2.nodelay = cq->nodelay; 3411 ctx->v2.coalesce_wm = cq->ncoalesce; 3412 ctx->v2.armed = 0; 3413 ctx->v2.eq_id = cq->eq->id; 3414 if (ctx->v2.count == 3) { 3415 if (cq->nitems > (4*1024)-1) 3416 ctx->v2.cqe_count = (4*1024)-1; 3417 else 3418 ctx->v2.cqe_count = cq->nitems; 3419 } 3420 } else { 3421 ctx->v0.num_pages = htole16(npages); 3422 ctx->v0.eventable = cq->eventable; 3423 ctx->v0.valid = 1; 3424 ctx->v0.count = ilog2(cq->nitems / 256); 3425 ctx->v0.nodelay = cq->nodelay; 3426 ctx->v0.coalesce_wm = cq->ncoalesce; 3427 ctx->v0.armed = 0; 3428 ctx->v0.eq_id = cq->eq->id; 3429 } 3430 3431 err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_CQ, 3432 IS_XE201(sc) ? OCE_MBX_VER_V2 : OCE_MBX_VER_V0, &cmd, 3433 sizeof(cmd)); 3434 if (err) 3435 return (err); 3436 3437 cq->id = letoh16(cmd.params.rsp.cq_id); 3438 3439 return (0); 3440} 3441 3442int 3443oce_init_stats(struct oce_softc *sc) 3444{ 3445 union cmd { 3446 struct mbx_get_nic_stats_v0 _be2; 3447 struct mbx_get_nic_stats _be3; 3448 struct mbx_get_pport_stats _xe201; 3449 }; 3450 3451 sc->sc_statcmd = malloc(sizeof(union cmd), M_DEVBUF, M_ZERO | M_NOWAIT); 3452 if (sc->sc_statcmd == NULL) { 3453 printf("%s: failed to allocate statistics command block\n", 3454 sc->sc_dev.dv_xname); 3455 return (-1); 3456 } 3457 return (0); 3458} 3459 3460int 3461oce_update_stats(struct oce_softc *sc) 3462{ 3463 struct ifnet *ifp = &sc->sc_ac.ac_if; 3464 uint64_t rxe, txe; 3465 int err; 3466 3467 if (ISSET(sc->sc_flags, OCE_F_BE2)) 3468 err = oce_stats_be2(sc, &rxe, &txe); 3469 else if (ISSET(sc->sc_flags, OCE_F_BE3)) 3470 err = oce_stats_be3(sc, &rxe, &txe); 3471 else 3472 err = oce_stats_xe(sc, &rxe, &txe); 3473 if (err) 3474 return (err); 3475 3476 ifp->if_ierrors += (rxe > sc->sc_rx_errors) ? 3477 rxe - sc->sc_rx_errors : sc->sc_rx_errors - rxe; 3478 sc->sc_rx_errors = rxe; 3479 ifp->if_oerrors += (txe > sc->sc_tx_errors) ? 3480 txe - sc->sc_tx_errors : sc->sc_tx_errors - txe; 3481 sc->sc_tx_errors = txe; 3482 3483 return (0); 3484} 3485 3486int 3487oce_stats_be2(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe) 3488{ 3489 struct mbx_get_nic_stats_v0 *cmd = sc->sc_statcmd; 3490 struct oce_pmem_stats *ms; 3491 struct oce_rxf_stats_v0 *rs; 3492 struct oce_port_rxf_stats_v0 *ps; 3493 int err; 3494 3495 memset(cmd, 0, sizeof(*cmd)); 3496 3497 err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_STATS, OCE_MBX_VER_V0, 3498 cmd, sizeof(*cmd)); 3499 if (err) 3500 return (err); 3501 3502 ms = &cmd->params.rsp.stats.pmem; 3503 rs = &cmd->params.rsp.stats.rxf; 3504 ps = &rs->port[sc->sc_port]; 3505 3506 *rxe = ps->rx_crc_errors + ps->rx_in_range_errors + 3507 ps->rx_frame_too_long + ps->rx_dropped_runt + 3508 ps->rx_ip_checksum_errs + ps->rx_tcp_checksum_errs + 3509 ps->rx_udp_checksum_errs + ps->rxpp_fifo_overflow_drop + 3510 ps->rx_dropped_tcp_length + ps->rx_dropped_too_small + 3511 ps->rx_dropped_too_short + ps->rx_out_range_errors + 3512 ps->rx_dropped_header_too_small + ps->rx_input_fifo_overflow_drop + 3513 ps->rx_alignment_symbol_errors; 3514 if (sc->sc_if_id) 3515 *rxe += rs->port1_jabber_events; 3516 else 3517 *rxe += rs->port0_jabber_events; 3518 *rxe += ms->eth_red_drops; 3519 3520 *txe = 0; /* hardware doesn't provide any extra tx error statistics */ 3521 3522 return (0); 3523} 3524 3525int 3526oce_stats_be3(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe) 3527{ 3528 struct mbx_get_nic_stats *cmd = sc->sc_statcmd; 3529 struct oce_pmem_stats *ms; 3530 struct oce_rxf_stats_v1 *rs; 3531 struct oce_port_rxf_stats_v1 *ps; 3532 int err; 3533 3534 memset(cmd, 0, sizeof(*cmd)); 3535 3536 err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_STATS, OCE_MBX_VER_V1, 3537 cmd, sizeof(*cmd)); 3538 if (err) 3539 return (err); 3540 3541 ms = &cmd->params.rsp.stats.pmem; 3542 rs = &cmd->params.rsp.stats.rxf; 3543 ps = &rs->port[sc->sc_port]; 3544 3545 *rxe = ps->rx_crc_errors + ps->rx_in_range_errors + 3546 ps->rx_frame_too_long + ps->rx_dropped_runt + 3547 ps->rx_ip_checksum_errs + ps->rx_tcp_checksum_errs + 3548 ps->rx_udp_checksum_errs + ps->rxpp_fifo_overflow_drop + 3549 ps->rx_dropped_tcp_length + ps->rx_dropped_too_small + 3550 ps->rx_dropped_too_short + ps->rx_out_range_errors + 3551 ps->rx_dropped_header_too_small + ps->rx_input_fifo_overflow_drop + 3552 ps->rx_alignment_symbol_errors + ps->jabber_events; 3553 *rxe += ms->eth_red_drops; 3554 3555 *txe = 0; /* hardware doesn't provide any extra tx error statistics */ 3556 3557 return (0); 3558} 3559 3560int 3561oce_stats_xe(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe) 3562{ 3563 struct mbx_get_pport_stats *cmd = sc->sc_statcmd; 3564 struct oce_pport_stats *pps; 3565 int err; 3566 3567 memset(cmd, 0, sizeof(*cmd)); 3568 3569 cmd->params.req.reset_stats = 0; 3570 cmd->params.req.port_number = sc->sc_if_id; 3571 3572 err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_PPORT_STATS, 3573 OCE_MBX_VER_V0, cmd, sizeof(*cmd)); 3574 if (err) 3575 return (err); 3576 3577 pps = &cmd->params.rsp.pps; 3578 3579 *rxe = pps->rx_discards + pps->rx_errors + pps->rx_crc_errors + 3580 pps->rx_alignment_errors + pps->rx_symbol_errors + 3581 pps->rx_frames_too_long + pps->rx_internal_mac_errors + 3582 pps->rx_undersize_pkts + pps->rx_oversize_pkts + pps->rx_jabbers + 3583 pps->rx_control_frames_unknown_opcode + pps->rx_in_range_errors + 3584 pps->rx_out_of_range_errors + pps->rx_ip_checksum_errors + 3585 pps->rx_tcp_checksum_errors + pps->rx_udp_checksum_errors + 3586 pps->rx_fifo_overflow + pps->rx_input_fifo_overflow + 3587 pps->rx_drops_too_many_frags + pps->rx_drops_mtu; 3588 3589 *txe = pps->tx_discards + pps->tx_errors + pps->tx_internal_mac_errors; 3590 3591 return (0); 3592} 3593