1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010-2016 Solarflare Communications Inc.
5 * All rights reserved.
6 *
7 * This software was developed in part by Philip Paeps under contract for
8 * Solarflare Communications, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright notice,
14 *    this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 *    this list of conditions and the following disclaimer in the documentation
17 *    and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * The views and conclusions contained in the software and documentation are
32 * those of the authors and should not be interpreted as representing official
33 * policies, either expressed or implied, of the FreeBSD Project.
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD$");
38
39#include <sys/types.h>
40#include <sys/limits.h>
41#include <net/ethernet.h>
42#include <net/if_dl.h>
43
44#include "common/efx.h"
45
46#include "sfxge.h"
47
48#define	SFXGE_PARAM_STATS_UPDATE_PERIOD_MS \
49	SFXGE_PARAM(stats_update_period_ms)
50static int sfxge_stats_update_period_ms = SFXGE_STATS_UPDATE_PERIOD_MS;
51TUNABLE_INT(SFXGE_PARAM_STATS_UPDATE_PERIOD_MS,
52	    &sfxge_stats_update_period_ms);
53SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period_ms, CTLFLAG_RDTUN,
54	   &sfxge_stats_update_period_ms, 0,
55	   "netstat interface statistics update period in milliseconds");
56
57static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *);
58
59static int
60sfxge_mac_stat_update(struct sfxge_softc *sc)
61{
62	struct sfxge_port *port = &sc->port;
63	efsys_mem_t *esmp = &(port->mac_stats.dma_buf);
64	clock_t now;
65	unsigned int min_ticks;
66	unsigned int count;
67	int rc;
68
69	SFXGE_PORT_LOCK_ASSERT_OWNED(port);
70
71	if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) {
72		rc = 0;
73		goto out;
74	}
75
76	min_ticks = (unsigned int)hz * port->stats_update_period_ms / 1000;
77
78	now = ticks;
79	if ((unsigned int)(now - port->mac_stats.update_time) < min_ticks) {
80		rc = 0;
81		goto out;
82	}
83
84	port->mac_stats.update_time = now;
85
86	/* If we're unlucky enough to read statistics wduring the DMA, wait
87	 * up to 10ms for it to finish (typically takes <500us) */
88	for (count = 0; count < 100; ++count) {
89		EFSYS_PROBE1(wait, unsigned int, count);
90
91		/* Try to update the cached counters */
92		if ((rc = efx_mac_stats_update(sc->enp, esmp,
93		    port->mac_stats.decode_buf, NULL)) != EAGAIN)
94			goto out;
95
96		DELAY(100);
97	}
98
99	rc = ETIMEDOUT;
100out:
101	return (rc);
102}
103
104uint64_t
105sfxge_get_counter(struct ifnet *ifp, ift_counter c)
106{
107	struct sfxge_softc *sc = ifp->if_softc;
108	uint64_t *mac_stats;
109	uint64_t val;
110
111	SFXGE_PORT_LOCK(&sc->port);
112
113	/* Ignore error and use old values */
114	(void)sfxge_mac_stat_update(sc);
115
116	mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf;
117
118	switch (c) {
119	case IFCOUNTER_IPACKETS:
120		val = mac_stats[EFX_MAC_RX_PKTS];
121		break;
122	case IFCOUNTER_IERRORS:
123		val = mac_stats[EFX_MAC_RX_ERRORS];
124		break;
125	case IFCOUNTER_OPACKETS:
126		val = mac_stats[EFX_MAC_TX_PKTS];
127		break;
128	case IFCOUNTER_OERRORS:
129		val = mac_stats[EFX_MAC_TX_ERRORS];
130		break;
131	case IFCOUNTER_COLLISIONS:
132		val = mac_stats[EFX_MAC_TX_SGL_COL_PKTS] +
133		      mac_stats[EFX_MAC_TX_MULT_COL_PKTS] +
134		      mac_stats[EFX_MAC_TX_EX_COL_PKTS] +
135		      mac_stats[EFX_MAC_TX_LATE_COL_PKTS];
136		break;
137	case IFCOUNTER_IBYTES:
138		val = mac_stats[EFX_MAC_RX_OCTETS];
139		break;
140	case IFCOUNTER_OBYTES:
141		val = mac_stats[EFX_MAC_TX_OCTETS];
142		break;
143	case IFCOUNTER_OMCASTS:
144		val = mac_stats[EFX_MAC_TX_MULTICST_PKTS] +
145		      mac_stats[EFX_MAC_TX_BRDCST_PKTS];
146		break;
147	case IFCOUNTER_OQDROPS:
148		SFXGE_PORT_UNLOCK(&sc->port);
149		return (sfxge_tx_get_drops(sc));
150	case IFCOUNTER_IMCASTS:
151		/* if_imcasts is maintained in net/if_ethersubr.c */
152	case IFCOUNTER_IQDROPS:
153		/* if_iqdrops is maintained in net/if_ethersubr.c */
154	case IFCOUNTER_NOPROTO:
155		/* if_noproto is maintained in net/if_ethersubr.c */
156	default:
157		SFXGE_PORT_UNLOCK(&sc->port);
158		return (if_get_counter_default(ifp, c));
159	}
160
161	SFXGE_PORT_UNLOCK(&sc->port);
162
163	return (val);
164}
165
166static int
167sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS)
168{
169	struct sfxge_softc *sc = arg1;
170	unsigned int id = arg2;
171	int rc;
172	uint64_t val;
173
174	SFXGE_PORT_LOCK(&sc->port);
175	if ((rc = sfxge_mac_stat_update(sc)) == 0)
176		val = ((uint64_t *)sc->port.mac_stats.decode_buf)[id];
177	SFXGE_PORT_UNLOCK(&sc->port);
178
179	if (rc == 0)
180		rc = SYSCTL_OUT(req, &val, sizeof(val));
181	return (rc);
182}
183
184static void
185sfxge_mac_stat_init(struct sfxge_softc *sc)
186{
187	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
188	struct sysctl_oid_list *stat_list;
189	unsigned int id;
190	const char *name;
191
192	stat_list = SYSCTL_CHILDREN(sc->stats_node);
193
194	/* Initialise the named stats */
195	for (id = 0; id < EFX_MAC_NSTATS; id++) {
196		name = efx_mac_stat_name(sc->enp, id);
197		SYSCTL_ADD_PROC(ctx, stat_list, OID_AUTO, name,
198		    CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
199		    sc, id, sfxge_mac_stat_handler, "Q", "");
200	}
201}
202
203#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
204
205static unsigned int
206sfxge_port_wanted_fc(struct sfxge_softc *sc)
207{
208	struct ifmedia_entry *ifm = sc->media.ifm_cur;
209
210	if (ifm->ifm_media == (IFM_ETHER | IFM_AUTO))
211		return (EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE);
212	return (((ifm->ifm_media & IFM_ETH_RXPAUSE) ? EFX_FCNTL_RESPOND : 0) |
213		((ifm->ifm_media & IFM_ETH_TXPAUSE) ? EFX_FCNTL_GENERATE : 0));
214}
215
216static unsigned int
217sfxge_port_link_fc_ifm(struct sfxge_softc *sc)
218{
219	unsigned int wanted_fc, link_fc;
220
221	efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc);
222	return ((link_fc & EFX_FCNTL_RESPOND) ? IFM_ETH_RXPAUSE : 0) |
223		((link_fc & EFX_FCNTL_GENERATE) ? IFM_ETH_TXPAUSE : 0);
224}
225
226#else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */
227
228static unsigned int
229sfxge_port_wanted_fc(struct sfxge_softc *sc)
230{
231	return (sc->port.wanted_fc);
232}
233
234static unsigned int
235sfxge_port_link_fc_ifm(struct sfxge_softc *sc)
236{
237	return (0);
238}
239
240static int
241sfxge_port_wanted_fc_handler(SYSCTL_HANDLER_ARGS)
242{
243	struct sfxge_softc *sc;
244	struct sfxge_port *port;
245	unsigned int fcntl;
246	int error;
247
248	sc = arg1;
249	port = &sc->port;
250
251	if (req->newptr != NULL) {
252		if ((error = SYSCTL_IN(req, &fcntl, sizeof(fcntl))) != 0)
253			return (error);
254
255		SFXGE_PORT_LOCK(port);
256
257		if (port->wanted_fc != fcntl) {
258			if (port->init_state == SFXGE_PORT_STARTED)
259				error = efx_mac_fcntl_set(sc->enp,
260							  port->wanted_fc,
261							  B_TRUE);
262			if (error == 0)
263				port->wanted_fc = fcntl;
264		}
265
266		SFXGE_PORT_UNLOCK(port);
267	} else {
268		SFXGE_PORT_LOCK(port);
269		fcntl = port->wanted_fc;
270		SFXGE_PORT_UNLOCK(port);
271
272		error = SYSCTL_OUT(req, &fcntl, sizeof(fcntl));
273	}
274
275	return (error);
276}
277
278static int
279sfxge_port_link_fc_handler(SYSCTL_HANDLER_ARGS)
280{
281	struct sfxge_softc *sc;
282	struct sfxge_port *port;
283	unsigned int wanted_fc, link_fc;
284
285	sc = arg1;
286	port = &sc->port;
287
288	SFXGE_PORT_LOCK(port);
289	if (__predict_true(port->init_state == SFXGE_PORT_STARTED) &&
290	    SFXGE_LINK_UP(sc))
291		efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc);
292	else
293		link_fc = 0;
294	SFXGE_PORT_UNLOCK(port);
295
296	return (SYSCTL_OUT(req, &link_fc, sizeof(link_fc)));
297}
298
299#endif /* SFXGE_HAVE_PAUSE_MEDIAOPTS */
300
301static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = {
302	[EFX_LINK_10HDX]	= IF_Mbps(10),
303	[EFX_LINK_10FDX]	= IF_Mbps(10),
304	[EFX_LINK_100HDX]	= IF_Mbps(100),
305	[EFX_LINK_100FDX]	= IF_Mbps(100),
306	[EFX_LINK_1000HDX]	= IF_Gbps(1),
307	[EFX_LINK_1000FDX]	= IF_Gbps(1),
308	[EFX_LINK_10000FDX]	= IF_Gbps(10),
309	[EFX_LINK_25000FDX]	= IF_Gbps(25),
310	[EFX_LINK_40000FDX]	= IF_Gbps(40),
311	[EFX_LINK_50000FDX]	= IF_Gbps(50),
312	[EFX_LINK_100000FDX]	= IF_Gbps(100),
313};
314
315void
316sfxge_mac_link_update(struct sfxge_softc *sc, efx_link_mode_t mode)
317{
318	struct sfxge_port *port;
319	int link_state;
320
321	port = &sc->port;
322
323	if (port->link_mode == mode)
324		return;
325
326	port->link_mode = mode;
327
328	/* Push link state update to the OS */
329	link_state = (SFXGE_LINK_UP(sc) ? LINK_STATE_UP : LINK_STATE_DOWN);
330	sc->ifnet->if_baudrate = sfxge_link_baudrate[port->link_mode];
331	if_link_state_change(sc->ifnet, link_state);
332}
333
334static void
335sfxge_mac_poll_work(void *arg, int npending)
336{
337	struct sfxge_softc *sc;
338	efx_nic_t *enp;
339	struct sfxge_port *port;
340	efx_link_mode_t mode;
341
342	sc = (struct sfxge_softc *)arg;
343	enp = sc->enp;
344	port = &sc->port;
345
346	SFXGE_PORT_LOCK(port);
347
348	if (__predict_false(port->init_state != SFXGE_PORT_STARTED))
349		goto done;
350
351	/* This may sleep waiting for MCDI completion */
352	(void)efx_port_poll(enp, &mode);
353	sfxge_mac_link_update(sc, mode);
354
355done:
356	SFXGE_PORT_UNLOCK(port);
357}
358
359static u_int
360sfxge_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
361{
362	uint8_t *mcast_addr = arg;
363
364	if (cnt == EFX_MAC_MULTICAST_LIST_MAX)
365		return (0);
366
367	memcpy(mcast_addr + (cnt * EFX_MAC_ADDR_LEN), LLADDR(sdl),
368	    EFX_MAC_ADDR_LEN);
369
370	return (1);
371}
372
373static int
374sfxge_mac_multicast_list_set(struct sfxge_softc *sc)
375{
376	struct ifnet *ifp = sc->ifnet;
377	struct sfxge_port *port = &sc->port;
378	int rc = 0;
379
380	mtx_assert(&port->lock, MA_OWNED);
381
382	port->mcast_count = if_foreach_llmaddr(ifp, sfxge_copy_maddr,
383	    port->mcast_addrs);
384	if (port->mcast_count == EFX_MAC_MULTICAST_LIST_MAX) {
385		device_printf(sc->dev, "Too many multicast addresses\n");
386		rc = EINVAL;
387	}
388
389	if (rc == 0) {
390		rc = efx_mac_multicast_list_set(sc->enp, port->mcast_addrs,
391						port->mcast_count);
392		if (rc != 0)
393			device_printf(sc->dev,
394			    "Cannot set multicast address list\n");
395	}
396
397	return (rc);
398}
399
400static int
401sfxge_mac_filter_set_locked(struct sfxge_softc *sc)
402{
403	struct ifnet *ifp = sc->ifnet;
404	struct sfxge_port *port = &sc->port;
405	boolean_t all_mulcst;
406	int rc;
407
408	mtx_assert(&port->lock, MA_OWNED);
409
410	all_mulcst = !!(ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI));
411
412	rc = sfxge_mac_multicast_list_set(sc);
413	/* Fallback to all multicast if cannot set multicast list */
414	if (rc != 0)
415		all_mulcst = B_TRUE;
416
417	rc = efx_mac_filter_set(sc->enp, !!(ifp->if_flags & IFF_PROMISC),
418				(port->mcast_count > 0), all_mulcst, B_TRUE);
419
420	return (rc);
421}
422
423int
424sfxge_mac_filter_set(struct sfxge_softc *sc)
425{
426	struct sfxge_port *port = &sc->port;
427	int rc;
428
429	SFXGE_PORT_LOCK(port);
430	/*
431	 * The function may be called without softc_lock held in the
432	 * case of SIOCADDMULTI and SIOCDELMULTI ioctls. ioctl handler
433	 * checks IFF_DRV_RUNNING flag which implies port started, but
434	 * it is not guaranteed to remain. softc_lock shared lock can't
435	 * be held in the case of these ioctls processing, since it
436	 * results in failure where kernel complains that non-sleepable
437	 * lock is held in sleeping thread. Both problems are repeatable
438	 * on LAG with LACP proto bring up.
439	 */
440	if (__predict_true(port->init_state == SFXGE_PORT_STARTED))
441		rc = sfxge_mac_filter_set_locked(sc);
442	else
443		rc = 0;
444	SFXGE_PORT_UNLOCK(port);
445	return (rc);
446}
447
448void
449sfxge_port_stop(struct sfxge_softc *sc)
450{
451	struct sfxge_port *port;
452	efx_nic_t *enp;
453
454	port = &sc->port;
455	enp = sc->enp;
456
457	SFXGE_PORT_LOCK(port);
458
459	KASSERT(port->init_state == SFXGE_PORT_STARTED,
460	    ("port not started"));
461
462	port->init_state = SFXGE_PORT_INITIALIZED;
463
464	port->mac_stats.update_time = 0;
465
466	/* This may call MCDI */
467	(void)efx_mac_drain(enp, B_TRUE);
468
469	(void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE);
470
471	port->link_mode = EFX_LINK_UNKNOWN;
472
473	/* Destroy the common code port object. */
474	efx_port_fini(enp);
475
476	efx_filter_fini(enp);
477
478	SFXGE_PORT_UNLOCK(port);
479}
480
481int
482sfxge_port_start(struct sfxge_softc *sc)
483{
484	uint8_t mac_addr[ETHER_ADDR_LEN];
485	struct epoch_tracker et;
486	struct ifnet *ifp = sc->ifnet;
487	struct sfxge_port *port;
488	efx_nic_t *enp;
489	size_t pdu;
490	int rc;
491	uint32_t phy_cap_mask;
492
493	port = &sc->port;
494	enp = sc->enp;
495
496	SFXGE_PORT_LOCK(port);
497
498	KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
499	    ("port not initialized"));
500
501	/* Initialise the required filtering */
502	if ((rc = efx_filter_init(enp)) != 0)
503		goto fail_filter_init;
504
505	/* Initialize the port object in the common code. */
506	if ((rc = efx_port_init(sc->enp)) != 0)
507		goto fail;
508
509	/* Set the SDU */
510	pdu = EFX_MAC_PDU(ifp->if_mtu);
511	if ((rc = efx_mac_pdu_set(enp, pdu)) != 0)
512		goto fail2;
513
514	if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE))
515	    != 0)
516		goto fail3;
517
518	/* Set the unicast address */
519	NET_EPOCH_ENTER(et);
520	bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr),
521	      mac_addr, sizeof(mac_addr));
522	NET_EPOCH_EXIT(et);
523	if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0)
524		goto fail4;
525
526	sfxge_mac_filter_set_locked(sc);
527
528	/* Update MAC stats by DMA every period */
529	if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
530					 port->stats_update_period_ms,
531					 B_FALSE)) != 0)
532		goto fail6;
533
534	if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
535		goto fail8;
536
537	if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media,
538				     &phy_cap_mask)) != 0)
539		goto fail9;
540
541	if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0)
542		goto fail10;
543
544	port->init_state = SFXGE_PORT_STARTED;
545
546	/* Single poll in case there were missing initial events */
547	SFXGE_PORT_UNLOCK(port);
548	sfxge_mac_poll_work(sc, 0);
549
550	return (0);
551
552fail10:
553fail9:
554	(void)efx_mac_drain(enp, B_TRUE);
555fail8:
556	(void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE);
557fail6:
558fail4:
559fail3:
560
561fail2:
562	efx_port_fini(enp);
563fail:
564	efx_filter_fini(enp);
565fail_filter_init:
566	SFXGE_PORT_UNLOCK(port);
567
568	return (rc);
569}
570
571static int
572sfxge_phy_stat_update(struct sfxge_softc *sc)
573{
574	struct sfxge_port *port = &sc->port;
575	efsys_mem_t *esmp = &port->phy_stats.dma_buf;
576	clock_t now;
577	unsigned int count;
578	int rc;
579
580	SFXGE_PORT_LOCK_ASSERT_OWNED(port);
581
582	if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) {
583		rc = 0;
584		goto out;
585	}
586
587	now = ticks;
588	if ((unsigned int)(now - port->phy_stats.update_time) < (unsigned int)hz) {
589		rc = 0;
590		goto out;
591	}
592
593	port->phy_stats.update_time = now;
594
595	/* If we're unlucky enough to read statistics wduring the DMA, wait
596	 * up to 10ms for it to finish (typically takes <500us) */
597	for (count = 0; count < 100; ++count) {
598		EFSYS_PROBE1(wait, unsigned int, count);
599
600		/* Synchronize the DMA memory for reading */
601		bus_dmamap_sync(esmp->esm_tag, esmp->esm_map,
602		    BUS_DMASYNC_POSTREAD);
603
604		/* Try to update the cached counters */
605		if ((rc = efx_phy_stats_update(sc->enp, esmp,
606		    port->phy_stats.decode_buf)) != EAGAIN)
607			goto out;
608
609		DELAY(100);
610	}
611
612	rc = ETIMEDOUT;
613out:
614	return (rc);
615}
616
617static int
618sfxge_phy_stat_handler(SYSCTL_HANDLER_ARGS)
619{
620	struct sfxge_softc *sc = arg1;
621	unsigned int id = arg2;
622	int rc;
623	uint32_t val;
624
625	SFXGE_PORT_LOCK(&sc->port);
626	if ((rc = sfxge_phy_stat_update(sc)) == 0)
627		val = ((uint32_t *)sc->port.phy_stats.decode_buf)[id];
628	SFXGE_PORT_UNLOCK(&sc->port);
629
630	if (rc == 0)
631		rc = SYSCTL_OUT(req, &val, sizeof(val));
632	return (rc);
633}
634
635static void
636sfxge_phy_stat_init(struct sfxge_softc *sc)
637{
638	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
639	struct sysctl_oid_list *stat_list;
640	unsigned int id;
641	const char *name;
642	uint64_t stat_mask = efx_nic_cfg_get(sc->enp)->enc_phy_stat_mask;
643
644	stat_list = SYSCTL_CHILDREN(sc->stats_node);
645
646	/* Initialise the named stats */
647	for (id = 0; id < EFX_PHY_NSTATS; id++) {
648		if (!(stat_mask & ((uint64_t)1 << id)))
649			continue;
650		name = efx_phy_stat_name(sc->enp, id);
651		SYSCTL_ADD_PROC(ctx, stat_list, OID_AUTO, name,
652		    CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_MPSAFE,
653		    sc, id, sfxge_phy_stat_handler,
654		    id == EFX_PHY_STAT_OUI ? "IX" : "IU", "");
655	}
656}
657
658void
659sfxge_port_fini(struct sfxge_softc *sc)
660{
661	struct sfxge_port *port;
662	efsys_mem_t *esmp;
663
664	port = &sc->port;
665	esmp = &port->mac_stats.dma_buf;
666
667	KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
668	    ("Port not initialized"));
669
670	port->init_state = SFXGE_PORT_UNINITIALIZED;
671
672	port->link_mode = EFX_LINK_UNKNOWN;
673
674	/* Finish with PHY DMA memory */
675	sfxge_dma_free(&port->phy_stats.dma_buf);
676	free(port->phy_stats.decode_buf, M_SFXGE);
677
678	sfxge_dma_free(esmp);
679	free(port->mac_stats.decode_buf, M_SFXGE);
680
681	SFXGE_PORT_LOCK_DESTROY(port);
682
683	port->sc = NULL;
684}
685
686static uint16_t
687sfxge_port_stats_update_period_ms(struct sfxge_softc *sc)
688{
689	int period_ms = sfxge_stats_update_period_ms;
690
691	if (period_ms < 0) {
692		device_printf(sc->dev,
693			"treat negative stats update period %d as 0 (disable)\n",
694			 period_ms);
695		period_ms = 0;
696	} else if (period_ms > UINT16_MAX) {
697		device_printf(sc->dev,
698			"treat too big stats update period %d as %u\n",
699			period_ms, UINT16_MAX);
700		period_ms = UINT16_MAX;
701	}
702
703	return period_ms;
704}
705
706static int
707sfxge_port_stats_update_period_ms_handler(SYSCTL_HANDLER_ARGS)
708{
709	struct sfxge_softc *sc;
710	struct sfxge_port *port;
711	unsigned int period_ms;
712	int error;
713
714	sc = arg1;
715	port = &sc->port;
716
717	if (req->newptr != NULL) {
718		error = SYSCTL_IN(req, &period_ms, sizeof(period_ms));
719		if (error != 0)
720			return (error);
721
722		if (period_ms > UINT16_MAX)
723			return (EINVAL);
724
725		SFXGE_PORT_LOCK(port);
726
727		if (port->stats_update_period_ms != period_ms) {
728			if (port->init_state == SFXGE_PORT_STARTED)
729				error = efx_mac_stats_periodic(sc->enp,
730						&port->mac_stats.dma_buf,
731						period_ms, B_FALSE);
732			if (error == 0)
733				port->stats_update_period_ms = period_ms;
734		}
735
736		SFXGE_PORT_UNLOCK(port);
737	} else {
738		SFXGE_PORT_LOCK(port);
739		period_ms = port->stats_update_period_ms;
740		SFXGE_PORT_UNLOCK(port);
741
742		error = SYSCTL_OUT(req, &period_ms, sizeof(period_ms));
743	}
744
745	return (error);
746}
747
748int
749sfxge_port_init(struct sfxge_softc *sc)
750{
751	struct sfxge_port *port;
752	struct sysctl_ctx_list *sysctl_ctx;
753	struct sysctl_oid *sysctl_tree;
754	efsys_mem_t *mac_stats_buf, *phy_stats_buf;
755	uint32_t mac_nstats;
756	size_t mac_stats_size;
757	int rc;
758
759	port = &sc->port;
760	mac_stats_buf = &port->mac_stats.dma_buf;
761	phy_stats_buf = &port->phy_stats.dma_buf;
762
763	KASSERT(port->init_state == SFXGE_PORT_UNINITIALIZED,
764	    ("Port already initialized"));
765
766	port->sc = sc;
767
768	SFXGE_PORT_LOCK_INIT(port, device_get_nameunit(sc->dev));
769
770	DBGPRINT(sc->dev, "alloc PHY stats");
771	port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t),
772					    M_SFXGE, M_WAITOK | M_ZERO);
773	if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0)
774		goto fail;
775	sfxge_phy_stat_init(sc);
776
777	DBGPRINT(sc->dev, "init sysctl");
778	sysctl_ctx = device_get_sysctl_ctx(sc->dev);
779	sysctl_tree = device_get_sysctl_tree(sc->dev);
780
781#ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS
782	/* If flow control cannot be configured or reported through
783	 * ifmedia, provide sysctls for it. */
784	port->wanted_fc = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
785	SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
786	    "wanted_fc", CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
787	    sfxge_port_wanted_fc_handler, "IU", "wanted flow control mode");
788	SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
789	    "link_fc", CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
790	    sfxge_port_link_fc_handler, "IU", "link flow control mode");
791#endif
792
793	DBGPRINT(sc->dev, "alloc MAC stats");
794	port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t),
795					    M_SFXGE, M_WAITOK | M_ZERO);
796	mac_nstats = efx_nic_cfg_get(sc->enp)->enc_mac_stats_nstats;
797	mac_stats_size = EFX_P2ROUNDUP(size_t, mac_nstats * sizeof(uint64_t),
798				       EFX_BUF_SIZE);
799	if ((rc = sfxge_dma_alloc(sc, mac_stats_size, mac_stats_buf)) != 0)
800		goto fail2;
801	port->stats_update_period_ms = sfxge_port_stats_update_period_ms(sc);
802	sfxge_mac_stat_init(sc);
803
804	SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
805	    "stats_update_period_ms",
806	    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
807	    sfxge_port_stats_update_period_ms_handler, "IU",
808	    "interface statistics refresh period");
809
810	port->init_state = SFXGE_PORT_INITIALIZED;
811
812	DBGPRINT(sc->dev, "success");
813	return (0);
814
815fail2:
816	free(port->mac_stats.decode_buf, M_SFXGE);
817	sfxge_dma_free(phy_stats_buf);
818fail:
819	free(port->phy_stats.decode_buf, M_SFXGE);
820	SFXGE_PORT_LOCK_DESTROY(port);
821	port->sc = NULL;
822	DBGPRINT(sc->dev, "failed %d", rc);
823	return (rc);
824}
825
826static const int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = {
827	[EFX_PHY_MEDIA_CX4] = {
828		[EFX_LINK_10000FDX]	= IFM_ETHER | IFM_FDX | IFM_10G_CX4,
829	},
830	[EFX_PHY_MEDIA_KX4] = {
831		[EFX_LINK_10000FDX]	= IFM_ETHER | IFM_FDX | IFM_10G_KX4,
832	},
833	[EFX_PHY_MEDIA_XFP] = {
834		/* Don't know the module type, but assume SR for now. */
835		[EFX_LINK_10000FDX]	= IFM_ETHER | IFM_FDX | IFM_10G_SR,
836	},
837	[EFX_PHY_MEDIA_QSFP_PLUS] = {
838		/* Don't know the module type, but assume SR for now. */
839		[EFX_LINK_10000FDX]	= IFM_ETHER | IFM_FDX | IFM_10G_SR,
840		[EFX_LINK_25000FDX]	= IFM_ETHER | IFM_FDX | IFM_25G_SR,
841		[EFX_LINK_40000FDX]	= IFM_ETHER | IFM_FDX | IFM_40G_CR4,
842		[EFX_LINK_50000FDX]	= IFM_ETHER | IFM_FDX | IFM_50G_SR,
843		[EFX_LINK_100000FDX]	= IFM_ETHER | IFM_FDX | IFM_100G_SR2,
844	},
845	[EFX_PHY_MEDIA_SFP_PLUS] = {
846		/* Don't know the module type, but assume SX/SR for now. */
847		[EFX_LINK_1000FDX]	= IFM_ETHER | IFM_FDX | IFM_1000_SX,
848		[EFX_LINK_10000FDX]	= IFM_ETHER | IFM_FDX | IFM_10G_SR,
849		[EFX_LINK_25000FDX]	= IFM_ETHER | IFM_FDX | IFM_25G_SR,
850	},
851	[EFX_PHY_MEDIA_BASE_T] = {
852		[EFX_LINK_10HDX]	= IFM_ETHER | IFM_HDX | IFM_10_T,
853		[EFX_LINK_10FDX]	= IFM_ETHER | IFM_FDX | IFM_10_T,
854		[EFX_LINK_100HDX]	= IFM_ETHER | IFM_HDX | IFM_100_TX,
855		[EFX_LINK_100FDX]	= IFM_ETHER | IFM_FDX | IFM_100_TX,
856		[EFX_LINK_1000HDX]	= IFM_ETHER | IFM_HDX | IFM_1000_T,
857		[EFX_LINK_1000FDX]	= IFM_ETHER | IFM_FDX | IFM_1000_T,
858		[EFX_LINK_10000FDX]	= IFM_ETHER | IFM_FDX | IFM_10G_T,
859	},
860};
861
862static void
863sfxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
864{
865	struct sfxge_softc *sc;
866	efx_phy_media_type_t medium_type;
867	efx_link_mode_t mode;
868
869	sc = ifp->if_softc;
870	SFXGE_ADAPTER_LOCK(sc);
871
872	ifmr->ifm_status = IFM_AVALID;
873	ifmr->ifm_active = IFM_ETHER;
874
875	if (SFXGE_RUNNING(sc) && SFXGE_LINK_UP(sc)) {
876		ifmr->ifm_status |= IFM_ACTIVE;
877
878		efx_phy_media_type_get(sc->enp, &medium_type);
879		mode = sc->port.link_mode;
880		ifmr->ifm_active |= sfxge_link_mode[medium_type][mode];
881		ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc);
882	}
883
884	SFXGE_ADAPTER_UNLOCK(sc);
885}
886
887static efx_phy_cap_type_t
888sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
889{
890	switch (mode) {
891	case EFX_LINK_10HDX:
892		return (EFX_PHY_CAP_10HDX);
893	case EFX_LINK_10FDX:
894		return (EFX_PHY_CAP_10FDX);
895	case EFX_LINK_100HDX:
896		return (EFX_PHY_CAP_100HDX);
897	case EFX_LINK_100FDX:
898		return (EFX_PHY_CAP_100FDX);
899	case EFX_LINK_1000HDX:
900		return (EFX_PHY_CAP_1000HDX);
901	case EFX_LINK_1000FDX:
902		return (EFX_PHY_CAP_1000FDX);
903	case EFX_LINK_10000FDX:
904		return (EFX_PHY_CAP_10000FDX);
905	case EFX_LINK_25000FDX:
906		return (EFX_PHY_CAP_25000FDX);
907	case EFX_LINK_40000FDX:
908		return (EFX_PHY_CAP_40000FDX);
909	case EFX_LINK_50000FDX:
910		return (EFX_PHY_CAP_50000FDX);
911	case EFX_LINK_100000FDX:
912		return (EFX_PHY_CAP_100000FDX);
913	default:
914		return (EFX_PHY_CAP_INVALID);
915	}
916}
917
918static int
919sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
920{
921	/* Get global options (duplex), type and subtype bits */
922	int ifmedia_masked = ifmedia & (IFM_GMASK | IFM_NMASK | IFM_TMASK);
923	efx_phy_media_type_t medium_type;
924	boolean_t mode_found = B_FALSE;
925	uint32_t cap_mask, mode_cap_mask;
926	efx_link_mode_t mode;
927	efx_phy_cap_type_t phy_cap;
928
929	efx_phy_media_type_get(sc->enp, &medium_type);
930	if (medium_type >= nitems(sfxge_link_mode)) {
931		if_printf(sc->ifnet, "unexpected media type %d\n", medium_type);
932		return (EINVAL);
933	}
934
935	efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
936
937	for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
938		if (ifmedia_masked == sfxge_link_mode[medium_type][mode]) {
939			mode_found = B_TRUE;
940			break;
941		}
942	}
943
944	if (!mode_found) {
945		/*
946		 * If media is not in the table, it must be IFM_AUTO.
947		 */
948		KASSERT((cap_mask & (1 << EFX_PHY_CAP_AN)) &&
949		    ifmedia_masked == (IFM_ETHER | IFM_AUTO),
950		    ("%s: no mode for media %#x", __func__, ifmedia));
951		*phy_cap_mask = (cap_mask & ~(1 << EFX_PHY_CAP_ASYM));
952		return (0);
953	}
954
955	phy_cap = sfxge_link_mode_to_phy_cap(mode);
956	if (phy_cap == EFX_PHY_CAP_INVALID) {
957		if_printf(sc->ifnet,
958			  "cannot map link mode %d to phy capability\n",
959			  mode);
960		return (EINVAL);
961	}
962
963	mode_cap_mask = (1 << phy_cap);
964	mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN);
965#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
966	if (ifmedia & IFM_ETH_RXPAUSE)
967		mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
968	if (!(ifmedia & IFM_ETH_TXPAUSE))
969		mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_ASYM);
970#else
971	mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
972#endif
973
974	*phy_cap_mask = mode_cap_mask;
975	return (0);
976}
977
978static int
979sfxge_media_change(struct ifnet *ifp)
980{
981	struct sfxge_softc *sc;
982	struct ifmedia_entry *ifm;
983	int rc;
984	uint32_t phy_cap_mask;
985
986	sc = ifp->if_softc;
987	ifm = sc->media.ifm_cur;
988
989	SFXGE_ADAPTER_LOCK(sc);
990
991	if (!SFXGE_RUNNING(sc)) {
992		rc = 0;
993		goto out;
994	}
995
996	rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE);
997	if (rc != 0)
998		goto out;
999
1000	if ((rc = sfxge_phy_cap_mask(sc, ifm->ifm_media, &phy_cap_mask)) != 0)
1001		goto out;
1002
1003	rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask);
1004out:
1005	SFXGE_ADAPTER_UNLOCK(sc);
1006
1007	return (rc);
1008}
1009
1010int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
1011{
1012	efx_phy_media_type_t medium_type;
1013	uint32_t cap_mask, mode_cap_mask;
1014	efx_link_mode_t mode;
1015	efx_phy_cap_type_t phy_cap;
1016	int mode_ifm, best_mode_ifm = 0;
1017	int rc;
1018
1019	/*
1020	 * We need port state to initialise the ifmedia list.
1021	 * It requires initialized NIC what is already done in
1022	 * sfxge_create() when resources are estimated.
1023	 */
1024	if ((rc = efx_filter_init(sc->enp)) != 0)
1025		goto out1;
1026	if ((rc = efx_port_init(sc->enp)) != 0)
1027		goto out2;
1028
1029	/*
1030	 * Register ifconfig callbacks for querying and setting the
1031	 * link mode and link status.
1032	 */
1033	ifmedia_init(&sc->media, IFM_IMASK, sfxge_media_change,
1034	    sfxge_media_status);
1035
1036	/*
1037	 * Map firmware medium type and capabilities to ifmedia types.
1038	 * ifmedia does not distinguish between forcing the link mode
1039	 * and disabling auto-negotiation.  1000BASE-T and 10GBASE-T
1040	 * require AN even if only one link mode is enabled, and for
1041	 * 100BASE-TX it is useful even if the link mode is forced.
1042	 * Therefore we never disable auto-negotiation.
1043	 *
1044	 * Also enable and advertise flow control by default.
1045	 */
1046
1047	efx_phy_media_type_get(sc->enp, &medium_type);
1048	efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
1049
1050	for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
1051		phy_cap = sfxge_link_mode_to_phy_cap(mode);
1052		if (phy_cap == EFX_PHY_CAP_INVALID)
1053			continue;
1054
1055		mode_cap_mask = (1 << phy_cap);
1056		mode_ifm = sfxge_link_mode[medium_type][mode];
1057
1058		if ((cap_mask & mode_cap_mask) && mode_ifm) {
1059			/* No flow-control */
1060			ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1061
1062#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
1063			/* Respond-only.  If using AN, we implicitly
1064			 * offer symmetric as well, but that doesn't
1065			 * mean we *have* to generate pause frames.
1066			 */
1067			mode_ifm |= IFM_ETH_RXPAUSE;
1068			ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1069
1070			/* Symmetric */
1071			mode_ifm |= IFM_ETH_TXPAUSE;
1072			ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1073#endif
1074
1075			/* Link modes are numbered in order of speed,
1076			 * so assume the last one available is the best.
1077			 */
1078			best_mode_ifm = mode_ifm;
1079		}
1080	}
1081
1082	if (cap_mask & (1 << EFX_PHY_CAP_AN)) {
1083		/* Add autoselect mode. */
1084		mode_ifm = IFM_ETHER | IFM_AUTO;
1085		ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1086		best_mode_ifm = mode_ifm;
1087	}
1088
1089	if (best_mode_ifm != 0)
1090		ifmedia_set(&sc->media, best_mode_ifm);
1091
1092	/* Now discard port state until interface is started. */
1093	efx_port_fini(sc->enp);
1094out2:
1095	efx_filter_fini(sc->enp);
1096out1:
1097	return (rc);
1098}
1099