1/*- 2 * Copyright (C) 2013 Emulex 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, --- 22 unchanged lines hidden (view full) --- 31 * Contact Information: 32 * freebsd-drivers@emulex.com 33 * 34 * Emulex 35 * 3333 Susan Street 36 * Costa Mesa, CA 92626 37 */ 38 |
39/* $FreeBSD: head/sys/dev/oce/oce_if.c 257007 2013-10-23 18:58:38Z delphij $ */ |
40 |
41#include "opt_inet6.h" 42#include "opt_inet.h" 43 44#include "oce_if.h" 45 |
46/* UE Status Low CSR */ 47static char *ue_status_low_desc[] = { 48 "CEV", 49 "CTX", 50 "DBUF", 51 "ERX", 52 "Host", 53 "MPU", 54 "NDMA", 55 "PTC ", 56 "RDMA ", 57 "RXF ", 58 "RXIPS ", 59 "RXULP0 ", 60 "RXULP1 ", 61 "RXULP2 ", 62 "TIM ", 63 "TPOST ", 64 "TPRE ", 65 "TXIPS ", 66 "TXULP0 ", 67 "TXULP1 ", 68 "UC ", 69 "WDMA ", 70 "TXULP2 ", 71 "HOST1 ", 72 "P0_OB_LINK ", 73 "P1_OB_LINK ", 74 "HOST_GPIO ", 75 "MBOX ", 76 "AXGMAC0", 77 "AXGMAC1", 78 "JTAG", 79 "MPU_INTPEND" 80}; |
81 |
82/* UE Status High CSR */ 83static char *ue_status_hi_desc[] = { 84 "LPCMEMHOST", 85 "MGMT_MAC", 86 "PCS0ONLINE", 87 "MPU_IRAM", 88 "PCS1ONLINE", 89 "PCTL0", 90 "PCTL1", 91 "PMEM", 92 "RR", 93 "TXPB", 94 "RXPP", 95 "XAUI", 96 "TXP", 97 "ARM", 98 "IPC", 99 "HOST2", 100 "HOST3", 101 "HOST4", 102 "HOST5", 103 "HOST6", 104 "HOST7", 105 "HOST8", 106 "HOST9", 107 "NETC", 108 "Unknown", 109 "Unknown", 110 "Unknown", 111 "Unknown", 112 "Unknown", 113 "Unknown", 114 "Unknown", 115 "Unknown" 116}; 117 118 |
119/* Driver entry points prototypes */ 120static int oce_probe(device_t dev); 121static int oce_attach(device_t dev); 122static int oce_detach(device_t dev); 123static int oce_shutdown(device_t dev); 124static int oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data); 125static void oce_init(void *xsc); 126static int oce_multiq_start(struct ifnet *ifp, struct mbuf *m); --- 327 unchanged lines hidden (view full) --- 454 oce_if_deactivate(sc); 455 456 UNLOCK(&sc->dev_lock); 457 458 device_printf(sc->dev, "Interface Down\n"); 459 } 460 461 if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) { |
462 if (!oce_rxf_set_promiscuous(sc, (1 | (1 << 1)))) 463 sc->promisc = TRUE; |
464 } else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) { |
465 if (!oce_rxf_set_promiscuous(sc, 0)) 466 sc->promisc = FALSE; |
467 } 468 469 break; 470 471 case SIOCADDMULTI: 472 case SIOCDELMULTI: 473 rc = oce_hw_update_multicast(sc); 474 if (rc) --- 453 unchanged lines hidden (view full) --- 928 nichdr->u0.s.forward = 0; 929 nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0; 930 nichdr->u0.s.udpcs = 931 (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0; 932 nichdr->u0.s.tcpcs = 933 (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0; 934 nichdr->u0.s.num_wqe = num_wqes; 935 nichdr->u0.s.total_length = m->m_pkthdr.len; |
936 |
937 if (m->m_flags & M_VLANTAG) { 938 nichdr->u0.s.vlan = 1; /*Vlan present*/ 939 nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag; 940 } |
941 |
942 if (m->m_pkthdr.csum_flags & CSUM_TSO) { 943 if (m->m_pkthdr.tso_segsz) { 944 nichdr->u0.s.lso = 1; 945 nichdr->u0.s.lso_mss = m->m_pkthdr.tso_segsz; 946 } 947 if (!IS_BE(sc) || !IS_SH(sc)) 948 nichdr->u0.s.ipcs = 1; 949 } --- 274 unchanged lines hidden (view full) --- 1224 1225 if (num_cqes) 1226 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE); 1227 1228 return 0; 1229} 1230 1231 |
1232#if __FreeBSD_version >= 1000000 1233static __inline void 1234drbr_stats_update(struct ifnet *ifp, int len, int mflags) 1235{ 1236#ifndef NO_SLOW_STATS 1237 ifp->if_obytes += len; 1238 if (mflags & M_MCAST) 1239 ifp->if_omcasts++; 1240#endif 1241} 1242#endif 1243 |
1244static int 1245oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq) 1246{ 1247 POCE_SOFTC sc = ifp->if_softc; 1248 int status = 0, queue_index = 0; 1249 struct mbuf *next = NULL; 1250 struct buf_ring *br = NULL; 1251 1252 br = wq->br; 1253 queue_index = wq->queue_index; 1254 1255 if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 1256 IFF_DRV_RUNNING) { 1257 if (m != NULL) 1258 status = drbr_enqueue(ifp, br, m); 1259 return status; 1260 } 1261 |
1262 if (m != NULL) { |
1263 if ((status = drbr_enqueue(ifp, br, m)) != 0) 1264 return status; 1265 } 1266 while ((next = drbr_peek(ifp, br)) != NULL) { 1267 if (oce_tx(sc, &next, queue_index)) { 1268 if (next == NULL) { 1269 drbr_advance(ifp, br); 1270 } else { --- 455 unchanged lines hidden (view full) --- 1726 sc->ifp->if_capabilities |= IFCAP_TSO; 1727 sc->ifp->if_capabilities |= IFCAP_LRO; 1728 sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO; 1729#endif 1730 1731 sc->ifp->if_capenable = sc->ifp->if_capabilities; 1732 if_initbaudrate(sc->ifp, IF_Gbps(10)); 1733 |
1734#if __FreeBSD_version >= 1000000 1735 sc->ifp->if_hw_tsomax = OCE_MAX_TSO_SIZE; 1736#endif 1737 |
1738 ether_ifattach(sc->ifp, sc->macaddr.mac_addr); 1739 1740 return 0; 1741} 1742 1743 1744static void 1745oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag) 1746{ 1747 POCE_SOFTC sc = ifp->if_softc; 1748 1749 if (ifp->if_softc != arg) 1750 return; 1751 if ((vtag == 0) || (vtag > 4095)) 1752 return; 1753 1754 sc->vlan_tag[vtag] = 1; 1755 sc->vlans_added++; |
1756 if (sc->vlans_added <= (sc->max_vlans + 1)) 1757 oce_vid_config(sc); |
1758} 1759 1760 1761static void 1762oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag) 1763{ 1764 POCE_SOFTC sc = ifp->if_softc; 1765 --- 185 unchanged lines hidden (view full) --- 1951 } 1952 1953 /* Is there atleast one eq that needs to be modified? */ 1954 if(num) 1955 oce_mbox_eqd_modify_periodic(sc, set_eqd, num); 1956 1957} 1958 |
1959static void oce_detect_hw_error(POCE_SOFTC sc) 1960{ 1961 1962 uint32_t ue_low = 0, ue_high = 0, ue_low_mask = 0, ue_high_mask = 0; 1963 uint32_t sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; 1964 uint32_t i; 1965 1966 if (sc->hw_error) 1967 return; 1968 1969 if (IS_XE201(sc)) { 1970 sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET); 1971 if (sliport_status & SLIPORT_STATUS_ERR_MASK) { 1972 sliport_err1 = OCE_READ_REG32(sc, db, SLIPORT_ERROR1_OFFSET); 1973 sliport_err2 = OCE_READ_REG32(sc, db, SLIPORT_ERROR2_OFFSET); 1974 } 1975 } else { 1976 ue_low = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW); 1977 ue_high = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HIGH); 1978 ue_low_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW_MASK); 1979 ue_high_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HI_MASK); 1980 1981 ue_low = (ue_low & ~ue_low_mask); 1982 ue_high = (ue_high & ~ue_high_mask); 1983 } 1984 1985 /* On certain platforms BE hardware can indicate spurious UEs. 1986 * Allow the h/w to stop working completely in case of a real UE. 1987 * Hence not setting the hw_error for UE detection. 1988 */ 1989 if (sliport_status & SLIPORT_STATUS_ERR_MASK) { 1990 sc->hw_error = TRUE; 1991 device_printf(sc->dev, "Error detected in the card\n"); 1992 } 1993 1994 if (sliport_status & SLIPORT_STATUS_ERR_MASK) { 1995 device_printf(sc->dev, 1996 "ERR: sliport status 0x%x\n", sliport_status); 1997 device_printf(sc->dev, 1998 "ERR: sliport error1 0x%x\n", sliport_err1); 1999 device_printf(sc->dev, 2000 "ERR: sliport error2 0x%x\n", sliport_err2); 2001 } 2002 2003 if (ue_low) { 2004 for (i = 0; ue_low; ue_low >>= 1, i++) { 2005 if (ue_low & 1) 2006 device_printf(sc->dev, "UE: %s bit set\n", 2007 ue_status_low_desc[i]); 2008 } 2009 } 2010 2011 if (ue_high) { 2012 for (i = 0; ue_high; ue_high >>= 1, i++) { 2013 if (ue_high & 1) 2014 device_printf(sc->dev, "UE: %s bit set\n", 2015 ue_status_hi_desc[i]); 2016 } 2017 } 2018 2019} 2020 2021 |
2022static void 2023oce_local_timer(void *arg) 2024{ 2025 POCE_SOFTC sc = arg; 2026 int i = 0; 2027 |
2028 oce_detect_hw_error(sc); |
2029 oce_refresh_nic_stats(sc); 2030 oce_refresh_queue_stats(sc); 2031 oce_mac_addr_set(sc); 2032 2033 /* TX Watch Dog*/ 2034 for (i = 0; i < sc->nwqs; i++) 2035 oce_tx_restart(sc, sc->wq[i]); 2036 2037 /* calculate and set the eq delay for optimal interrupt rate */ 2038 if (IS_BE(sc) || IS_SH(sc)) 2039 oce_eqd_set_periodic(sc); 2040 2041 callout_reset(&sc->timer, hz, oce_local_timer, sc); 2042} 2043 2044 2045/* NOTE : This should only be called holding 2046 * DEVICE_LOCK. |
2047 */ |
2048static void 2049oce_if_deactivate(POCE_SOFTC sc) 2050{ 2051 int i, mtime = 0; 2052 int wait_req = 0; 2053 struct oce_rq *rq; 2054 struct oce_wq *wq; 2055 struct oce_eq *eq; --- 173 unchanged lines hidden (view full) --- 2229 /* Check if it is FLEX machine. Is so dont use RSS */ 2230 if ((sc->function_mode & FNM_FLEX10_MODE) || 2231 (sc->function_mode & FNM_UMC_MODE) || 2232 (sc->function_mode & FNM_VNIC_MODE) || 2233 (!is_rss_enabled(sc)) || 2234 (sc->flags & OCE_FLAGS_BE2)) { 2235 sc->nrqs = 1; 2236 sc->nwqs = 1; |
2237 } else { 2238 sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1; 2239 sc->nwqs = MIN(OCE_NCPUS, sc->nrssqs); |
2240 } 2241} 2242 2243 2244static void 2245update_queues_got(POCE_SOFTC sc) 2246{ 2247 if (is_rss_enabled(sc)) { --- 112 unchanged lines hidden --- |