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

--- 14 unchanged lines hidden (view full) ---

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

--- 14 unchanged lines hidden (view full) ---

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>

--- 50 unchanged lines hidden (view full) ---

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>

--- 50 unchanged lines hidden (view full) ---

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 }

--- 52 unchanged lines hidden (view full) ---

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 }

--- 52 unchanged lines hidden (view full) ---

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);

--- 23 unchanged lines hidden (view full) ---

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);

--- 23 unchanged lines hidden (view full) ---

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)

--- 59 unchanged lines hidden (view full) ---

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)

--- 59 unchanged lines hidden (view full) ---

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(

--- 127 unchanged lines hidden (view full) ---

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(

--- 127 unchanged lines hidden (view full) ---

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

--- 32 unchanged lines hidden (view full) ---

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

--- 32 unchanged lines hidden (view full) ---

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;

--- 85 unchanged lines hidden (view full) ---

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;

--- 85 unchanged lines hidden (view full) ---

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

--- 101 unchanged lines hidden ---
713}
714
715void
716sfxge_schedule_reset(struct sfxge_softc *sc)
717{
718 taskqueue_enqueue(taskqueue_thread, &sc->task_reset);
719}
720

--- 101 unchanged lines hidden ---