Deleted Added
full compact
sfxge.c (277894) sfxge.c (278221)
1/*-
2 * Copyright (c) 2010-2011 Solarflare Communications, Inc.
3 * All rights reserved.
4 *
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2010-2011 Solarflare Communications, Inc.
3 * All rights reserved.
4 *
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge.c 277894 2015-01-29 19:09:14Z arybchik $");
31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge.c 278221 2015-02-04 20:03:57Z arybchik $");
32
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/bus.h>
36#include <sys/rman.h>
37#include <sys/lock.h>
38#include <sys/module.h>
39#include <sys/mutex.h>
40#include <sys/smp.h>
41#include <sys/socket.h>
42#include <sys/taskqueue.h>
43#include <sys/sockio.h>
44#include <sys/sysctl.h>
45#include <sys/syslog.h>
46
47#include <dev/pci/pcireg.h>
48#include <dev/pci/pcivar.h>
49
50#include <net/ethernet.h>
51#include <net/if.h>
52#include <net/if_var.h>
53#include <net/if_media.h>
54#include <net/if_types.h>
55
56#include "common/efx.h"
57
58#include "sfxge.h"
59#include "sfxge_rx.h"
60
61#define SFXGE_CAP (IFCAP_VLAN_MTU | \
62 IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | \
63 IFCAP_JUMBO_MTU | IFCAP_LRO | \
64 IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
65#define SFXGE_CAP_ENABLE SFXGE_CAP
66#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
67 IFCAP_JUMBO_MTU | IFCAP_LINKSTATE)
68
69MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver");
70
71
72SYSCTL_NODE(_hw, OID_AUTO, sfxge, CTLFLAG_RD, 0,
73 "SFXGE driver parameters");
74
75#define SFXGE_PARAM_RX_RING SFXGE_PARAM(rx_ring)
76static int sfxge_rx_ring_entries = SFXGE_NDESCS;
77TUNABLE_INT(SFXGE_PARAM_RX_RING, &sfxge_rx_ring_entries);
78SYSCTL_INT(_hw_sfxge, OID_AUTO, rx_ring, CTLFLAG_RDTUN,
79 &sfxge_rx_ring_entries, 0,
80 "Maximum number of descriptors in a receive ring");
81
82#define SFXGE_PARAM_TX_RING SFXGE_PARAM(tx_ring)
83static int sfxge_tx_ring_entries = SFXGE_NDESCS;
84TUNABLE_INT(SFXGE_PARAM_TX_RING, &sfxge_tx_ring_entries);
85SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN,
86 &sfxge_tx_ring_entries, 0,
87 "Maximum number of descriptors in a transmit ring");
88
89
90static void
91sfxge_reset(void *arg, int npending);
92
93static int
94sfxge_start(struct sfxge_softc *sc)
95{
96 int rc;
97
32
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/bus.h>
36#include <sys/rman.h>
37#include <sys/lock.h>
38#include <sys/module.h>
39#include <sys/mutex.h>
40#include <sys/smp.h>
41#include <sys/socket.h>
42#include <sys/taskqueue.h>
43#include <sys/sockio.h>
44#include <sys/sysctl.h>
45#include <sys/syslog.h>
46
47#include <dev/pci/pcireg.h>
48#include <dev/pci/pcivar.h>
49
50#include <net/ethernet.h>
51#include <net/if.h>
52#include <net/if_var.h>
53#include <net/if_media.h>
54#include <net/if_types.h>
55
56#include "common/efx.h"
57
58#include "sfxge.h"
59#include "sfxge_rx.h"
60
61#define SFXGE_CAP (IFCAP_VLAN_MTU | \
62 IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | \
63 IFCAP_JUMBO_MTU | IFCAP_LRO | \
64 IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
65#define SFXGE_CAP_ENABLE SFXGE_CAP
66#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
67 IFCAP_JUMBO_MTU | IFCAP_LINKSTATE)
68
69MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver");
70
71
72SYSCTL_NODE(_hw, OID_AUTO, sfxge, CTLFLAG_RD, 0,
73 "SFXGE driver parameters");
74
75#define SFXGE_PARAM_RX_RING SFXGE_PARAM(rx_ring)
76static int sfxge_rx_ring_entries = SFXGE_NDESCS;
77TUNABLE_INT(SFXGE_PARAM_RX_RING, &sfxge_rx_ring_entries);
78SYSCTL_INT(_hw_sfxge, OID_AUTO, rx_ring, CTLFLAG_RDTUN,
79 &sfxge_rx_ring_entries, 0,
80 "Maximum number of descriptors in a receive ring");
81
82#define SFXGE_PARAM_TX_RING SFXGE_PARAM(tx_ring)
83static int sfxge_tx_ring_entries = SFXGE_NDESCS;
84TUNABLE_INT(SFXGE_PARAM_TX_RING, &sfxge_tx_ring_entries);
85SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN,
86 &sfxge_tx_ring_entries, 0,
87 "Maximum number of descriptors in a transmit ring");
88
89
90static void
91sfxge_reset(void *arg, int npending);
92
93static int
94sfxge_start(struct sfxge_softc *sc)
95{
96 int rc;
97
98 sx_assert(&sc->softc_lock, LA_XLOCKED);
98 SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
99
100 if (sc->init_state == SFXGE_STARTED)
101 return (0);
102
103 if (sc->init_state != SFXGE_REGISTERED) {
104 rc = EINVAL;
105 goto fail;
106 }
107
108 if ((rc = efx_nic_init(sc->enp)) != 0)
109 goto fail;
110
111 /* Start processing interrupts. */
112 if ((rc = sfxge_intr_start(sc)) != 0)
113 goto fail2;
114
115 /* Start processing events. */
116 if ((rc = sfxge_ev_start(sc)) != 0)
117 goto fail3;
118
119 /* Start the receiver side. */
120 if ((rc = sfxge_rx_start(sc)) != 0)
121 goto fail4;
122
123 /* Start the transmitter side. */
124 if ((rc = sfxge_tx_start(sc)) != 0)
125 goto fail5;
126
127 /* Fire up the port. */
128 if ((rc = sfxge_port_start(sc)) != 0)
129 goto fail6;
130
131 sc->init_state = SFXGE_STARTED;
132
133 /* Tell the stack we're running. */
134 sc->ifnet->if_drv_flags |= IFF_DRV_RUNNING;
135 sc->ifnet->if_drv_flags &= ~IFF_DRV_OACTIVE;
136
137 return (0);
138
139fail6:
140 sfxge_tx_stop(sc);
141
142fail5:
143 sfxge_rx_stop(sc);
144
145fail4:
146 sfxge_ev_stop(sc);
147
148fail3:
149 sfxge_intr_stop(sc);
150
151fail2:
152 efx_nic_fini(sc->enp);
153
154fail:
155 device_printf(sc->dev, "sfxge_start: %d\n", rc);
156
157 return (rc);
158}
159
160static void
161sfxge_if_init(void *arg)
162{
163 struct sfxge_softc *sc;
164
165 sc = (struct sfxge_softc *)arg;
166
99
100 if (sc->init_state == SFXGE_STARTED)
101 return (0);
102
103 if (sc->init_state != SFXGE_REGISTERED) {
104 rc = EINVAL;
105 goto fail;
106 }
107
108 if ((rc = efx_nic_init(sc->enp)) != 0)
109 goto fail;
110
111 /* Start processing interrupts. */
112 if ((rc = sfxge_intr_start(sc)) != 0)
113 goto fail2;
114
115 /* Start processing events. */
116 if ((rc = sfxge_ev_start(sc)) != 0)
117 goto fail3;
118
119 /* Start the receiver side. */
120 if ((rc = sfxge_rx_start(sc)) != 0)
121 goto fail4;
122
123 /* Start the transmitter side. */
124 if ((rc = sfxge_tx_start(sc)) != 0)
125 goto fail5;
126
127 /* Fire up the port. */
128 if ((rc = sfxge_port_start(sc)) != 0)
129 goto fail6;
130
131 sc->init_state = SFXGE_STARTED;
132
133 /* Tell the stack we're running. */
134 sc->ifnet->if_drv_flags |= IFF_DRV_RUNNING;
135 sc->ifnet->if_drv_flags &= ~IFF_DRV_OACTIVE;
136
137 return (0);
138
139fail6:
140 sfxge_tx_stop(sc);
141
142fail5:
143 sfxge_rx_stop(sc);
144
145fail4:
146 sfxge_ev_stop(sc);
147
148fail3:
149 sfxge_intr_stop(sc);
150
151fail2:
152 efx_nic_fini(sc->enp);
153
154fail:
155 device_printf(sc->dev, "sfxge_start: %d\n", rc);
156
157 return (rc);
158}
159
160static void
161sfxge_if_init(void *arg)
162{
163 struct sfxge_softc *sc;
164
165 sc = (struct sfxge_softc *)arg;
166
167 sx_xlock(&sc->softc_lock);
167 SFXGE_ADAPTER_LOCK(sc);
168 (void)sfxge_start(sc);
168 (void)sfxge_start(sc);
169 sx_xunlock(&sc->softc_lock);
169 SFXGE_ADAPTER_UNLOCK(sc);
170}
171
172static void
173sfxge_stop(struct sfxge_softc *sc)
174{
170}
171
172static void
173sfxge_stop(struct sfxge_softc *sc)
174{
175 sx_assert(&sc->softc_lock, LA_XLOCKED);
175 SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
176
177 if (sc->init_state != SFXGE_STARTED)
178 return;
179
180 sc->init_state = SFXGE_REGISTERED;
181
182 /* Stop the port. */
183 sfxge_port_stop(sc);
184
185 /* Stop the transmitter. */
186 sfxge_tx_stop(sc);
187
188 /* Stop the receiver. */
189 sfxge_rx_stop(sc);
190
191 /* Stop processing events. */
192 sfxge_ev_stop(sc);
193
194 /* Stop processing interrupts. */
195 sfxge_intr_stop(sc);
196
197 efx_nic_fini(sc->enp);
198
199 sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING;
200}
201
202static int
203sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
204{
205 struct sfxge_softc *sc;
206 struct ifreq *ifr;
207 int error;
208
209 ifr = (struct ifreq *)data;
210 sc = ifp->if_softc;
211 error = 0;
212
213 switch (command) {
214 case SIOCSIFFLAGS:
176
177 if (sc->init_state != SFXGE_STARTED)
178 return;
179
180 sc->init_state = SFXGE_REGISTERED;
181
182 /* Stop the port. */
183 sfxge_port_stop(sc);
184
185 /* Stop the transmitter. */
186 sfxge_tx_stop(sc);
187
188 /* Stop the receiver. */
189 sfxge_rx_stop(sc);
190
191 /* Stop processing events. */
192 sfxge_ev_stop(sc);
193
194 /* Stop processing interrupts. */
195 sfxge_intr_stop(sc);
196
197 efx_nic_fini(sc->enp);
198
199 sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING;
200}
201
202static int
203sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
204{
205 struct sfxge_softc *sc;
206 struct ifreq *ifr;
207 int error;
208
209 ifr = (struct ifreq *)data;
210 sc = ifp->if_softc;
211 error = 0;
212
213 switch (command) {
214 case SIOCSIFFLAGS:
215 sx_xlock(&sc->softc_lock);
215 SFXGE_ADAPTER_LOCK(sc);
216 if (ifp->if_flags & IFF_UP) {
217 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
218 if ((ifp->if_flags ^ sc->if_flags) &
219 (IFF_PROMISC | IFF_ALLMULTI)) {
220 sfxge_mac_filter_set(sc);
221 }
222 } else
223 sfxge_start(sc);
224 } else
225 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
226 sfxge_stop(sc);
227 sc->if_flags = ifp->if_flags;
216 if (ifp->if_flags & IFF_UP) {
217 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
218 if ((ifp->if_flags ^ sc->if_flags) &
219 (IFF_PROMISC | IFF_ALLMULTI)) {
220 sfxge_mac_filter_set(sc);
221 }
222 } else
223 sfxge_start(sc);
224 } else
225 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
226 sfxge_stop(sc);
227 sc->if_flags = ifp->if_flags;
228 sx_xunlock(&sc->softc_lock);
228 SFXGE_ADAPTER_UNLOCK(sc);
229 break;
230 case SIOCSIFMTU:
231 if (ifr->ifr_mtu == ifp->if_mtu) {
232 /* Nothing to do */
233 error = 0;
234 } else if (ifr->ifr_mtu > SFXGE_MAX_MTU) {
235 error = EINVAL;
236 } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
237 ifp->if_mtu = ifr->ifr_mtu;
238 error = 0;
239 } else {
240 /* Restart required */
229 break;
230 case SIOCSIFMTU:
231 if (ifr->ifr_mtu == ifp->if_mtu) {
232 /* Nothing to do */
233 error = 0;
234 } else if (ifr->ifr_mtu > SFXGE_MAX_MTU) {
235 error = EINVAL;
236 } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
237 ifp->if_mtu = ifr->ifr_mtu;
238 error = 0;
239 } else {
240 /* Restart required */
241 sx_xlock(&sc->softc_lock);
241 SFXGE_ADAPTER_LOCK(sc);
242 sfxge_stop(sc);
243 ifp->if_mtu = ifr->ifr_mtu;
244 error = sfxge_start(sc);
242 sfxge_stop(sc);
243 ifp->if_mtu = ifr->ifr_mtu;
244 error = sfxge_start(sc);
245 sx_xunlock(&sc->softc_lock);
245 SFXGE_ADAPTER_UNLOCK(sc);
246 if (error != 0) {
247 ifp->if_flags &= ~IFF_UP;
248 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
249 if_down(ifp);
250 }
251 }
252 break;
253 case SIOCADDMULTI:
254 case SIOCDELMULTI:
255 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
256 sfxge_mac_filter_set(sc);
257 break;
258 case SIOCSIFCAP:
246 if (error != 0) {
247 ifp->if_flags &= ~IFF_UP;
248 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
249 if_down(ifp);
250 }
251 }
252 break;
253 case SIOCADDMULTI:
254 case SIOCDELMULTI:
255 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
256 sfxge_mac_filter_set(sc);
257 break;
258 case SIOCSIFCAP:
259 sx_xlock(&sc->softc_lock);
259 SFXGE_ADAPTER_LOCK(sc);
260
261 /*
262 * The networking core already rejects attempts to
263 * enable capabilities we don't have. We still have
264 * to reject attempts to disable capabilities that we
265 * can't (yet) disable.
266 */
267 if (~ifr->ifr_reqcap & SFXGE_CAP_FIXED) {
268 error = EINVAL;
260
261 /*
262 * The networking core already rejects attempts to
263 * enable capabilities we don't have. We still have
264 * to reject attempts to disable capabilities that we
265 * can't (yet) disable.
266 */
267 if (~ifr->ifr_reqcap & SFXGE_CAP_FIXED) {
268 error = EINVAL;
269 sx_xunlock(&sc->softc_lock);
269 SFXGE_ADAPTER_UNLOCK(sc);
270 break;
271 }
272
273 ifp->if_capenable = ifr->ifr_reqcap;
274 if (ifp->if_capenable & IFCAP_TXCSUM)
275 ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP);
276 else
277 ifp->if_hwassist &= ~(CSUM_IP | CSUM_TCP | CSUM_UDP);
278 if (ifp->if_capenable & IFCAP_TSO)
279 ifp->if_hwassist |= CSUM_TSO;
280 else
281 ifp->if_hwassist &= ~CSUM_TSO;
282
270 break;
271 }
272
273 ifp->if_capenable = ifr->ifr_reqcap;
274 if (ifp->if_capenable & IFCAP_TXCSUM)
275 ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP);
276 else
277 ifp->if_hwassist &= ~(CSUM_IP | CSUM_TCP | CSUM_UDP);
278 if (ifp->if_capenable & IFCAP_TSO)
279 ifp->if_hwassist |= CSUM_TSO;
280 else
281 ifp->if_hwassist &= ~CSUM_TSO;
282
283 sx_xunlock(&sc->softc_lock);
283 SFXGE_ADAPTER_UNLOCK(sc);
284 break;
285 case SIOCSIFMEDIA:
286 case SIOCGIFMEDIA:
287 error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
288 break;
289 default:
290 error = ether_ioctl(ifp, command, data);
291 }
292
293 return (error);
294}
295
296static void
297sfxge_ifnet_fini(struct ifnet *ifp)
298{
299 struct sfxge_softc *sc = ifp->if_softc;
300
284 break;
285 case SIOCSIFMEDIA:
286 case SIOCGIFMEDIA:
287 error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
288 break;
289 default:
290 error = ether_ioctl(ifp, command, data);
291 }
292
293 return (error);
294}
295
296static void
297sfxge_ifnet_fini(struct ifnet *ifp)
298{
299 struct sfxge_softc *sc = ifp->if_softc;
300
301 sx_xlock(&sc->softc_lock);
301 SFXGE_ADAPTER_LOCK(sc);
302 sfxge_stop(sc);
302 sfxge_stop(sc);
303 sx_xunlock(&sc->softc_lock);
303 SFXGE_ADAPTER_UNLOCK(sc);
304
305 ifmedia_removeall(&sc->media);
306 ether_ifdetach(ifp);
307 if_free(ifp);
308}
309
310static int
311sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
312{
313 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
314 device_t dev;
315 int rc;
316
317 dev = sc->dev;
318 sc->ifnet = ifp;
319
320 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
321 ifp->if_init = sfxge_if_init;
322 ifp->if_softc = sc;
323 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
324 ifp->if_ioctl = sfxge_if_ioctl;
325
326 ifp->if_capabilities = SFXGE_CAP;
327 ifp->if_capenable = SFXGE_CAP_ENABLE;
328 ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO;
329
330 ether_ifattach(ifp, encp->enc_mac_addr);
331
332#ifdef SFXGE_HAVE_MQ
333 ifp->if_transmit = sfxge_if_transmit;
334 ifp->if_qflush = sfxge_if_qflush;
335#else
336 ifp->if_start = sfxge_if_start;
337 IFQ_SET_MAXLEN(&ifp->if_snd, sc->txq_entries - 1);
338 ifp->if_snd.ifq_drv_maxlen = sc->txq_entries - 1;
339 IFQ_SET_READY(&ifp->if_snd);
340
341 mtx_init(&sc->tx_lock, "txq", NULL, MTX_DEF);
342#endif
343
344 if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
345 goto fail;
346
347 return (0);
348
349fail:
350 ether_ifdetach(sc->ifnet);
351 return (rc);
352}
353
354void
355sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n, uint32_t *idp)
356{
357 KASSERT(sc->buffer_table_next + n <=
358 efx_nic_cfg_get(sc->enp)->enc_buftbl_limit,
359 ("buffer table full"));
360
361 *idp = sc->buffer_table_next;
362 sc->buffer_table_next += n;
363}
364
365static int
366sfxge_bar_init(struct sfxge_softc *sc)
367{
368 efsys_bar_t *esbp = &sc->bar;
369
370 esbp->esb_rid = PCIR_BAR(EFX_MEM_BAR);
371 if ((esbp->esb_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY,
372 &esbp->esb_rid, RF_ACTIVE)) == NULL) {
373 device_printf(sc->dev, "Cannot allocate BAR region %d\n",
374 EFX_MEM_BAR);
375 return (ENXIO);
376 }
377 esbp->esb_tag = rman_get_bustag(esbp->esb_res);
378 esbp->esb_handle = rman_get_bushandle(esbp->esb_res);
304
305 ifmedia_removeall(&sc->media);
306 ether_ifdetach(ifp);
307 if_free(ifp);
308}
309
310static int
311sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
312{
313 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
314 device_t dev;
315 int rc;
316
317 dev = sc->dev;
318 sc->ifnet = ifp;
319
320 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
321 ifp->if_init = sfxge_if_init;
322 ifp->if_softc = sc;
323 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
324 ifp->if_ioctl = sfxge_if_ioctl;
325
326 ifp->if_capabilities = SFXGE_CAP;
327 ifp->if_capenable = SFXGE_CAP_ENABLE;
328 ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO;
329
330 ether_ifattach(ifp, encp->enc_mac_addr);
331
332#ifdef SFXGE_HAVE_MQ
333 ifp->if_transmit = sfxge_if_transmit;
334 ifp->if_qflush = sfxge_if_qflush;
335#else
336 ifp->if_start = sfxge_if_start;
337 IFQ_SET_MAXLEN(&ifp->if_snd, sc->txq_entries - 1);
338 ifp->if_snd.ifq_drv_maxlen = sc->txq_entries - 1;
339 IFQ_SET_READY(&ifp->if_snd);
340
341 mtx_init(&sc->tx_lock, "txq", NULL, MTX_DEF);
342#endif
343
344 if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
345 goto fail;
346
347 return (0);
348
349fail:
350 ether_ifdetach(sc->ifnet);
351 return (rc);
352}
353
354void
355sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n, uint32_t *idp)
356{
357 KASSERT(sc->buffer_table_next + n <=
358 efx_nic_cfg_get(sc->enp)->enc_buftbl_limit,
359 ("buffer table full"));
360
361 *idp = sc->buffer_table_next;
362 sc->buffer_table_next += n;
363}
364
365static int
366sfxge_bar_init(struct sfxge_softc *sc)
367{
368 efsys_bar_t *esbp = &sc->bar;
369
370 esbp->esb_rid = PCIR_BAR(EFX_MEM_BAR);
371 if ((esbp->esb_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY,
372 &esbp->esb_rid, RF_ACTIVE)) == NULL) {
373 device_printf(sc->dev, "Cannot allocate BAR region %d\n",
374 EFX_MEM_BAR);
375 return (ENXIO);
376 }
377 esbp->esb_tag = rman_get_bustag(esbp->esb_res);
378 esbp->esb_handle = rman_get_bushandle(esbp->esb_res);
379 mtx_init(&esbp->esb_lock, "sfxge_efsys_bar", NULL, MTX_DEF);
379 SFXGE_BAR_LOCK_INIT(esbp, "sfxge_efsys_bar");
380
381 return (0);
382}
383
384static void
385sfxge_bar_fini(struct sfxge_softc *sc)
386{
387 efsys_bar_t *esbp = &sc->bar;
388
389 bus_release_resource(sc->dev, SYS_RES_MEMORY, esbp->esb_rid,
390 esbp->esb_res);
380
381 return (0);
382}
383
384static void
385sfxge_bar_fini(struct sfxge_softc *sc)
386{
387 efsys_bar_t *esbp = &sc->bar;
388
389 bus_release_resource(sc->dev, SYS_RES_MEMORY, esbp->esb_rid,
390 esbp->esb_res);
391 mtx_destroy(&esbp->esb_lock);
391 SFXGE_BAR_LOCK_DESTROY(esbp);
392}
393
394static int
395sfxge_create(struct sfxge_softc *sc)
396{
397 device_t dev;
398 efx_nic_t *enp;
399 int error;
400 char rss_param_name[sizeof(SFXGE_PARAM(%d.max_rss_channels))];
401
402 dev = sc->dev;
403
392}
393
394static int
395sfxge_create(struct sfxge_softc *sc)
396{
397 device_t dev;
398 efx_nic_t *enp;
399 int error;
400 char rss_param_name[sizeof(SFXGE_PARAM(%d.max_rss_channels))];
401
402 dev = sc->dev;
403
404 sx_init(&sc->softc_lock, "sfxge_softc");
404 SFXGE_ADAPTER_LOCK_INIT(sc, "sfxge_softc");
405
406 sc->max_rss_channels = 0;
407 snprintf(rss_param_name, sizeof(rss_param_name),
408 SFXGE_PARAM(%d.max_rss_channels),
409 (int)device_get_unit(dev));
410 TUNABLE_INT_FETCH(rss_param_name, &sc->max_rss_channels);
411
412 sc->stats_node = SYSCTL_ADD_NODE(
413 device_get_sysctl_ctx(dev),
414 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
415 OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics");
416 if (sc->stats_node == NULL) {
417 error = ENOMEM;
418 goto fail;
419 }
420
421 TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc);
422
423 (void) pci_enable_busmaster(dev);
424
425 /* Initialize DMA mappings. */
426 if ((error = sfxge_dma_init(sc)) != 0)
427 goto fail;
428
429 /* Map the device registers. */
430 if ((error = sfxge_bar_init(sc)) != 0)
431 goto fail;
432
433 error = efx_family(pci_get_vendor(dev), pci_get_device(dev),
434 &sc->family);
435 KASSERT(error == 0, ("Family should be filtered by sfxge_probe()"));
436
437 /* Create the common code nic object. */
438 mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF);
439 if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc,
440 &sc->bar, &sc->enp_lock, &enp)) != 0)
441 goto fail3;
442 sc->enp = enp;
443
444 if (!ISP2(sfxge_rx_ring_entries) ||
445 !(sfxge_rx_ring_entries & EFX_RXQ_NDESCS_MASK)) {
446 log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
447 SFXGE_PARAM_RX_RING, sfxge_rx_ring_entries,
448 EFX_RXQ_MINNDESCS, EFX_RXQ_MAXNDESCS);
449 error = EINVAL;
450 goto fail_rx_ring_entries;
451 }
452 sc->rxq_entries = sfxge_rx_ring_entries;
453
454 if (!ISP2(sfxge_tx_ring_entries) ||
455 !(sfxge_tx_ring_entries & EFX_TXQ_NDESCS_MASK)) {
456 log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
457 SFXGE_PARAM_TX_RING, sfxge_tx_ring_entries,
458 EFX_TXQ_MINNDESCS, EFX_TXQ_MAXNDESCS);
459 error = EINVAL;
460 goto fail_tx_ring_entries;
461 }
462 sc->txq_entries = sfxge_tx_ring_entries;
463
464 /* Initialize MCDI to talk to the microcontroller. */
465 if ((error = sfxge_mcdi_init(sc)) != 0)
466 goto fail4;
467
468 /* Probe the NIC and build the configuration data area. */
469 if ((error = efx_nic_probe(enp)) != 0)
470 goto fail5;
471
472 /* Initialize the NVRAM. */
473 if ((error = efx_nvram_init(enp)) != 0)
474 goto fail6;
475
476 /* Initialize the VPD. */
477 if ((error = efx_vpd_init(enp)) != 0)
478 goto fail7;
479
480 /* Reset the NIC. */
481 if ((error = efx_nic_reset(enp)) != 0)
482 goto fail8;
483
484 /* Initialize buffer table allocation. */
485 sc->buffer_table_next = 0;
486
487 /* Set up interrupts. */
488 if ((error = sfxge_intr_init(sc)) != 0)
489 goto fail8;
490
491 /* Initialize event processing state. */
492 if ((error = sfxge_ev_init(sc)) != 0)
493 goto fail11;
494
495 /* Initialize receive state. */
496 if ((error = sfxge_rx_init(sc)) != 0)
497 goto fail12;
498
499 /* Initialize transmit state. */
500 if ((error = sfxge_tx_init(sc)) != 0)
501 goto fail13;
502
503 /* Initialize port state. */
504 if ((error = sfxge_port_init(sc)) != 0)
505 goto fail14;
506
507 sc->init_state = SFXGE_INITIALIZED;
508
509 return (0);
510
511fail14:
512 sfxge_tx_fini(sc);
513
514fail13:
515 sfxge_rx_fini(sc);
516
517fail12:
518 sfxge_ev_fini(sc);
519
520fail11:
521 sfxge_intr_fini(sc);
522
523fail8:
524 efx_vpd_fini(enp);
525
526fail7:
527 efx_nvram_fini(enp);
528
529fail6:
530 efx_nic_unprobe(enp);
531
532fail5:
533 sfxge_mcdi_fini(sc);
534
535fail4:
536fail_tx_ring_entries:
537fail_rx_ring_entries:
538 sc->enp = NULL;
539 efx_nic_destroy(enp);
540 mtx_destroy(&sc->enp_lock);
541
542fail3:
543 sfxge_bar_fini(sc);
544 (void) pci_disable_busmaster(sc->dev);
545
546fail:
547 sc->dev = NULL;
405
406 sc->max_rss_channels = 0;
407 snprintf(rss_param_name, sizeof(rss_param_name),
408 SFXGE_PARAM(%d.max_rss_channels),
409 (int)device_get_unit(dev));
410 TUNABLE_INT_FETCH(rss_param_name, &sc->max_rss_channels);
411
412 sc->stats_node = SYSCTL_ADD_NODE(
413 device_get_sysctl_ctx(dev),
414 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
415 OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics");
416 if (sc->stats_node == NULL) {
417 error = ENOMEM;
418 goto fail;
419 }
420
421 TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc);
422
423 (void) pci_enable_busmaster(dev);
424
425 /* Initialize DMA mappings. */
426 if ((error = sfxge_dma_init(sc)) != 0)
427 goto fail;
428
429 /* Map the device registers. */
430 if ((error = sfxge_bar_init(sc)) != 0)
431 goto fail;
432
433 error = efx_family(pci_get_vendor(dev), pci_get_device(dev),
434 &sc->family);
435 KASSERT(error == 0, ("Family should be filtered by sfxge_probe()"));
436
437 /* Create the common code nic object. */
438 mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF);
439 if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc,
440 &sc->bar, &sc->enp_lock, &enp)) != 0)
441 goto fail3;
442 sc->enp = enp;
443
444 if (!ISP2(sfxge_rx_ring_entries) ||
445 !(sfxge_rx_ring_entries & EFX_RXQ_NDESCS_MASK)) {
446 log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
447 SFXGE_PARAM_RX_RING, sfxge_rx_ring_entries,
448 EFX_RXQ_MINNDESCS, EFX_RXQ_MAXNDESCS);
449 error = EINVAL;
450 goto fail_rx_ring_entries;
451 }
452 sc->rxq_entries = sfxge_rx_ring_entries;
453
454 if (!ISP2(sfxge_tx_ring_entries) ||
455 !(sfxge_tx_ring_entries & EFX_TXQ_NDESCS_MASK)) {
456 log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
457 SFXGE_PARAM_TX_RING, sfxge_tx_ring_entries,
458 EFX_TXQ_MINNDESCS, EFX_TXQ_MAXNDESCS);
459 error = EINVAL;
460 goto fail_tx_ring_entries;
461 }
462 sc->txq_entries = sfxge_tx_ring_entries;
463
464 /* Initialize MCDI to talk to the microcontroller. */
465 if ((error = sfxge_mcdi_init(sc)) != 0)
466 goto fail4;
467
468 /* Probe the NIC and build the configuration data area. */
469 if ((error = efx_nic_probe(enp)) != 0)
470 goto fail5;
471
472 /* Initialize the NVRAM. */
473 if ((error = efx_nvram_init(enp)) != 0)
474 goto fail6;
475
476 /* Initialize the VPD. */
477 if ((error = efx_vpd_init(enp)) != 0)
478 goto fail7;
479
480 /* Reset the NIC. */
481 if ((error = efx_nic_reset(enp)) != 0)
482 goto fail8;
483
484 /* Initialize buffer table allocation. */
485 sc->buffer_table_next = 0;
486
487 /* Set up interrupts. */
488 if ((error = sfxge_intr_init(sc)) != 0)
489 goto fail8;
490
491 /* Initialize event processing state. */
492 if ((error = sfxge_ev_init(sc)) != 0)
493 goto fail11;
494
495 /* Initialize receive state. */
496 if ((error = sfxge_rx_init(sc)) != 0)
497 goto fail12;
498
499 /* Initialize transmit state. */
500 if ((error = sfxge_tx_init(sc)) != 0)
501 goto fail13;
502
503 /* Initialize port state. */
504 if ((error = sfxge_port_init(sc)) != 0)
505 goto fail14;
506
507 sc->init_state = SFXGE_INITIALIZED;
508
509 return (0);
510
511fail14:
512 sfxge_tx_fini(sc);
513
514fail13:
515 sfxge_rx_fini(sc);
516
517fail12:
518 sfxge_ev_fini(sc);
519
520fail11:
521 sfxge_intr_fini(sc);
522
523fail8:
524 efx_vpd_fini(enp);
525
526fail7:
527 efx_nvram_fini(enp);
528
529fail6:
530 efx_nic_unprobe(enp);
531
532fail5:
533 sfxge_mcdi_fini(sc);
534
535fail4:
536fail_tx_ring_entries:
537fail_rx_ring_entries:
538 sc->enp = NULL;
539 efx_nic_destroy(enp);
540 mtx_destroy(&sc->enp_lock);
541
542fail3:
543 sfxge_bar_fini(sc);
544 (void) pci_disable_busmaster(sc->dev);
545
546fail:
547 sc->dev = NULL;
548 sx_destroy(&sc->softc_lock);
548 SFXGE_ADAPTER_LOCK_DESTROY(sc);
549 return (error);
550}
551
552static void
553sfxge_destroy(struct sfxge_softc *sc)
554{
555 efx_nic_t *enp;
556
557 /* Clean up port state. */
558 sfxge_port_fini(sc);
559
560 /* Clean up transmit state. */
561 sfxge_tx_fini(sc);
562
563 /* Clean up receive state. */
564 sfxge_rx_fini(sc);
565
566 /* Clean up event processing state. */
567 sfxge_ev_fini(sc);
568
569 /* Clean up interrupts. */
570 sfxge_intr_fini(sc);
571
572 /* Tear down common code subsystems. */
573 efx_nic_reset(sc->enp);
574 efx_vpd_fini(sc->enp);
575 efx_nvram_fini(sc->enp);
576 efx_nic_unprobe(sc->enp);
577
578 /* Tear down MCDI. */
579 sfxge_mcdi_fini(sc);
580
581 /* Destroy common code context. */
582 enp = sc->enp;
583 sc->enp = NULL;
584 efx_nic_destroy(enp);
585
586 /* Free DMA memory. */
587 sfxge_dma_fini(sc);
588
589 /* Free mapped BARs. */
590 sfxge_bar_fini(sc);
591
592 (void) pci_disable_busmaster(sc->dev);
593
594 taskqueue_drain(taskqueue_thread, &sc->task_reset);
595
596 /* Destroy the softc lock. */
549 return (error);
550}
551
552static void
553sfxge_destroy(struct sfxge_softc *sc)
554{
555 efx_nic_t *enp;
556
557 /* Clean up port state. */
558 sfxge_port_fini(sc);
559
560 /* Clean up transmit state. */
561 sfxge_tx_fini(sc);
562
563 /* Clean up receive state. */
564 sfxge_rx_fini(sc);
565
566 /* Clean up event processing state. */
567 sfxge_ev_fini(sc);
568
569 /* Clean up interrupts. */
570 sfxge_intr_fini(sc);
571
572 /* Tear down common code subsystems. */
573 efx_nic_reset(sc->enp);
574 efx_vpd_fini(sc->enp);
575 efx_nvram_fini(sc->enp);
576 efx_nic_unprobe(sc->enp);
577
578 /* Tear down MCDI. */
579 sfxge_mcdi_fini(sc);
580
581 /* Destroy common code context. */
582 enp = sc->enp;
583 sc->enp = NULL;
584 efx_nic_destroy(enp);
585
586 /* Free DMA memory. */
587 sfxge_dma_fini(sc);
588
589 /* Free mapped BARs. */
590 sfxge_bar_fini(sc);
591
592 (void) pci_disable_busmaster(sc->dev);
593
594 taskqueue_drain(taskqueue_thread, &sc->task_reset);
595
596 /* Destroy the softc lock. */
597 sx_destroy(&sc->softc_lock);
597 SFXGE_ADAPTER_LOCK_DESTROY(sc);
598}
599
600static int
601sfxge_vpd_handler(SYSCTL_HANDLER_ARGS)
602{
603 struct sfxge_softc *sc = arg1;
604 efx_vpd_value_t value;
605 int rc;
606
607 value.evv_tag = arg2 >> 16;
608 value.evv_keyword = arg2 & 0xffff;
609 if ((rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value))
610 != 0)
611 return (rc);
612
613 return (SYSCTL_OUT(req, value.evv_value, value.evv_length));
614}
615
616static void
617sfxge_vpd_try_add(struct sfxge_softc *sc, struct sysctl_oid_list *list,
618 efx_vpd_tag_t tag, const char *keyword)
619{
620 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
621 efx_vpd_value_t value;
622
623 /* Check whether VPD tag/keyword is present */
624 value.evv_tag = tag;
625 value.evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]);
626 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) != 0)
627 return;
628
629 SYSCTL_ADD_PROC(
630 ctx, list, OID_AUTO, keyword, CTLTYPE_STRING|CTLFLAG_RD,
631 sc, tag << 16 | EFX_VPD_KEYWORD(keyword[0], keyword[1]),
632 sfxge_vpd_handler, "A", "");
633}
634
635static int
636sfxge_vpd_init(struct sfxge_softc *sc)
637{
638 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
639 struct sysctl_oid *vpd_node;
640 struct sysctl_oid_list *vpd_list;
641 char keyword[3];
642 efx_vpd_value_t value;
643 int rc;
644
645 if ((rc = efx_vpd_size(sc->enp, &sc->vpd_size)) != 0)
646 goto fail;
647 sc->vpd_data = malloc(sc->vpd_size, M_SFXGE, M_WAITOK);
648 if ((rc = efx_vpd_read(sc->enp, sc->vpd_data, sc->vpd_size)) != 0)
649 goto fail2;
650
651 /* Copy ID (product name) into device description, and log it. */
652 value.evv_tag = EFX_VPD_ID;
653 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) == 0) {
654 value.evv_value[value.evv_length] = 0;
655 device_set_desc_copy(sc->dev, value.evv_value);
656 device_printf(sc->dev, "%s\n", value.evv_value);
657 }
658
659 vpd_node = SYSCTL_ADD_NODE(
660 ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
661 OID_AUTO, "vpd", CTLFLAG_RD, NULL, "Vital Product Data");
662 vpd_list = SYSCTL_CHILDREN(vpd_node);
663
664 /* Add sysctls for all expected and any vendor-defined keywords. */
665 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "PN");
666 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "EC");
667 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "SN");
668 keyword[0] = 'V';
669 keyword[2] = 0;
670 for (keyword[1] = '0'; keyword[1] <= '9'; keyword[1]++)
671 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword);
672 for (keyword[1] = 'A'; keyword[1] <= 'Z'; keyword[1]++)
673 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword);
674
675 return (0);
676
677fail2:
678 free(sc->vpd_data, M_SFXGE);
679fail:
680 return (rc);
681}
682
683static void
684sfxge_vpd_fini(struct sfxge_softc *sc)
685{
686 free(sc->vpd_data, M_SFXGE);
687}
688
689static void
690sfxge_reset(void *arg, int npending)
691{
692 struct sfxge_softc *sc;
693 int rc;
694
695 (void)npending;
696
697 sc = (struct sfxge_softc *)arg;
698
598}
599
600static int
601sfxge_vpd_handler(SYSCTL_HANDLER_ARGS)
602{
603 struct sfxge_softc *sc = arg1;
604 efx_vpd_value_t value;
605 int rc;
606
607 value.evv_tag = arg2 >> 16;
608 value.evv_keyword = arg2 & 0xffff;
609 if ((rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value))
610 != 0)
611 return (rc);
612
613 return (SYSCTL_OUT(req, value.evv_value, value.evv_length));
614}
615
616static void
617sfxge_vpd_try_add(struct sfxge_softc *sc, struct sysctl_oid_list *list,
618 efx_vpd_tag_t tag, const char *keyword)
619{
620 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
621 efx_vpd_value_t value;
622
623 /* Check whether VPD tag/keyword is present */
624 value.evv_tag = tag;
625 value.evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]);
626 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) != 0)
627 return;
628
629 SYSCTL_ADD_PROC(
630 ctx, list, OID_AUTO, keyword, CTLTYPE_STRING|CTLFLAG_RD,
631 sc, tag << 16 | EFX_VPD_KEYWORD(keyword[0], keyword[1]),
632 sfxge_vpd_handler, "A", "");
633}
634
635static int
636sfxge_vpd_init(struct sfxge_softc *sc)
637{
638 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
639 struct sysctl_oid *vpd_node;
640 struct sysctl_oid_list *vpd_list;
641 char keyword[3];
642 efx_vpd_value_t value;
643 int rc;
644
645 if ((rc = efx_vpd_size(sc->enp, &sc->vpd_size)) != 0)
646 goto fail;
647 sc->vpd_data = malloc(sc->vpd_size, M_SFXGE, M_WAITOK);
648 if ((rc = efx_vpd_read(sc->enp, sc->vpd_data, sc->vpd_size)) != 0)
649 goto fail2;
650
651 /* Copy ID (product name) into device description, and log it. */
652 value.evv_tag = EFX_VPD_ID;
653 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) == 0) {
654 value.evv_value[value.evv_length] = 0;
655 device_set_desc_copy(sc->dev, value.evv_value);
656 device_printf(sc->dev, "%s\n", value.evv_value);
657 }
658
659 vpd_node = SYSCTL_ADD_NODE(
660 ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
661 OID_AUTO, "vpd", CTLFLAG_RD, NULL, "Vital Product Data");
662 vpd_list = SYSCTL_CHILDREN(vpd_node);
663
664 /* Add sysctls for all expected and any vendor-defined keywords. */
665 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "PN");
666 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "EC");
667 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "SN");
668 keyword[0] = 'V';
669 keyword[2] = 0;
670 for (keyword[1] = '0'; keyword[1] <= '9'; keyword[1]++)
671 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword);
672 for (keyword[1] = 'A'; keyword[1] <= 'Z'; keyword[1]++)
673 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword);
674
675 return (0);
676
677fail2:
678 free(sc->vpd_data, M_SFXGE);
679fail:
680 return (rc);
681}
682
683static void
684sfxge_vpd_fini(struct sfxge_softc *sc)
685{
686 free(sc->vpd_data, M_SFXGE);
687}
688
689static void
690sfxge_reset(void *arg, int npending)
691{
692 struct sfxge_softc *sc;
693 int rc;
694
695 (void)npending;
696
697 sc = (struct sfxge_softc *)arg;
698
699 sx_xlock(&sc->softc_lock);
699 SFXGE_ADAPTER_LOCK(sc);
700
701 if (sc->init_state != SFXGE_STARTED)
702 goto done;
703
704 sfxge_stop(sc);
705 efx_nic_reset(sc->enp);
706 if ((rc = sfxge_start(sc)) != 0)
707 device_printf(sc->dev,
708 "reset failed (%d); interface is now stopped\n",
709 rc);
710
711done:
700
701 if (sc->init_state != SFXGE_STARTED)
702 goto done;
703
704 sfxge_stop(sc);
705 efx_nic_reset(sc->enp);
706 if ((rc = sfxge_start(sc)) != 0)
707 device_printf(sc->dev,
708 "reset failed (%d); interface is now stopped\n",
709 rc);
710
711done:
712 sx_xunlock(&sc->softc_lock);
712 SFXGE_ADAPTER_UNLOCK(sc);
713}
714
715void
716sfxge_schedule_reset(struct sfxge_softc *sc)
717{
718 taskqueue_enqueue(taskqueue_thread, &sc->task_reset);
719}
720
721static int
722sfxge_attach(device_t dev)
723{
724 struct sfxge_softc *sc;
725 struct ifnet *ifp;
726 int error;
727
728 sc = device_get_softc(dev);
729 sc->dev = dev;
730
731 /* Allocate ifnet. */
732 ifp = if_alloc(IFT_ETHER);
733 if (ifp == NULL) {
734 device_printf(dev, "Couldn't allocate ifnet\n");
735 error = ENOMEM;
736 goto fail;
737 }
738 sc->ifnet = ifp;
739
740 /* Initialize hardware. */
741 if ((error = sfxge_create(sc)) != 0)
742 goto fail2;
743
744 /* Create the ifnet for the port. */
745 if ((error = sfxge_ifnet_init(ifp, sc)) != 0)
746 goto fail3;
747
748 if ((error = sfxge_vpd_init(sc)) != 0)
749 goto fail4;
750
751 sc->init_state = SFXGE_REGISTERED;
752
753 return (0);
754
755fail4:
756 sfxge_ifnet_fini(ifp);
757fail3:
758 sfxge_destroy(sc);
759
760fail2:
761 if_free(sc->ifnet);
762
763fail:
764 return (error);
765}
766
767static int
768sfxge_detach(device_t dev)
769{
770 struct sfxge_softc *sc;
771
772 sc = device_get_softc(dev);
773
774 sfxge_vpd_fini(sc);
775
776 /* Destroy the ifnet. */
777 sfxge_ifnet_fini(sc->ifnet);
778
779 /* Tear down hardware. */
780 sfxge_destroy(sc);
781
782 return (0);
783}
784
785static int
786sfxge_probe(device_t dev)
787{
788 uint16_t pci_vendor_id;
789 uint16_t pci_device_id;
790 efx_family_t family;
791 int rc;
792
793 pci_vendor_id = pci_get_vendor(dev);
794 pci_device_id = pci_get_device(dev);
795
796 rc = efx_family(pci_vendor_id, pci_device_id, &family);
797 if (rc != 0)
798 return (ENXIO);
799
800 KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family"));
801 device_set_desc(dev, "Solarflare SFC9000 family");
802 return (0);
803}
804
805static device_method_t sfxge_methods[] = {
806 DEVMETHOD(device_probe, sfxge_probe),
807 DEVMETHOD(device_attach, sfxge_attach),
808 DEVMETHOD(device_detach, sfxge_detach),
809
810 DEVMETHOD_END
811};
812
813static devclass_t sfxge_devclass;
814
815static driver_t sfxge_driver = {
816 "sfxge",
817 sfxge_methods,
818 sizeof(struct sfxge_softc)
819};
820
821DRIVER_MODULE(sfxge, pci, sfxge_driver, sfxge_devclass, 0, 0);
713}
714
715void
716sfxge_schedule_reset(struct sfxge_softc *sc)
717{
718 taskqueue_enqueue(taskqueue_thread, &sc->task_reset);
719}
720
721static int
722sfxge_attach(device_t dev)
723{
724 struct sfxge_softc *sc;
725 struct ifnet *ifp;
726 int error;
727
728 sc = device_get_softc(dev);
729 sc->dev = dev;
730
731 /* Allocate ifnet. */
732 ifp = if_alloc(IFT_ETHER);
733 if (ifp == NULL) {
734 device_printf(dev, "Couldn't allocate ifnet\n");
735 error = ENOMEM;
736 goto fail;
737 }
738 sc->ifnet = ifp;
739
740 /* Initialize hardware. */
741 if ((error = sfxge_create(sc)) != 0)
742 goto fail2;
743
744 /* Create the ifnet for the port. */
745 if ((error = sfxge_ifnet_init(ifp, sc)) != 0)
746 goto fail3;
747
748 if ((error = sfxge_vpd_init(sc)) != 0)
749 goto fail4;
750
751 sc->init_state = SFXGE_REGISTERED;
752
753 return (0);
754
755fail4:
756 sfxge_ifnet_fini(ifp);
757fail3:
758 sfxge_destroy(sc);
759
760fail2:
761 if_free(sc->ifnet);
762
763fail:
764 return (error);
765}
766
767static int
768sfxge_detach(device_t dev)
769{
770 struct sfxge_softc *sc;
771
772 sc = device_get_softc(dev);
773
774 sfxge_vpd_fini(sc);
775
776 /* Destroy the ifnet. */
777 sfxge_ifnet_fini(sc->ifnet);
778
779 /* Tear down hardware. */
780 sfxge_destroy(sc);
781
782 return (0);
783}
784
785static int
786sfxge_probe(device_t dev)
787{
788 uint16_t pci_vendor_id;
789 uint16_t pci_device_id;
790 efx_family_t family;
791 int rc;
792
793 pci_vendor_id = pci_get_vendor(dev);
794 pci_device_id = pci_get_device(dev);
795
796 rc = efx_family(pci_vendor_id, pci_device_id, &family);
797 if (rc != 0)
798 return (ENXIO);
799
800 KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family"));
801 device_set_desc(dev, "Solarflare SFC9000 family");
802 return (0);
803}
804
805static device_method_t sfxge_methods[] = {
806 DEVMETHOD(device_probe, sfxge_probe),
807 DEVMETHOD(device_attach, sfxge_attach),
808 DEVMETHOD(device_detach, sfxge_detach),
809
810 DEVMETHOD_END
811};
812
813static devclass_t sfxge_devclass;
814
815static driver_t sfxge_driver = {
816 "sfxge",
817 sfxge_methods,
818 sizeof(struct sfxge_softc)
819};
820
821DRIVER_MODULE(sfxge, pci, sfxge_driver, sfxge_devclass, 0, 0);