Deleted Added
full compact
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
40/* $FreeBSD: head/sys/dev/oce/oce_if.c 252869 2013-07-06 08:30:45Z delphij $ */
41
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) {
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;
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;
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
1177 if (m != NULL) {
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++;
1667 oce_vid_config(sc);
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.
1893*/
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 ---