oce_if.c (252869) | oce_if.c (257007) |
---|---|
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 | 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 $ */ |
|
39 | 40 |
40/* $FreeBSD: head/sys/dev/oce/oce_if.c 252869 2013-07-06 08:30:45Z delphij $ */ 41 | |
42#include "opt_inet6.h" 43#include "opt_inet.h" 44 45#include "oce_if.h" 46 | 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}; |
|
47 | 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 |
|
48/* Driver entry points prototypes */ 49static int oce_probe(device_t dev); 50static int oce_attach(device_t dev); 51static int oce_detach(device_t dev); 52static int oce_shutdown(device_t dev); 53static int oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data); 54static void oce_init(void *xsc); 55static int oce_multiq_start(struct ifnet *ifp, struct mbuf *m); --- 327 unchanged lines hidden (view full) --- 383 oce_if_deactivate(sc); 384 385 UNLOCK(&sc->dev_lock); 386 387 device_printf(sc->dev, "Interface Down\n"); 388 } 389 390 if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) { | 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) { |
391 sc->promisc = TRUE; 392 oce_rxf_set_promiscuous(sc, sc->promisc); | 462 if (!oce_rxf_set_promiscuous(sc, (1 | (1 << 1)))) 463 sc->promisc = TRUE; |
393 } else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) { | 464 } else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) { |
394 sc->promisc = FALSE; 395 oce_rxf_set_promiscuous(sc, sc->promisc); | 465 if (!oce_rxf_set_promiscuous(sc, 0)) 466 sc->promisc = FALSE; |
396 } 397 398 break; 399 400 case SIOCADDMULTI: 401 case SIOCDELMULTI: 402 rc = oce_hw_update_multicast(sc); 403 if (rc) --- 453 unchanged lines hidden (view full) --- 857 nichdr->u0.s.forward = 0; 858 nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0; 859 nichdr->u0.s.udpcs = 860 (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0; 861 nichdr->u0.s.tcpcs = 862 (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0; 863 nichdr->u0.s.num_wqe = num_wqes; 864 nichdr->u0.s.total_length = m->m_pkthdr.len; | 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 |
|
865 if (m->m_flags & M_VLANTAG) { 866 nichdr->u0.s.vlan = 1; /*Vlan present*/ 867 nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag; 868 } | 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 |
|
869 if (m->m_pkthdr.csum_flags & CSUM_TSO) { 870 if (m->m_pkthdr.tso_segsz) { 871 nichdr->u0.s.lso = 1; 872 nichdr->u0.s.lso_mss = m->m_pkthdr.tso_segsz; 873 } 874 if (!IS_BE(sc) || !IS_SH(sc)) 875 nichdr->u0.s.ipcs = 1; 876 } --- 274 unchanged lines hidden (view full) --- 1151 1152 if (num_cqes) 1153 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE); 1154 1155 return 0; 1156} 1157 1158 | 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 |
|
1159static int 1160oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq) 1161{ 1162 POCE_SOFTC sc = ifp->if_softc; 1163 int status = 0, queue_index = 0; 1164 struct mbuf *next = NULL; 1165 struct buf_ring *br = NULL; 1166 1167 br = wq->br; 1168 queue_index = wq->queue_index; 1169 1170 if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 1171 IFF_DRV_RUNNING) { 1172 if (m != NULL) 1173 status = drbr_enqueue(ifp, br, m); 1174 return status; 1175 } 1176 | 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 |
1177 if (m != NULL) { | 1262 if (m != NULL) { |
1178 if ((status = drbr_enqueue(ifp, br, m)) != 0) 1179 return status; 1180 } 1181 while ((next = drbr_peek(ifp, br)) != NULL) { 1182 if (oce_tx(sc, &next, queue_index)) { 1183 if (next == NULL) { 1184 drbr_advance(ifp, br); 1185 } else { --- 455 unchanged lines hidden (view full) --- 1641 sc->ifp->if_capabilities |= IFCAP_TSO; 1642 sc->ifp->if_capabilities |= IFCAP_LRO; 1643 sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO; 1644#endif 1645 1646 sc->ifp->if_capenable = sc->ifp->if_capabilities; 1647 if_initbaudrate(sc->ifp, IF_Gbps(10)); 1648 | 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 |
|
1649 ether_ifattach(sc->ifp, sc->macaddr.mac_addr); 1650 1651 return 0; 1652} 1653 1654 1655static void 1656oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag) 1657{ 1658 POCE_SOFTC sc = ifp->if_softc; 1659 1660 if (ifp->if_softc != arg) 1661 return; 1662 if ((vtag == 0) || (vtag > 4095)) 1663 return; 1664 1665 sc->vlan_tag[vtag] = 1; 1666 sc->vlans_added++; | 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++; |
1667 oce_vid_config(sc); | 1756 if (sc->vlans_added <= (sc->max_vlans + 1)) 1757 oce_vid_config(sc); |
1668} 1669 1670 1671static void 1672oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag) 1673{ 1674 POCE_SOFTC sc = ifp->if_softc; 1675 --- 185 unchanged lines hidden (view full) --- 1861 } 1862 1863 /* Is there atleast one eq that needs to be modified? */ 1864 if(num) 1865 oce_mbox_eqd_modify_periodic(sc, set_eqd, num); 1866 1867} 1868 | 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 |
|
1869static void 1870oce_local_timer(void *arg) 1871{ 1872 POCE_SOFTC sc = arg; 1873 int i = 0; 1874 | 2022static void 2023oce_local_timer(void *arg) 2024{ 2025 POCE_SOFTC sc = arg; 2026 int i = 0; 2027 |
2028 oce_detect_hw_error(sc); |
|
1875 oce_refresh_nic_stats(sc); 1876 oce_refresh_queue_stats(sc); 1877 oce_mac_addr_set(sc); 1878 1879 /* TX Watch Dog*/ 1880 for (i = 0; i < sc->nwqs; i++) 1881 oce_tx_restart(sc, sc->wq[i]); 1882 1883 /* calculate and set the eq delay for optimal interrupt rate */ 1884 if (IS_BE(sc) || IS_SH(sc)) 1885 oce_eqd_set_periodic(sc); 1886 1887 callout_reset(&sc->timer, hz, oce_local_timer, sc); 1888} 1889 1890 1891/* NOTE : This should only be called holding 1892 * DEVICE_LOCK. | 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. |
1893*/ | 2047 */ |
1894static void 1895oce_if_deactivate(POCE_SOFTC sc) 1896{ 1897 int i, mtime = 0; 1898 int wait_req = 0; 1899 struct oce_rq *rq; 1900 struct oce_wq *wq; 1901 struct oce_eq *eq; --- 173 unchanged lines hidden (view full) --- 2075 /* Check if it is FLEX machine. Is so dont use RSS */ 2076 if ((sc->function_mode & FNM_FLEX10_MODE) || 2077 (sc->function_mode & FNM_UMC_MODE) || 2078 (sc->function_mode & FNM_VNIC_MODE) || 2079 (!is_rss_enabled(sc)) || 2080 (sc->flags & OCE_FLAGS_BE2)) { 2081 sc->nrqs = 1; 2082 sc->nwqs = 1; | 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); |
|
2083 } 2084} 2085 2086 2087static void 2088update_queues_got(POCE_SOFTC sc) 2089{ 2090 if (is_rss_enabled(sc)) { --- 112 unchanged lines hidden --- | 2240 } 2241} 2242 2243 2244static void 2245update_queues_got(POCE_SOFTC sc) 2246{ 2247 if (is_rss_enabled(sc)) { --- 112 unchanged lines hidden --- |