xref: /freebsd-src/sys/dev/axgbe/xgbe-sysctl.c (revision a527b9cb721a597a0bc5313ac55290cc6a91deac)
17113afc8SEmmanuel Vadot /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
37113afc8SEmmanuel Vadot  *
47113afc8SEmmanuel Vadot  * Copyright (c) 2020 Advanced Micro Devices, Inc.
57113afc8SEmmanuel Vadot  *
67113afc8SEmmanuel Vadot  * Redistribution and use in source and binary forms, with or without
77113afc8SEmmanuel Vadot  * modification, are permitted provided that the following conditions
87113afc8SEmmanuel Vadot  * are met:
97113afc8SEmmanuel Vadot  * 1. Redistributions of source code must retain the above copyright
107113afc8SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer.
117113afc8SEmmanuel Vadot  * 2. Redistributions in binary form must reproduce the above copyright
127113afc8SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer in the
137113afc8SEmmanuel Vadot  *    documentation and/or other materials provided with the distribution.
147113afc8SEmmanuel Vadot  *
157113afc8SEmmanuel Vadot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
167113afc8SEmmanuel Vadot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
177113afc8SEmmanuel Vadot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
187113afc8SEmmanuel Vadot  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
197113afc8SEmmanuel Vadot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
207113afc8SEmmanuel Vadot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
217113afc8SEmmanuel Vadot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
227113afc8SEmmanuel Vadot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
237113afc8SEmmanuel Vadot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
247113afc8SEmmanuel Vadot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
257113afc8SEmmanuel Vadot  * SUCH DAMAGE.
267113afc8SEmmanuel Vadot  *
277113afc8SEmmanuel Vadot  * Contact Information :
287113afc8SEmmanuel Vadot  * Rajesh Kumar <rajesh1.kumar@amd.com>
297113afc8SEmmanuel Vadot  * Arpan Palit <Arpan.Palit@amd.com>
307113afc8SEmmanuel Vadot  */
317113afc8SEmmanuel Vadot 
327113afc8SEmmanuel Vadot #include <sys/param.h>
337113afc8SEmmanuel Vadot #include <sys/sysctl.h>
347113afc8SEmmanuel Vadot #include <sys/sbuf.h>
357113afc8SEmmanuel Vadot 
367113afc8SEmmanuel Vadot #include "xgbe.h"
377113afc8SEmmanuel Vadot #include "xgbe-common.h"
387113afc8SEmmanuel Vadot 
397113afc8SEmmanuel Vadot #define SYSCTL_BUF_LEN 64
407113afc8SEmmanuel Vadot 
417113afc8SEmmanuel Vadot typedef enum{
427113afc8SEmmanuel Vadot 	/* Coalesce flag */
437113afc8SEmmanuel Vadot 	rx_coalesce_usecs = 1,
447113afc8SEmmanuel Vadot 	rx_max_coalesced_frames,
457113afc8SEmmanuel Vadot 	rx_coalesce_usecs_irq,
467113afc8SEmmanuel Vadot 	rx_max_coalesced_frames_irq,
477113afc8SEmmanuel Vadot 	tx_coalesce_usecs,
487113afc8SEmmanuel Vadot 	tx_max_coalesced_frames,
497113afc8SEmmanuel Vadot 	tx_coalesce_usecs_irq,
507113afc8SEmmanuel Vadot 	tx_max_coalesced_frames_irq,
517113afc8SEmmanuel Vadot 	stats_block_coalesce_usecs,
527113afc8SEmmanuel Vadot 	use_adaptive_rx_coalesce,
537113afc8SEmmanuel Vadot 	use_adaptive_tx_coalesce,
547113afc8SEmmanuel Vadot 	pkt_rate_low,
557113afc8SEmmanuel Vadot 	rx_coalesce_usecs_low,
567113afc8SEmmanuel Vadot 	rx_max_coalesced_frames_low,
577113afc8SEmmanuel Vadot 	tx_coalesce_usecs_low,
587113afc8SEmmanuel Vadot 	tx_max_coalesced_frames_low,
597113afc8SEmmanuel Vadot 	pkt_rate_high,
607113afc8SEmmanuel Vadot 	rx_coalesce_usecs_high,
617113afc8SEmmanuel Vadot 	rx_max_coalesced_frames_high,
627113afc8SEmmanuel Vadot 	tx_coalesce_usecs_high,
637113afc8SEmmanuel Vadot 	tx_max_coalesced_frames_high,
647113afc8SEmmanuel Vadot 	rate_sample_interval,
657113afc8SEmmanuel Vadot 
667113afc8SEmmanuel Vadot 	/* Pasue flag */
677113afc8SEmmanuel Vadot 	autoneg,
687113afc8SEmmanuel Vadot 	tx_pause,
697113afc8SEmmanuel Vadot 	rx_pause,
707113afc8SEmmanuel Vadot 
717113afc8SEmmanuel Vadot 	/* link settings */
727113afc8SEmmanuel Vadot 	speed,
737113afc8SEmmanuel Vadot 	duplex,
747113afc8SEmmanuel Vadot 
757113afc8SEmmanuel Vadot 	/* Ring settings */
767113afc8SEmmanuel Vadot 	rx_pending,
777113afc8SEmmanuel Vadot 	rx_mini_pending,
787113afc8SEmmanuel Vadot 	rx_jumbo_pending,
797113afc8SEmmanuel Vadot 	tx_pending,
807113afc8SEmmanuel Vadot 
817113afc8SEmmanuel Vadot 	/* Channels settings */
827113afc8SEmmanuel Vadot 	rx_count,
837113afc8SEmmanuel Vadot 	tx_count,
847113afc8SEmmanuel Vadot 	other_count,
857113afc8SEmmanuel Vadot 	combined_count,
867113afc8SEmmanuel Vadot } sysctl_variable_t;
877113afc8SEmmanuel Vadot 
887113afc8SEmmanuel Vadot typedef enum {
897113afc8SEmmanuel Vadot 	SYSL_NONE,
907113afc8SEmmanuel Vadot 	SYSL_BOOL,
917113afc8SEmmanuel Vadot 	SYSL_S32,
927113afc8SEmmanuel Vadot 	SYSL_U8,
937113afc8SEmmanuel Vadot 	SYSL_U16,
947113afc8SEmmanuel Vadot 	SYSL_U32,
957113afc8SEmmanuel Vadot 	SYSL_U64,
967113afc8SEmmanuel Vadot 	SYSL_BE16,
977113afc8SEmmanuel Vadot 	SYSL_IP4,
987113afc8SEmmanuel Vadot 	SYSL_STR,
997113afc8SEmmanuel Vadot 	SYSL_FLAG,
1007113afc8SEmmanuel Vadot 	SYSL_MAC,
1017113afc8SEmmanuel Vadot } sysctl_type_t;
1027113afc8SEmmanuel Vadot 
1037113afc8SEmmanuel Vadot struct sysctl_info {
1047113afc8SEmmanuel Vadot 	uint8_t name[32];
1057113afc8SEmmanuel Vadot 	sysctl_type_t type;
1067113afc8SEmmanuel Vadot 	sysctl_variable_t flag;
1077113afc8SEmmanuel Vadot 	uint8_t support[16];
1087113afc8SEmmanuel Vadot };
1097113afc8SEmmanuel Vadot 
1107113afc8SEmmanuel Vadot struct sysctl_op {
1117113afc8SEmmanuel Vadot 	/* Coalesce options */
1127113afc8SEmmanuel Vadot 	unsigned int rx_coalesce_usecs;
1137113afc8SEmmanuel Vadot 	unsigned int rx_max_coalesced_frames;
1147113afc8SEmmanuel Vadot 	unsigned int rx_coalesce_usecs_irq;
1157113afc8SEmmanuel Vadot 	unsigned int rx_max_coalesced_frames_irq;
1167113afc8SEmmanuel Vadot 	unsigned int tx_coalesce_usecs;
1177113afc8SEmmanuel Vadot 	unsigned int tx_max_coalesced_frames;
1187113afc8SEmmanuel Vadot 	unsigned int tx_coalesce_usecs_irq;
1197113afc8SEmmanuel Vadot 	unsigned int tx_max_coalesced_frames_irq;
1207113afc8SEmmanuel Vadot 	unsigned int stats_block_coalesce_usecs;
1217113afc8SEmmanuel Vadot 	unsigned int use_adaptive_rx_coalesce;
1227113afc8SEmmanuel Vadot 	unsigned int use_adaptive_tx_coalesce;
1237113afc8SEmmanuel Vadot 	unsigned int pkt_rate_low;
1247113afc8SEmmanuel Vadot 	unsigned int rx_coalesce_usecs_low;
1257113afc8SEmmanuel Vadot 	unsigned int rx_max_coalesced_frames_low;
1267113afc8SEmmanuel Vadot 	unsigned int tx_coalesce_usecs_low;
1277113afc8SEmmanuel Vadot 	unsigned int tx_max_coalesced_frames_low;
1287113afc8SEmmanuel Vadot 	unsigned int pkt_rate_high;
1297113afc8SEmmanuel Vadot 	unsigned int rx_coalesce_usecs_high;
1307113afc8SEmmanuel Vadot 	unsigned int rx_max_coalesced_frames_high;
1317113afc8SEmmanuel Vadot 	unsigned int tx_coalesce_usecs_high;
1327113afc8SEmmanuel Vadot 	unsigned int tx_max_coalesced_frames_high;
1337113afc8SEmmanuel Vadot 	unsigned int rate_sample_interval;
1347113afc8SEmmanuel Vadot 
1357113afc8SEmmanuel Vadot 	/* Pasue options */
1367113afc8SEmmanuel Vadot 	unsigned int autoneg;
1377113afc8SEmmanuel Vadot 	unsigned int tx_pause;
1387113afc8SEmmanuel Vadot 	unsigned int rx_pause;
1397113afc8SEmmanuel Vadot 
1407113afc8SEmmanuel Vadot 	/* Link settings options */
1417113afc8SEmmanuel Vadot 	unsigned int speed;
1427113afc8SEmmanuel Vadot 	unsigned int duplex;
1437113afc8SEmmanuel Vadot 
1447113afc8SEmmanuel Vadot 	/* Ring param options */
1457113afc8SEmmanuel Vadot 	unsigned int rx_max_pending;
1467113afc8SEmmanuel Vadot 	unsigned int rx_mini_max_pending;
1477113afc8SEmmanuel Vadot 	unsigned int rx_jumbo_max_pending;
1487113afc8SEmmanuel Vadot 	unsigned int tx_max_pending;
1497113afc8SEmmanuel Vadot 	unsigned int rx_pending;
1507113afc8SEmmanuel Vadot 	unsigned int rx_mini_pending;
1517113afc8SEmmanuel Vadot 	unsigned int rx_jumbo_pending;
1527113afc8SEmmanuel Vadot 	unsigned int tx_pending;
1537113afc8SEmmanuel Vadot 
1547113afc8SEmmanuel Vadot 	/* Channels options */
1557113afc8SEmmanuel Vadot 	unsigned int max_rx;
1567113afc8SEmmanuel Vadot 	unsigned int max_tx;
1577113afc8SEmmanuel Vadot 	unsigned int max_other;
1587113afc8SEmmanuel Vadot 	unsigned int max_combined;
1597113afc8SEmmanuel Vadot 	unsigned int rx_count;
1607113afc8SEmmanuel Vadot 	unsigned int tx_count;
1617113afc8SEmmanuel Vadot 	unsigned int other_count;
1627113afc8SEmmanuel Vadot 	unsigned int combined_count;
1637113afc8SEmmanuel Vadot } sys_op;
1647113afc8SEmmanuel Vadot 
1657113afc8SEmmanuel Vadot #define GSTRING_LEN 32
1667113afc8SEmmanuel Vadot 
1677113afc8SEmmanuel Vadot struct xgbe_stats {
1687113afc8SEmmanuel Vadot 	char stat_string[GSTRING_LEN];
1697113afc8SEmmanuel Vadot 	int stat_size;
1707113afc8SEmmanuel Vadot 	int stat_offset;
1717113afc8SEmmanuel Vadot };
1727113afc8SEmmanuel Vadot 
1737113afc8SEmmanuel Vadot #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
1747113afc8SEmmanuel Vadot 
1757113afc8SEmmanuel Vadot #define XGMAC_MMC_STAT(_string, _var)			   \
1767113afc8SEmmanuel Vadot 	{ _string,					      \
1777113afc8SEmmanuel Vadot 	  FIELD_SIZEOF(struct xgbe_mmc_stats, _var),	    \
1787113afc8SEmmanuel Vadot 	  offsetof(struct xgbe_prv_data, mmc_stats._var),       \
1797113afc8SEmmanuel Vadot 	}
1807113afc8SEmmanuel Vadot 
1817113afc8SEmmanuel Vadot #define XGMAC_EXT_STAT(_string, _var)			   \
1827113afc8SEmmanuel Vadot 	{ _string,					      \
1837113afc8SEmmanuel Vadot 	  FIELD_SIZEOF(struct xgbe_ext_stats, _var),	    \
1847113afc8SEmmanuel Vadot 	  offsetof(struct xgbe_prv_data, ext_stats._var),       \
1857113afc8SEmmanuel Vadot 	}
1867113afc8SEmmanuel Vadot static const struct xgbe_stats xgbe_gstring_stats[] = {
1877113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
1887113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_packets", txframecount_gb),
1897113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
1907113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
1917113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
1927113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
1937113afc8SEmmanuel Vadot 	XGMAC_EXT_STAT("tx_vxlan_packets", tx_vxlan_packets),
1947113afc8SEmmanuel Vadot 	XGMAC_EXT_STAT("tx_tso_packets", tx_tso_packets),
1957113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
1967113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
1977113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
1987113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
1997113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
2007113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
2017113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
2027113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
2037113afc8SEmmanuel Vadot 
2047113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
2057113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_packets", rxframecount_gb),
2067113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
2077113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
2087113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
2097113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
2107113afc8SEmmanuel Vadot 	XGMAC_EXT_STAT("rx_vxlan_packets", rx_vxlan_packets),
2117113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
2127113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
2137113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
2147113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
2157113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
2167113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
2177113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
2187113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
2197113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
2207113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
2217113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
2227113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
2237113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
2247113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
2257113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
2267113afc8SEmmanuel Vadot 	XGMAC_EXT_STAT("rx_csum_errors", rx_csum_errors),
2277113afc8SEmmanuel Vadot 	XGMAC_EXT_STAT("rx_vxlan_csum_errors", rx_vxlan_csum_errors),
2287113afc8SEmmanuel Vadot 	XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
2297113afc8SEmmanuel Vadot 	XGMAC_EXT_STAT("rx_split_header_packets", rx_split_header_packets),
2307113afc8SEmmanuel Vadot 	XGMAC_EXT_STAT("rx_buffer_unavailable", rx_buffer_unavailable),
2317113afc8SEmmanuel Vadot };
2327113afc8SEmmanuel Vadot 
2337113afc8SEmmanuel Vadot #define XGBE_STATS_COUNT	ARRAY_SIZE(xgbe_gstring_stats)
2347113afc8SEmmanuel Vadot 
2357113afc8SEmmanuel Vadot char** alloc_sysctl_buffer(void);
2367113afc8SEmmanuel Vadot void get_val(char *buf, char **op, char **val, int *n_op);
2377113afc8SEmmanuel Vadot void fill_data(struct sysctl_op *sys_op, int flag, unsigned int value);
2387113afc8SEmmanuel Vadot 
2397113afc8SEmmanuel Vadot static int
2407113afc8SEmmanuel Vadot exit_bad_op(void)
2417113afc8SEmmanuel Vadot {
2427113afc8SEmmanuel Vadot 
2437113afc8SEmmanuel Vadot 	printf("SYSCTL: bad command line option (s)\n");
2447113afc8SEmmanuel Vadot 	return(-EINVAL);
2457113afc8SEmmanuel Vadot }
2467113afc8SEmmanuel Vadot 
2477113afc8SEmmanuel Vadot static inline int
2487113afc8SEmmanuel Vadot get_ubuf(struct sysctl_req *req, char *ubuf)
2497113afc8SEmmanuel Vadot {
2507113afc8SEmmanuel Vadot 	int rc;
2517113afc8SEmmanuel Vadot 
2527113afc8SEmmanuel Vadot 	printf("%s: len:0x%li idx:0x%li\n", __func__, req->newlen,
2537113afc8SEmmanuel Vadot 	    req->newidx);
2547113afc8SEmmanuel Vadot 	if (req->newlen >= SYSCTL_BUF_LEN)
2557113afc8SEmmanuel Vadot 		return (-EINVAL);
2567113afc8SEmmanuel Vadot 
2577113afc8SEmmanuel Vadot 	rc = SYSCTL_IN(req, ubuf, req->newlen);
2587113afc8SEmmanuel Vadot 	if (rc)
2597113afc8SEmmanuel Vadot 		return (rc);
2607113afc8SEmmanuel Vadot 	ubuf[req->newlen] = '\0';
2617113afc8SEmmanuel Vadot 
2627113afc8SEmmanuel Vadot 	return (0);
2637113afc8SEmmanuel Vadot }
2647113afc8SEmmanuel Vadot 
2657113afc8SEmmanuel Vadot char**
2667113afc8SEmmanuel Vadot alloc_sysctl_buffer(void)
2677113afc8SEmmanuel Vadot {
2687113afc8SEmmanuel Vadot 	char **buffer;
2697113afc8SEmmanuel Vadot 	int i;
2707113afc8SEmmanuel Vadot 
2717113afc8SEmmanuel Vadot 	buffer = malloc(sizeof(char *)*32, M_AXGBE, M_WAITOK | M_ZERO);
2727113afc8SEmmanuel Vadot 	for(i = 0; i < 32; i++)
2737113afc8SEmmanuel Vadot 		buffer[i] = malloc(sizeof(char)*32, M_AXGBE, M_WAITOK | M_ZERO);
2747113afc8SEmmanuel Vadot 
2757113afc8SEmmanuel Vadot 	return (buffer);
2767113afc8SEmmanuel Vadot }
2777113afc8SEmmanuel Vadot 
2787113afc8SEmmanuel Vadot void
2797113afc8SEmmanuel Vadot get_val(char *buf, char **op, char **val, int *n_op)
2807113afc8SEmmanuel Vadot {
2817113afc8SEmmanuel Vadot 	int blen = strlen(buf);
2827113afc8SEmmanuel Vadot 	int count = 0;
2837113afc8SEmmanuel Vadot 	int i, j;
2847113afc8SEmmanuel Vadot 
2857113afc8SEmmanuel Vadot 	*n_op = 0;
2867113afc8SEmmanuel Vadot 	for (i = 0; i < blen; i++) {
2877113afc8SEmmanuel Vadot 		count++;
2887113afc8SEmmanuel Vadot 		/* Get sysctl command option */
2897113afc8SEmmanuel Vadot 		for (j = 0; buf[i] != ' '; j++) {
2907113afc8SEmmanuel Vadot 			if (i >= blen)
2917113afc8SEmmanuel Vadot 				break;
2927113afc8SEmmanuel Vadot 			op[*n_op][j] = buf[i++];
2937113afc8SEmmanuel Vadot 		}
2947113afc8SEmmanuel Vadot 		op[*n_op][j+1] = '\0';
2957113afc8SEmmanuel Vadot 		if (i >= strlen(buf))
2967113afc8SEmmanuel Vadot 			goto out;
2977113afc8SEmmanuel Vadot 
2987113afc8SEmmanuel Vadot 		/* Get sysctl value*/
2997113afc8SEmmanuel Vadot 		i++;
3007113afc8SEmmanuel Vadot 		for (j = 0; buf[i] != ' '; j++) {
3017113afc8SEmmanuel Vadot 			if (i >= blen)
3027113afc8SEmmanuel Vadot 				break;
3037113afc8SEmmanuel Vadot 			val[*n_op][j] = buf[i++];
3047113afc8SEmmanuel Vadot 		}
3057113afc8SEmmanuel Vadot 		val[*n_op][j+1] = '\0';
3067113afc8SEmmanuel Vadot 		if (i >= strlen(buf))
3077113afc8SEmmanuel Vadot 			goto out;
3087113afc8SEmmanuel Vadot 
3097113afc8SEmmanuel Vadot 		*n_op = count;
3107113afc8SEmmanuel Vadot 	}
3117113afc8SEmmanuel Vadot 
3127113afc8SEmmanuel Vadot out:
3137113afc8SEmmanuel Vadot 	*n_op = count;
3147113afc8SEmmanuel Vadot }
3157113afc8SEmmanuel Vadot 
3167113afc8SEmmanuel Vadot void
3177113afc8SEmmanuel Vadot fill_data(struct sysctl_op *sys_op, int flag, unsigned int value)
3187113afc8SEmmanuel Vadot {
3197113afc8SEmmanuel Vadot 
3207113afc8SEmmanuel Vadot 	switch(flag) {
3217113afc8SEmmanuel Vadot 	case 1:
3227113afc8SEmmanuel Vadot 	sys_op->rx_coalesce_usecs = value;
3237113afc8SEmmanuel Vadot 	break;
3247113afc8SEmmanuel Vadot 	case 2:
3257113afc8SEmmanuel Vadot 	sys_op->rx_max_coalesced_frames = value;
3267113afc8SEmmanuel Vadot 	break;
3277113afc8SEmmanuel Vadot 	case 3:
3287113afc8SEmmanuel Vadot 	sys_op->rx_coalesce_usecs_irq = value;
3297113afc8SEmmanuel Vadot 	break;
3307113afc8SEmmanuel Vadot 	case 4:
3317113afc8SEmmanuel Vadot 	sys_op->rx_max_coalesced_frames_irq = value;
3327113afc8SEmmanuel Vadot 	break;
3337113afc8SEmmanuel Vadot 	case 5:
3347113afc8SEmmanuel Vadot 	sys_op->tx_coalesce_usecs = value;
3357113afc8SEmmanuel Vadot 	break;
3367113afc8SEmmanuel Vadot 	case 6:
3377113afc8SEmmanuel Vadot 	sys_op->tx_max_coalesced_frames = value;
3387113afc8SEmmanuel Vadot 	break;
3397113afc8SEmmanuel Vadot 	case 7:
3407113afc8SEmmanuel Vadot 	sys_op->tx_coalesce_usecs_irq = value;
3417113afc8SEmmanuel Vadot 	break;
3427113afc8SEmmanuel Vadot 	case 8:
3437113afc8SEmmanuel Vadot 	sys_op->tx_max_coalesced_frames_irq = value;
3447113afc8SEmmanuel Vadot 	break;
3457113afc8SEmmanuel Vadot 	case 9:
3467113afc8SEmmanuel Vadot 	sys_op->stats_block_coalesce_usecs = value;
3477113afc8SEmmanuel Vadot 	break;
3487113afc8SEmmanuel Vadot 	case 10:
3497113afc8SEmmanuel Vadot 	sys_op->use_adaptive_rx_coalesce = value;
3507113afc8SEmmanuel Vadot 	break;
3517113afc8SEmmanuel Vadot 	case 11:
3527113afc8SEmmanuel Vadot 	sys_op->use_adaptive_tx_coalesce = value;
3537113afc8SEmmanuel Vadot 	break;
3547113afc8SEmmanuel Vadot 	case 12:
3557113afc8SEmmanuel Vadot 	sys_op->pkt_rate_low = value;
3567113afc8SEmmanuel Vadot 	break;
3577113afc8SEmmanuel Vadot 	case 13:
3587113afc8SEmmanuel Vadot 	sys_op->rx_coalesce_usecs_low = value;
3597113afc8SEmmanuel Vadot 	break;
3607113afc8SEmmanuel Vadot 	case 14:
3617113afc8SEmmanuel Vadot 	sys_op->rx_max_coalesced_frames_low = value;
3627113afc8SEmmanuel Vadot 	break;
3637113afc8SEmmanuel Vadot 	case 15:
3647113afc8SEmmanuel Vadot 	sys_op->tx_coalesce_usecs_low = value;
3657113afc8SEmmanuel Vadot 	break;
3667113afc8SEmmanuel Vadot 	case 16:
3677113afc8SEmmanuel Vadot 	sys_op->tx_max_coalesced_frames_low = value;
3687113afc8SEmmanuel Vadot 	break;
3697113afc8SEmmanuel Vadot 	case 17:
3707113afc8SEmmanuel Vadot 	sys_op->pkt_rate_high = value;
3717113afc8SEmmanuel Vadot 	break;
3727113afc8SEmmanuel Vadot 	case 18:
3737113afc8SEmmanuel Vadot 	sys_op->rx_coalesce_usecs_high = value;
3747113afc8SEmmanuel Vadot 	break;
3757113afc8SEmmanuel Vadot 	case 19:
3767113afc8SEmmanuel Vadot 	sys_op->rx_max_coalesced_frames_high = value;
3777113afc8SEmmanuel Vadot 	break;
3787113afc8SEmmanuel Vadot 	case 20:
3797113afc8SEmmanuel Vadot 	sys_op->tx_coalesce_usecs_high = value;
3807113afc8SEmmanuel Vadot 	break;
3817113afc8SEmmanuel Vadot 	case 21:
3827113afc8SEmmanuel Vadot 	sys_op->tx_max_coalesced_frames_high = value;
3837113afc8SEmmanuel Vadot 	break;
3847113afc8SEmmanuel Vadot 	case 22:
3857113afc8SEmmanuel Vadot 	sys_op->rate_sample_interval = value;
3867113afc8SEmmanuel Vadot 	break;
3877113afc8SEmmanuel Vadot 	case 23:
3887113afc8SEmmanuel Vadot 	sys_op->autoneg = value;
3897113afc8SEmmanuel Vadot 	break;
3907113afc8SEmmanuel Vadot 	case 24:
3917113afc8SEmmanuel Vadot 	sys_op->rx_pause = value;
3927113afc8SEmmanuel Vadot 	break;
3937113afc8SEmmanuel Vadot 	case 25:
3947113afc8SEmmanuel Vadot 	sys_op->tx_pause = value;
3957113afc8SEmmanuel Vadot 	break;
3967113afc8SEmmanuel Vadot 	case 26:
3977113afc8SEmmanuel Vadot 	sys_op->speed = value;
3987113afc8SEmmanuel Vadot 	break;
3997113afc8SEmmanuel Vadot 	case 27:
4007113afc8SEmmanuel Vadot 	sys_op->duplex = value;
4017113afc8SEmmanuel Vadot 	break;
4027113afc8SEmmanuel Vadot 	case 28:
4037113afc8SEmmanuel Vadot 	sys_op->rx_pending = value;
4047113afc8SEmmanuel Vadot 	break;
4057113afc8SEmmanuel Vadot 	case 29:
4067113afc8SEmmanuel Vadot 	sys_op->rx_mini_pending = value;
4077113afc8SEmmanuel Vadot 	break;
4087113afc8SEmmanuel Vadot 	case 30:
4097113afc8SEmmanuel Vadot 	sys_op->rx_jumbo_pending = value;
4107113afc8SEmmanuel Vadot 	break;
4117113afc8SEmmanuel Vadot 	case 31:
4127113afc8SEmmanuel Vadot 	sys_op->tx_pending = value;
4137113afc8SEmmanuel Vadot 	break;
4147113afc8SEmmanuel Vadot 	default:
4157113afc8SEmmanuel Vadot 		printf("Option error\n");
4167113afc8SEmmanuel Vadot 	}
4177113afc8SEmmanuel Vadot }
4187113afc8SEmmanuel Vadot 
4197113afc8SEmmanuel Vadot static int
4207113afc8SEmmanuel Vadot parse_generic_sysctl(struct xgbe_prv_data *pdata, char *buf,
4217113afc8SEmmanuel Vadot     struct sysctl_info *info, unsigned int n_info)
4227113afc8SEmmanuel Vadot {
4237113afc8SEmmanuel Vadot 	struct sysctl_op *sys_op = pdata->sys_op;
4247113afc8SEmmanuel Vadot 	unsigned int value;
4257113afc8SEmmanuel Vadot 	char **op, **val;
4267113afc8SEmmanuel Vadot 	int n_op = 0;
4277113afc8SEmmanuel Vadot 	int rc = 0;
4287113afc8SEmmanuel Vadot 	int i, idx;
4297113afc8SEmmanuel Vadot 
4307113afc8SEmmanuel Vadot 	op = alloc_sysctl_buffer();
4317113afc8SEmmanuel Vadot 	val = alloc_sysctl_buffer();
4327113afc8SEmmanuel Vadot 	get_val(buf, op, val, &n_op);
4337113afc8SEmmanuel Vadot 
4347113afc8SEmmanuel Vadot 	for (i = 0; i < n_op; i++) {
4357113afc8SEmmanuel Vadot 		for (idx = 0; idx < n_info; idx++) {
4367113afc8SEmmanuel Vadot 			if (strcmp(info[idx].name, op[i]) == 0) {
4377113afc8SEmmanuel Vadot 				if (strcmp(info[idx].support,
4387113afc8SEmmanuel Vadot 				    "not-supported") == 0){
4397113afc8SEmmanuel Vadot 					axgbe_printf(1, "ignoring not-supported "
4407113afc8SEmmanuel Vadot 					    "option \"%s\"\n", info[idx].name);
4417113afc8SEmmanuel Vadot 					break;
4427113afc8SEmmanuel Vadot 				}
4437113afc8SEmmanuel Vadot 				switch(info[idx].type) {
4447113afc8SEmmanuel Vadot 				case SYSL_BOOL: {
4457113afc8SEmmanuel Vadot 					if (!strcmp(val[i], "on"))
4467113afc8SEmmanuel Vadot 						fill_data(sys_op,
4477113afc8SEmmanuel Vadot 						    info[idx].flag, 1);
4487113afc8SEmmanuel Vadot 					else if (!strcmp(val[i], "off"))
4497113afc8SEmmanuel Vadot 						fill_data(sys_op,
4507113afc8SEmmanuel Vadot 						    info[idx].flag, 0);
4517113afc8SEmmanuel Vadot 					else
4527113afc8SEmmanuel Vadot 						rc = exit_bad_op();
4537113afc8SEmmanuel Vadot 					break;
4547113afc8SEmmanuel Vadot 				}
4557113afc8SEmmanuel Vadot 				case SYSL_S32:
4567113afc8SEmmanuel Vadot 					sscanf(val[i], "%u", &value);
4577113afc8SEmmanuel Vadot 					fill_data(sys_op, info[idx].flag, value);
4587113afc8SEmmanuel Vadot 					break;
4597113afc8SEmmanuel Vadot 				case SYSL_U8:
4607113afc8SEmmanuel Vadot 					if (!strcmp(val[i], "half"))
4617113afc8SEmmanuel Vadot 						fill_data(sys_op,
4627113afc8SEmmanuel Vadot 						    info[idx].flag, DUPLEX_HALF);
4637113afc8SEmmanuel Vadot 					else if (!strcmp(val[i], "full"))
4647113afc8SEmmanuel Vadot 						fill_data(sys_op,
4657113afc8SEmmanuel Vadot 						    info[idx].flag, DUPLEX_FULL);
4667113afc8SEmmanuel Vadot 					else
4677113afc8SEmmanuel Vadot 						exit_bad_op();
4687113afc8SEmmanuel Vadot 				default:
4697113afc8SEmmanuel Vadot 					rc = exit_bad_op();
4707113afc8SEmmanuel Vadot 				}
4717113afc8SEmmanuel Vadot 			}
4727113afc8SEmmanuel Vadot 		}
4737113afc8SEmmanuel Vadot 	}
4747113afc8SEmmanuel Vadot 
4757113afc8SEmmanuel Vadot 	for(i = 0; i < 32; i++)
4767113afc8SEmmanuel Vadot 		free(op[i], M_AXGBE);
4777113afc8SEmmanuel Vadot 	free(op, M_AXGBE);
4787113afc8SEmmanuel Vadot 
4797113afc8SEmmanuel Vadot 	for(i = 0; i < 32; i++)
4807113afc8SEmmanuel Vadot 		free(val[i], M_AXGBE);
4817113afc8SEmmanuel Vadot 	free(val, M_AXGBE);
4827113afc8SEmmanuel Vadot 	return (rc);
4837113afc8SEmmanuel Vadot }
4847113afc8SEmmanuel Vadot 
4857113afc8SEmmanuel Vadot 
4867113afc8SEmmanuel Vadot static int
4877113afc8SEmmanuel Vadot sysctl_xgmac_reg_addr_handler(SYSCTL_HANDLER_ARGS)
4887113afc8SEmmanuel Vadot {
4897113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
4907113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
4917113afc8SEmmanuel Vadot 	char buf[buf_size];
4927113afc8SEmmanuel Vadot 	struct sbuf *sb;
4937113afc8SEmmanuel Vadot 	unsigned int reg;
4947113afc8SEmmanuel Vadot 	int rc = 0;
4957113afc8SEmmanuel Vadot 
4967113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
4977113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
4987113afc8SEmmanuel Vadot 		if (sb == NULL) {
499ce0a9d7cSWarner Losh 			rc = ENOMEM;
5007113afc8SEmmanuel Vadot 			return (rc);
5017113afc8SEmmanuel Vadot 		}
5027113afc8SEmmanuel Vadot 
5037113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: sysctl_xgmac_reg: 0x%x\n",  __func__,
5047113afc8SEmmanuel Vadot 		    pdata->sysctl_xgmac_reg);
5057113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXGMAC reg_addr:	0x%x\n",
5067113afc8SEmmanuel Vadot 		    pdata->sysctl_xgmac_reg);
5077113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
5087113afc8SEmmanuel Vadot 		sbuf_delete(sb);
5097113afc8SEmmanuel Vadot 		return (rc);
5107113afc8SEmmanuel Vadot 	}
5117113afc8SEmmanuel Vadot 
5127113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
5137113afc8SEmmanuel Vadot 	if (rc == 0) {
5147113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &reg);
5157113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
5167113afc8SEmmanuel Vadot 		pdata->sysctl_xgmac_reg = reg;
5177113afc8SEmmanuel Vadot 	}
5187113afc8SEmmanuel Vadot 
5197113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
5207113afc8SEmmanuel Vadot 	return (rc);
5217113afc8SEmmanuel Vadot }
5227113afc8SEmmanuel Vadot 
5237113afc8SEmmanuel Vadot static int
5247113afc8SEmmanuel Vadot sysctl_get_drv_info_handler(SYSCTL_HANDLER_ARGS)
5257113afc8SEmmanuel Vadot {
5267113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
5277113afc8SEmmanuel Vadot 	struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
5287113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
5297113afc8SEmmanuel Vadot 	struct sbuf *sb;
5307113afc8SEmmanuel Vadot 	int rc = 0;
5317113afc8SEmmanuel Vadot 
5327113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
5337113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
5347113afc8SEmmanuel Vadot 		if (sb == NULL) {
535ce0a9d7cSWarner Losh 			rc = ENOMEM;
5367113afc8SEmmanuel Vadot 			return (rc);
5377113afc8SEmmanuel Vadot 		}
5387113afc8SEmmanuel Vadot 
5397113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\ndriver:	%s", XGBE_DRV_NAME);
5407113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nversion: %s", XGBE_DRV_VERSION);
5417113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nfirmware-version: %d.%d.%d",
5427113afc8SEmmanuel Vadot 		    XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
5437113afc8SEmmanuel Vadot 		    XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
5447113afc8SEmmanuel Vadot 		    XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
5457113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nbus-info: %04d:%02d:%02d",
5467113afc8SEmmanuel Vadot 		    pdata->pcie_bus, pdata->pcie_device, pdata->pcie_func);
5477113afc8SEmmanuel Vadot 
5487113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
5497113afc8SEmmanuel Vadot 		sbuf_delete(sb);
5507113afc8SEmmanuel Vadot 		return (rc);
5517113afc8SEmmanuel Vadot 	}
5527113afc8SEmmanuel Vadot 
5537113afc8SEmmanuel Vadot 	return (-EINVAL);
5547113afc8SEmmanuel Vadot }
5557113afc8SEmmanuel Vadot 
5567113afc8SEmmanuel Vadot static int
5577113afc8SEmmanuel Vadot sysctl_get_link_info_handler(SYSCTL_HANDLER_ARGS)
5587113afc8SEmmanuel Vadot {
5597113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
5607113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
5617113afc8SEmmanuel Vadot 	struct sbuf *sb;
5627113afc8SEmmanuel Vadot 	int rc = 0;
5637113afc8SEmmanuel Vadot 
5647113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
5657113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
5667113afc8SEmmanuel Vadot 		if (sb == NULL) {
567ce0a9d7cSWarner Losh 			rc = ENOMEM;
5687113afc8SEmmanuel Vadot 			return (rc);
5697113afc8SEmmanuel Vadot 		}
5707113afc8SEmmanuel Vadot 
5717113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nLink is %s", pdata->phy.link ? "Up" : "Down");
5727113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
5737113afc8SEmmanuel Vadot 		sbuf_delete(sb);
5747113afc8SEmmanuel Vadot 		return (0);
5757113afc8SEmmanuel Vadot 	}
5767113afc8SEmmanuel Vadot 
5777113afc8SEmmanuel Vadot 	return (-EINVAL);
5787113afc8SEmmanuel Vadot }
5797113afc8SEmmanuel Vadot 
5807113afc8SEmmanuel Vadot #define COALESCE_SYSCTL_INFO(__coalop)							\
5817113afc8SEmmanuel Vadot {											\
5827113afc8SEmmanuel Vadot 	{ "adaptive-rx", SYSL_BOOL, use_adaptive_rx_coalesce, "not-supported" },	\
5837113afc8SEmmanuel Vadot 	{ "adaptive-tx", SYSL_BOOL, use_adaptive_tx_coalesce, "not-supported" },	\
5847113afc8SEmmanuel Vadot 	{ "sample-interval", SYSL_S32, rate_sample_interval, "not-supported" },		\
5857113afc8SEmmanuel Vadot 	{ "stats-block-usecs", SYSL_S32, stats_block_coalesce_usecs, "not-supported" },	\
5867113afc8SEmmanuel Vadot 	{ "pkt-rate-low", SYSL_S32, pkt_rate_low, "not-supported" },	  		\
5877113afc8SEmmanuel Vadot 	{ "pkt-rate-high", SYSL_S32, pkt_rate_high, "not-supported" },	  		\
5887113afc8SEmmanuel Vadot 	{ "rx-usecs", SYSL_S32, rx_coalesce_usecs, "supported" },	  		\
5897113afc8SEmmanuel Vadot 	{ "rx-frames", SYSL_S32, rx_max_coalesced_frames, "supported" },	  	\
5907113afc8SEmmanuel Vadot 	{ "rx-usecs-irq", SYSL_S32, rx_coalesce_usecs_irq, "not-supported" },	  	\
5917113afc8SEmmanuel Vadot 	{ "rx-frames-irq", SYSL_S32, rx_max_coalesced_frames_irq, "not-supported" },	\
5927113afc8SEmmanuel Vadot 	{ "tx-usecs", SYSL_S32, tx_coalesce_usecs, "not-supported" },	  		\
5937113afc8SEmmanuel Vadot 	{ "tx-frames", SYSL_S32, tx_max_coalesced_frames, "supported" },	  	\
5947113afc8SEmmanuel Vadot 	{ "tx-usecs-irq", SYSL_S32, tx_coalesce_usecs_irq, "not-supported" },	  	\
5957113afc8SEmmanuel Vadot 	{ "tx-frames-irq", SYSL_S32, tx_max_coalesced_frames_irq, "not-supported" },	\
5967113afc8SEmmanuel Vadot 	{ "rx-usecs-low", SYSL_S32, rx_coalesce_usecs_low, "not-supported" },	  	\
5977113afc8SEmmanuel Vadot 	{ "rx-frames-low", SYSL_S32, rx_max_coalesced_frames_low, "not-supported"},	\
5987113afc8SEmmanuel Vadot 	{ "tx-usecs-low", SYSL_S32, tx_coalesce_usecs_low, "not-supported" },	  	\
5997113afc8SEmmanuel Vadot 	{ "tx-frames-low", SYSL_S32, tx_max_coalesced_frames_low, "not-supported" },	\
6007113afc8SEmmanuel Vadot 	{ "rx-usecs-high", SYSL_S32, rx_coalesce_usecs_high, "not-supported" },	  	\
6017113afc8SEmmanuel Vadot 	{ "rx-frames-high", SYSL_S32, rx_max_coalesced_frames_high, "not-supported" },	\
6027113afc8SEmmanuel Vadot 	{ "tx-usecs-high", SYSL_S32, tx_coalesce_usecs_high, "not-supported" },	  	\
6037113afc8SEmmanuel Vadot 	{ "tx-frames-high", SYSL_S32, tx_max_coalesced_frames_high, "not-supported" },	\
6047113afc8SEmmanuel Vadot }
6057113afc8SEmmanuel Vadot 
6067113afc8SEmmanuel Vadot static int
6077113afc8SEmmanuel Vadot sysctl_coalesce_handler(SYSCTL_HANDLER_ARGS)
6087113afc8SEmmanuel Vadot {
6097113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
6107113afc8SEmmanuel Vadot 	struct xgbe_hw_if *hw_if = &pdata->hw_if;
6117113afc8SEmmanuel Vadot 	struct sysctl_op *sys_op = pdata->sys_op;
6127113afc8SEmmanuel Vadot 	struct sysctl_info sysctl_coalesce[] = COALESCE_SYSCTL_INFO(coalop);
6137113afc8SEmmanuel Vadot 	unsigned int rx_frames, rx_riwt, rx_usecs;
6147113afc8SEmmanuel Vadot 	unsigned int tx_frames;
6157113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
6167113afc8SEmmanuel Vadot 	char buf[buf_size];
6177113afc8SEmmanuel Vadot 	struct sbuf *sb;
6187113afc8SEmmanuel Vadot 	int rc = 0;
6197113afc8SEmmanuel Vadot 
6207113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
6217113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
6227113afc8SEmmanuel Vadot 		if (sb == NULL) {
623ce0a9d7cSWarner Losh 			rc = ENOMEM;
6247113afc8SEmmanuel Vadot 			return (rc);
6257113afc8SEmmanuel Vadot 		}
6267113afc8SEmmanuel Vadot 		sys_op->rx_coalesce_usecs = pdata->rx_usecs;
6277113afc8SEmmanuel Vadot 		sys_op->rx_max_coalesced_frames = pdata->rx_frames;
6287113afc8SEmmanuel Vadot 		sys_op->tx_max_coalesced_frames = pdata->tx_frames;
6297113afc8SEmmanuel Vadot 
6307113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nAdaptive RX: %s  TX: %s\n",
6317113afc8SEmmanuel Vadot 		    sys_op->use_adaptive_rx_coalesce ? "on" : "off",
6327113afc8SEmmanuel Vadot 		    sys_op->use_adaptive_tx_coalesce ? "on" : "off");
6337113afc8SEmmanuel Vadot 
6347113afc8SEmmanuel Vadot 		sbuf_printf(sb, "stats-block-usecs: %u\n"
6357113afc8SEmmanuel Vadot 		    "sample-interval: %u\n"
6367113afc8SEmmanuel Vadot 		    "pkt-rate-low: %u\n"
6377113afc8SEmmanuel Vadot 		    "pkt-rate-high: %u\n"
6387113afc8SEmmanuel Vadot 		    "\n"
6397113afc8SEmmanuel Vadot 		    "rx-usecs: %u\n"
6407113afc8SEmmanuel Vadot 		    "rx-frames: %u\n"
6417113afc8SEmmanuel Vadot 		    "rx-usecs-irq: %u\n"
6427113afc8SEmmanuel Vadot 		    "rx-frames-irq: %u\n"
6437113afc8SEmmanuel Vadot 		    "\n"
6447113afc8SEmmanuel Vadot 		    "tx-usecs: %u\n"
6457113afc8SEmmanuel Vadot 		    "tx-frames: %u\n"
6467113afc8SEmmanuel Vadot 		    "tx-usecs-irq: %u\n"
6477113afc8SEmmanuel Vadot 		    "tx-frames-irq: %u\n"
6487113afc8SEmmanuel Vadot 		    "\n"
6497113afc8SEmmanuel Vadot 		    "rx-usecs-low: %u\n"
6507113afc8SEmmanuel Vadot 		    "rx-frames-low: %u\n"
6517113afc8SEmmanuel Vadot 		    "tx-usecs-low: %u\n"
6527113afc8SEmmanuel Vadot 		    "tx-frames-low: %u\n"
6537113afc8SEmmanuel Vadot 		    "\n"
6547113afc8SEmmanuel Vadot 		    "rx-usecs-high: %u\n"
6557113afc8SEmmanuel Vadot 		    "rx-frames-high: %u\n"
6567113afc8SEmmanuel Vadot 		    "tx-usecs-high: %u\n"
6577113afc8SEmmanuel Vadot 		    "tx-frames-high: %u\n",
6587113afc8SEmmanuel Vadot 		    sys_op->stats_block_coalesce_usecs,
6597113afc8SEmmanuel Vadot 		    sys_op->rate_sample_interval,
6607113afc8SEmmanuel Vadot 		    sys_op->pkt_rate_low,
6617113afc8SEmmanuel Vadot 		    sys_op->pkt_rate_high,
6627113afc8SEmmanuel Vadot 
6637113afc8SEmmanuel Vadot 		    sys_op->rx_coalesce_usecs,
6647113afc8SEmmanuel Vadot 		    sys_op->rx_max_coalesced_frames,
6657113afc8SEmmanuel Vadot 		    sys_op->rx_coalesce_usecs_irq,
6667113afc8SEmmanuel Vadot 		    sys_op->rx_max_coalesced_frames_irq,
6677113afc8SEmmanuel Vadot 
6687113afc8SEmmanuel Vadot 		    sys_op->tx_coalesce_usecs,
6697113afc8SEmmanuel Vadot 		    sys_op->tx_max_coalesced_frames,
6707113afc8SEmmanuel Vadot 		    sys_op->tx_coalesce_usecs_irq,
6717113afc8SEmmanuel Vadot 		    sys_op->tx_max_coalesced_frames_irq,
6727113afc8SEmmanuel Vadot 
6737113afc8SEmmanuel Vadot 		    sys_op->rx_coalesce_usecs_low,
6747113afc8SEmmanuel Vadot 		    sys_op->rx_max_coalesced_frames_low,
6757113afc8SEmmanuel Vadot 		    sys_op->tx_coalesce_usecs_low,
6767113afc8SEmmanuel Vadot 		    sys_op->tx_max_coalesced_frames_low,
6777113afc8SEmmanuel Vadot 
6787113afc8SEmmanuel Vadot 		    sys_op->rx_coalesce_usecs_high,
6797113afc8SEmmanuel Vadot 		    sys_op->rx_max_coalesced_frames_high,
6807113afc8SEmmanuel Vadot 		    sys_op->tx_coalesce_usecs_high,
6817113afc8SEmmanuel Vadot 		    sys_op->tx_max_coalesced_frames_high);
6827113afc8SEmmanuel Vadot 
6837113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
6847113afc8SEmmanuel Vadot 		sbuf_delete(sb);
6857113afc8SEmmanuel Vadot 		return (0);
6867113afc8SEmmanuel Vadot 	}
6877113afc8SEmmanuel Vadot 
6887113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
6897113afc8SEmmanuel Vadot 	if (rc == 0) {
6907113afc8SEmmanuel Vadot 		parse_generic_sysctl(pdata, buf, sysctl_coalesce,
6917113afc8SEmmanuel Vadot 		    ARRAY_SIZE(sysctl_coalesce));
6927113afc8SEmmanuel Vadot 
6937113afc8SEmmanuel Vadot 		rx_riwt = hw_if->usec_to_riwt(pdata, sys_op->rx_coalesce_usecs);
6947113afc8SEmmanuel Vadot 		rx_usecs = sys_op->rx_coalesce_usecs;
6957113afc8SEmmanuel Vadot 		rx_frames = sys_op->rx_max_coalesced_frames;
6967113afc8SEmmanuel Vadot 
6977113afc8SEmmanuel Vadot 		/* Use smallest possible value if conversion resulted in zero */
6987113afc8SEmmanuel Vadot 		if (rx_usecs && !rx_riwt)
6997113afc8SEmmanuel Vadot 			rx_riwt = 1;
7007113afc8SEmmanuel Vadot 
7017113afc8SEmmanuel Vadot 		/* Check the bounds of values for Rx */
7027113afc8SEmmanuel Vadot 		if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
7037113afc8SEmmanuel Vadot 			axgbe_printf(2, "rx-usec is limited to %d usecs\n",
7047113afc8SEmmanuel Vadot 			    hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
7057113afc8SEmmanuel Vadot 			return (-EINVAL);
7067113afc8SEmmanuel Vadot 		}
7077113afc8SEmmanuel Vadot 		if (rx_frames > pdata->rx_desc_count) {
7087113afc8SEmmanuel Vadot 			axgbe_printf(2, "rx-frames is limited to %d frames\n",
7097113afc8SEmmanuel Vadot 			    pdata->rx_desc_count);
7107113afc8SEmmanuel Vadot 			return (-EINVAL);
7117113afc8SEmmanuel Vadot 		}
7127113afc8SEmmanuel Vadot 
7137113afc8SEmmanuel Vadot 		tx_frames = sys_op->tx_max_coalesced_frames;
7147113afc8SEmmanuel Vadot 
7157113afc8SEmmanuel Vadot 		/* Check the bounds of values for Tx */
7167113afc8SEmmanuel Vadot 		if (tx_frames > pdata->tx_desc_count) {
7177113afc8SEmmanuel Vadot 			axgbe_printf(2, "tx-frames is limited to %d frames\n",
7187113afc8SEmmanuel Vadot 			    pdata->tx_desc_count);
7197113afc8SEmmanuel Vadot 			return (-EINVAL);
7207113afc8SEmmanuel Vadot 		}
7217113afc8SEmmanuel Vadot 
7227113afc8SEmmanuel Vadot 		pdata->rx_riwt = rx_riwt;
7237113afc8SEmmanuel Vadot 		pdata->rx_usecs = rx_usecs;
7247113afc8SEmmanuel Vadot 		pdata->rx_frames = rx_frames;
7257113afc8SEmmanuel Vadot 		hw_if->config_rx_coalesce(pdata);
7267113afc8SEmmanuel Vadot 
7277113afc8SEmmanuel Vadot 		pdata->tx_frames = tx_frames;
7287113afc8SEmmanuel Vadot 		hw_if->config_tx_coalesce(pdata);
7297113afc8SEmmanuel Vadot 	}
7307113afc8SEmmanuel Vadot 
7317113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
7327113afc8SEmmanuel Vadot 
7337113afc8SEmmanuel Vadot 	return (rc);
7347113afc8SEmmanuel Vadot }
7357113afc8SEmmanuel Vadot 
7367113afc8SEmmanuel Vadot static int
7377113afc8SEmmanuel Vadot sysctl_pauseparam_handler(SYSCTL_HANDLER_ARGS)
7387113afc8SEmmanuel Vadot {
7397113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
7407113afc8SEmmanuel Vadot 	struct sysctl_op *sys_op = pdata->sys_op;
7417113afc8SEmmanuel Vadot 	struct sysctl_info sysctl_pauseparam[] = {
7427113afc8SEmmanuel Vadot 		{ "autoneg", SYSL_BOOL, autoneg, "supported" },
7437113afc8SEmmanuel Vadot 		{ "rx", SYSL_BOOL, rx_pause, "supported" },
7447113afc8SEmmanuel Vadot 		{ "tx", SYSL_BOOL, tx_pause, "supported" },
7457113afc8SEmmanuel Vadot 	};
7467113afc8SEmmanuel Vadot 	ssize_t buf_size = 512;
7477113afc8SEmmanuel Vadot 	char buf[buf_size];
7487113afc8SEmmanuel Vadot 	struct sbuf *sb;
7497113afc8SEmmanuel Vadot 	int rc = 0;
7507113afc8SEmmanuel Vadot 
7517113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
7527113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
7537113afc8SEmmanuel Vadot 		if (sb == NULL) {
754ce0a9d7cSWarner Losh 			rc = ENOMEM;
7557113afc8SEmmanuel Vadot 			return (rc);
7567113afc8SEmmanuel Vadot 		}
7577113afc8SEmmanuel Vadot 		sys_op->autoneg = pdata->phy.pause_autoneg;
7587113afc8SEmmanuel Vadot 		sys_op->tx_pause = pdata->phy.tx_pause;
7597113afc8SEmmanuel Vadot 		sys_op->rx_pause = pdata->phy.rx_pause;
7607113afc8SEmmanuel Vadot 
7617113afc8SEmmanuel Vadot 		sbuf_printf(sb,
7627113afc8SEmmanuel Vadot 		    "\nAutonegotiate:	%s\n"
7637113afc8SEmmanuel Vadot 		    "RX:		%s\n"
7647113afc8SEmmanuel Vadot 		    "TX:		%s\n",
7657113afc8SEmmanuel Vadot 		    sys_op->autoneg ? "on" : "off",
7667113afc8SEmmanuel Vadot 		    sys_op->rx_pause ? "on" : "off",
7677113afc8SEmmanuel Vadot 		    sys_op->tx_pause ? "on" : "off");
7687113afc8SEmmanuel Vadot 
7697113afc8SEmmanuel Vadot 		if (pdata->phy.lp_advertising) {
7707113afc8SEmmanuel Vadot 			int an_rx = 0, an_tx = 0;
7717113afc8SEmmanuel Vadot 
7727113afc8SEmmanuel Vadot 			if (pdata->phy.advertising & pdata->phy.lp_advertising &
7737113afc8SEmmanuel Vadot 			    ADVERTISED_Pause) {
7747113afc8SEmmanuel Vadot 				an_tx = 1;
7757113afc8SEmmanuel Vadot 				an_rx = 1;
7767113afc8SEmmanuel Vadot 			} else if (pdata->phy.advertising &
7777113afc8SEmmanuel Vadot 			    pdata->phy.lp_advertising & ADVERTISED_Asym_Pause) {
7787113afc8SEmmanuel Vadot 				if (pdata->phy.advertising & ADVERTISED_Pause)
7797113afc8SEmmanuel Vadot 					an_rx = 1;
7807113afc8SEmmanuel Vadot 				else if (pdata->phy.lp_advertising &
7817113afc8SEmmanuel Vadot 				    ADVERTISED_Pause)
7827113afc8SEmmanuel Vadot 				an_tx = 1;
7837113afc8SEmmanuel Vadot 			}
7847113afc8SEmmanuel Vadot 			sbuf_printf(sb,
7857113afc8SEmmanuel Vadot 			    "\n->\nRX negotiated:	%s\n"
7867113afc8SEmmanuel Vadot 			    "TX negotiated:	%s\n",
7877113afc8SEmmanuel Vadot 			    an_rx ? "on" : "off",
7887113afc8SEmmanuel Vadot 			    an_tx ? "on" : "off");
7897113afc8SEmmanuel Vadot 		}
7907113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
7917113afc8SEmmanuel Vadot 		sbuf_delete(sb);
7927113afc8SEmmanuel Vadot 		return (0);
7937113afc8SEmmanuel Vadot 	}
7947113afc8SEmmanuel Vadot 
7957113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
7967113afc8SEmmanuel Vadot 	if (rc == 0) {
7977113afc8SEmmanuel Vadot 		parse_generic_sysctl(pdata, buf, sysctl_pauseparam,
7987113afc8SEmmanuel Vadot 		    ARRAY_SIZE(sysctl_pauseparam));
7997113afc8SEmmanuel Vadot 
8007113afc8SEmmanuel Vadot 		if (sys_op->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE)) {
8017113afc8SEmmanuel Vadot 			axgbe_error("autoneg disabled, pause autoneg not available\n");
8027113afc8SEmmanuel Vadot 			return (-EINVAL);
8037113afc8SEmmanuel Vadot 		}
8047113afc8SEmmanuel Vadot 
8057113afc8SEmmanuel Vadot 		pdata->phy.pause_autoneg = sys_op->autoneg;
8067113afc8SEmmanuel Vadot 		pdata->phy.tx_pause = sys_op->tx_pause;
8077113afc8SEmmanuel Vadot 		pdata->phy.rx_pause = sys_op->rx_pause;
8087113afc8SEmmanuel Vadot 
8097113afc8SEmmanuel Vadot 		XGBE_CLR_ADV(&pdata->phy, Pause);
8107113afc8SEmmanuel Vadot 		XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
8117113afc8SEmmanuel Vadot 
8127113afc8SEmmanuel Vadot 		if (sys_op->rx_pause) {
8137113afc8SEmmanuel Vadot 			XGBE_SET_ADV(&pdata->phy, Pause);
8147113afc8SEmmanuel Vadot 			XGBE_SET_ADV(&pdata->phy, Asym_Pause);
8157113afc8SEmmanuel Vadot 		}
8167113afc8SEmmanuel Vadot 
8177113afc8SEmmanuel Vadot 		if (sys_op->tx_pause) {
8187113afc8SEmmanuel Vadot 			/* Equivalent to XOR of Asym_Pause */
8197113afc8SEmmanuel Vadot 			if (XGBE_ADV(&pdata->phy, Asym_Pause))
8207113afc8SEmmanuel Vadot 				XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
8217113afc8SEmmanuel Vadot 			else
8227113afc8SEmmanuel Vadot 				XGBE_SET_ADV(&pdata->phy, Asym_Pause);
8237113afc8SEmmanuel Vadot 		}
8247113afc8SEmmanuel Vadot 
8257113afc8SEmmanuel Vadot 		if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
8267113afc8SEmmanuel Vadot 			rc = pdata->phy_if.phy_config_aneg(pdata);
8277113afc8SEmmanuel Vadot 
8287113afc8SEmmanuel Vadot 	}
8297113afc8SEmmanuel Vadot 
8307113afc8SEmmanuel Vadot 	return (rc);
8317113afc8SEmmanuel Vadot }
8327113afc8SEmmanuel Vadot 
8337113afc8SEmmanuel Vadot static int
8347113afc8SEmmanuel Vadot sysctl_link_ksettings_handler(SYSCTL_HANDLER_ARGS)
8357113afc8SEmmanuel Vadot {
8367113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
8377113afc8SEmmanuel Vadot 	struct sysctl_op *sys_op = pdata->sys_op;
8387113afc8SEmmanuel Vadot 	struct sysctl_info sysctl_linksettings[] = {
8397113afc8SEmmanuel Vadot 		{ "autoneg", SYSL_BOOL, autoneg, "supported" },
8407113afc8SEmmanuel Vadot 		{ "speed", SYSL_U32, speed, "supported" },
8417113afc8SEmmanuel Vadot 		{ "duplex", SYSL_U8, duplex, "supported" },
8427113afc8SEmmanuel Vadot 	};
8437113afc8SEmmanuel Vadot 	ssize_t buf_size = 512;
8447113afc8SEmmanuel Vadot 	char buf[buf_size], link_modes[16], speed_modes[16];
8457113afc8SEmmanuel Vadot 	struct sbuf *sb;
8467113afc8SEmmanuel Vadot 	uint32_t speed;
8477113afc8SEmmanuel Vadot 	int rc = 0;
8487113afc8SEmmanuel Vadot 
8497113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
8507113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
8517113afc8SEmmanuel Vadot 		if (sb == NULL) {
852ce0a9d7cSWarner Losh 			rc = ENOMEM;
8537113afc8SEmmanuel Vadot 			return (rc);
8547113afc8SEmmanuel Vadot 		}
8557113afc8SEmmanuel Vadot 		sys_op->autoneg = pdata->phy.autoneg;
8567113afc8SEmmanuel Vadot 		sys_op->speed = pdata->phy.speed;
8577113afc8SEmmanuel Vadot 		sys_op->duplex = pdata->phy.duplex;
8587113afc8SEmmanuel Vadot 
8597113afc8SEmmanuel Vadot 		XGBE_LM_COPY(&pdata->phy, supported, &pdata->phy, supported);
8607113afc8SEmmanuel Vadot 		XGBE_LM_COPY(&pdata->phy, advertising, &pdata->phy, advertising);
8617113afc8SEmmanuel Vadot 		XGBE_LM_COPY(&pdata->phy, lp_advertising, &pdata->phy, lp_advertising);
8627113afc8SEmmanuel Vadot 
8637113afc8SEmmanuel Vadot 		switch (sys_op->speed) {
8647113afc8SEmmanuel Vadot 		case 1:
8657113afc8SEmmanuel Vadot 			strcpy(link_modes, "Unknown");
8667113afc8SEmmanuel Vadot 			strcpy(speed_modes, "Unknown");
8677113afc8SEmmanuel Vadot 			break;
8687113afc8SEmmanuel Vadot 		case 2:
8697113afc8SEmmanuel Vadot 			strcpy(link_modes, "10Gbps/Full");
8707113afc8SEmmanuel Vadot 			strcpy(speed_modes, "10000");
8717113afc8SEmmanuel Vadot 			break;
8727113afc8SEmmanuel Vadot 		case 3:
8737113afc8SEmmanuel Vadot 			strcpy(link_modes, "2.5Gbps/Full");
8747113afc8SEmmanuel Vadot 			strcpy(speed_modes, "2500");
8757113afc8SEmmanuel Vadot 			break;
8767113afc8SEmmanuel Vadot 		case 4:
8777113afc8SEmmanuel Vadot 			strcpy(link_modes, "1Gbps/Full");
8787113afc8SEmmanuel Vadot 			strcpy(speed_modes, "1000");
8797113afc8SEmmanuel Vadot 			break;
8807113afc8SEmmanuel Vadot 		case 5:
8817113afc8SEmmanuel Vadot 			strcpy(link_modes, "100Mbps/Full");
8827113afc8SEmmanuel Vadot 			strcpy(speed_modes, "100");
8837113afc8SEmmanuel Vadot 			break;
8847113afc8SEmmanuel Vadot 		case 6:
8857113afc8SEmmanuel Vadot 			strcpy(link_modes, "10Mbps/Full");
8867113afc8SEmmanuel Vadot 			strcpy(speed_modes, "10");
8877113afc8SEmmanuel Vadot 			break;
8887113afc8SEmmanuel Vadot 		}
8897113afc8SEmmanuel Vadot 
8907113afc8SEmmanuel Vadot 		sbuf_printf(sb,
8917113afc8SEmmanuel Vadot 		    "\nlink_modes: %s\n"
8927113afc8SEmmanuel Vadot 		    "autonegotiation: %s\n"
8937113afc8SEmmanuel Vadot 		    "speed: %sMbps\n",
8947113afc8SEmmanuel Vadot 		    link_modes,
8957113afc8SEmmanuel Vadot 		    (sys_op->autoneg == AUTONEG_DISABLE) ? "off" : "on",
8967113afc8SEmmanuel Vadot 		    speed_modes);
8977113afc8SEmmanuel Vadot 
8987113afc8SEmmanuel Vadot 		switch (sys_op->duplex) {
8997113afc8SEmmanuel Vadot 			case DUPLEX_HALF:
9007113afc8SEmmanuel Vadot 				sbuf_printf(sb, "Duplex: Half\n");
9017113afc8SEmmanuel Vadot 				break;
9027113afc8SEmmanuel Vadot 			case DUPLEX_FULL:
9037113afc8SEmmanuel Vadot 				sbuf_printf(sb, "Duplex: Full\n");
9047113afc8SEmmanuel Vadot 				break;
9057113afc8SEmmanuel Vadot 			default:
9067113afc8SEmmanuel Vadot 				sbuf_printf(sb, "Duplex: Unknown\n");
9077113afc8SEmmanuel Vadot 				break;
9087113afc8SEmmanuel Vadot 		}
9097113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
9107113afc8SEmmanuel Vadot 		sbuf_delete(sb);
9117113afc8SEmmanuel Vadot 		return (0);
9127113afc8SEmmanuel Vadot 	}
9137113afc8SEmmanuel Vadot 
9147113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
9157113afc8SEmmanuel Vadot 	if (rc == 0) {
9167113afc8SEmmanuel Vadot 		parse_generic_sysctl(pdata, buf, sysctl_linksettings,
9177113afc8SEmmanuel Vadot 		    ARRAY_SIZE(sysctl_linksettings));
9187113afc8SEmmanuel Vadot 
9197113afc8SEmmanuel Vadot 		speed = sys_op->speed;
9207113afc8SEmmanuel Vadot 
9217113afc8SEmmanuel Vadot 		if ((sys_op->autoneg != AUTONEG_ENABLE) &&
9227113afc8SEmmanuel Vadot 		    (sys_op->autoneg != AUTONEG_DISABLE)) {
9237113afc8SEmmanuel Vadot 			axgbe_error("unsupported autoneg %hhu\n",
9247113afc8SEmmanuel Vadot 			    (unsigned char)sys_op->autoneg);
9257113afc8SEmmanuel Vadot 			return (-EINVAL);
9267113afc8SEmmanuel Vadot 		}
9277113afc8SEmmanuel Vadot 
9287113afc8SEmmanuel Vadot 		if (sys_op->autoneg == AUTONEG_DISABLE) {
9297113afc8SEmmanuel Vadot 			if (!pdata->phy_if.phy_valid_speed(pdata, speed)) {
9307113afc8SEmmanuel Vadot 				axgbe_error("unsupported speed %u\n", speed);
9317113afc8SEmmanuel Vadot 				return (-EINVAL);
9327113afc8SEmmanuel Vadot 			}
9337113afc8SEmmanuel Vadot 
9347113afc8SEmmanuel Vadot 			if (sys_op->duplex != DUPLEX_FULL) {
9357113afc8SEmmanuel Vadot 				axgbe_error("unsupported duplex %hhu\n",
9367113afc8SEmmanuel Vadot 				    (unsigned char)sys_op->duplex);
9377113afc8SEmmanuel Vadot 				return (-EINVAL);
9387113afc8SEmmanuel Vadot 			}
9397113afc8SEmmanuel Vadot 		}
9407113afc8SEmmanuel Vadot 
9417113afc8SEmmanuel Vadot 		pdata->phy.autoneg = sys_op->autoneg;
9427113afc8SEmmanuel Vadot 		pdata->phy.speed = speed;
9437113afc8SEmmanuel Vadot 		pdata->phy.duplex = sys_op->duplex;
9447113afc8SEmmanuel Vadot 
9457113afc8SEmmanuel Vadot 		if (sys_op->autoneg == AUTONEG_ENABLE)
9467113afc8SEmmanuel Vadot 			XGBE_SET_ADV(&pdata->phy, Autoneg);
9477113afc8SEmmanuel Vadot 		else
9487113afc8SEmmanuel Vadot 			XGBE_CLR_ADV(&pdata->phy, Autoneg);
9497113afc8SEmmanuel Vadot 
9507113afc8SEmmanuel Vadot 		if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
9517113afc8SEmmanuel Vadot 			rc = pdata->phy_if.phy_config_aneg(pdata);
9527113afc8SEmmanuel Vadot 	}
9537113afc8SEmmanuel Vadot 
9547113afc8SEmmanuel Vadot 	return (rc);
9557113afc8SEmmanuel Vadot }
9567113afc8SEmmanuel Vadot 
9577113afc8SEmmanuel Vadot static int
9587113afc8SEmmanuel Vadot sysctl_ringparam_handler(SYSCTL_HANDLER_ARGS)
9597113afc8SEmmanuel Vadot {
9607113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
9617113afc8SEmmanuel Vadot 	struct sysctl_op *sys_op = pdata->sys_op;
9627113afc8SEmmanuel Vadot 	struct sysctl_info sysctl_ringparam[] = {
9637113afc8SEmmanuel Vadot 		{ "rx", SYSL_S32, rx_pending, "supported" },
9647113afc8SEmmanuel Vadot 		{ "rx-mini", SYSL_S32, rx_mini_pending, "supported" },
9657113afc8SEmmanuel Vadot 		{ "rx-jumbo", SYSL_S32, rx_jumbo_pending, "supported" },
9667113afc8SEmmanuel Vadot 		{ "tx", SYSL_S32, tx_pending, "supported" },
9677113afc8SEmmanuel Vadot 	};
9687113afc8SEmmanuel Vadot 	ssize_t buf_size = 512;
9697113afc8SEmmanuel Vadot 	unsigned int rx, tx;
9707113afc8SEmmanuel Vadot 	char buf[buf_size];
9717113afc8SEmmanuel Vadot 	struct sbuf *sb;
9727113afc8SEmmanuel Vadot 	int rc = 0;
9737113afc8SEmmanuel Vadot 
9747113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
9757113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
9767113afc8SEmmanuel Vadot 		if (sb == NULL) {
977ce0a9d7cSWarner Losh 			rc = ENOMEM;
9787113afc8SEmmanuel Vadot 			return (rc);
9797113afc8SEmmanuel Vadot 		}
9807113afc8SEmmanuel Vadot 		sys_op->rx_max_pending = XGBE_RX_DESC_CNT_MAX;
9817113afc8SEmmanuel Vadot 		sys_op->tx_max_pending = XGBE_TX_DESC_CNT_MAX;
9827113afc8SEmmanuel Vadot 		sys_op->rx_pending = pdata->rx_desc_count;
9837113afc8SEmmanuel Vadot 		sys_op->tx_pending = pdata->tx_desc_count;
9847113afc8SEmmanuel Vadot 
9857113afc8SEmmanuel Vadot 		sbuf_printf(sb,
9867113afc8SEmmanuel Vadot 		    "\nPre-set maximums:\n"
9877113afc8SEmmanuel Vadot 		    "RX:		%u\n"
9887113afc8SEmmanuel Vadot 		    "RX Mini:	%u\n"
9897113afc8SEmmanuel Vadot 		    "RX Jumbo:	%u\n"
9907113afc8SEmmanuel Vadot 		    "TX:		%u\n",
9917113afc8SEmmanuel Vadot 		    sys_op->rx_max_pending,
9927113afc8SEmmanuel Vadot 		    sys_op->rx_mini_max_pending,
9937113afc8SEmmanuel Vadot 		    sys_op->rx_jumbo_max_pending,
9947113afc8SEmmanuel Vadot 		    sys_op->tx_max_pending);
9957113afc8SEmmanuel Vadot 
9967113afc8SEmmanuel Vadot 		sbuf_printf(sb,
9977113afc8SEmmanuel Vadot 		    "\nCurrent hardware settings:\n"
9987113afc8SEmmanuel Vadot 		    "RX:		%u\n"
9997113afc8SEmmanuel Vadot 		    "RX Mini:	%u\n"
10007113afc8SEmmanuel Vadot 		    "RX Jumbo:	%u\n"
10017113afc8SEmmanuel Vadot 		    "TX:		%u\n",
10027113afc8SEmmanuel Vadot 		    sys_op->rx_pending,
10037113afc8SEmmanuel Vadot 		    sys_op->rx_mini_pending,
10047113afc8SEmmanuel Vadot 		    sys_op->rx_jumbo_pending,
10057113afc8SEmmanuel Vadot 		    sys_op->tx_pending);
10067113afc8SEmmanuel Vadot 
10077113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
10087113afc8SEmmanuel Vadot 		sbuf_delete(sb);
10097113afc8SEmmanuel Vadot 		return (0);
10107113afc8SEmmanuel Vadot 	}
10117113afc8SEmmanuel Vadot 
10127113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
10137113afc8SEmmanuel Vadot 	if (rc == 0) {
10147113afc8SEmmanuel Vadot 		parse_generic_sysctl(pdata, buf, sysctl_ringparam,
10157113afc8SEmmanuel Vadot 		    ARRAY_SIZE(sysctl_ringparam));
10167113afc8SEmmanuel Vadot 
10177113afc8SEmmanuel Vadot 		if (sys_op->rx_mini_pending || sys_op->rx_jumbo_pending) {
10187113afc8SEmmanuel Vadot 			axgbe_error("unsupported ring parameter\n");
10197113afc8SEmmanuel Vadot 			return (-EINVAL);
10207113afc8SEmmanuel Vadot 		}
10217113afc8SEmmanuel Vadot 
10227113afc8SEmmanuel Vadot 		if ((sys_op->rx_pending < XGBE_RX_DESC_CNT_MIN) ||
10237113afc8SEmmanuel Vadot 				(sys_op->rx_pending > XGBE_RX_DESC_CNT_MAX)) {
10247113afc8SEmmanuel Vadot 			axgbe_error("rx ring param must be between %u and %u\n",
10257113afc8SEmmanuel Vadot 			    XGBE_RX_DESC_CNT_MIN, XGBE_RX_DESC_CNT_MAX);
10267113afc8SEmmanuel Vadot 			return (-EINVAL);
10277113afc8SEmmanuel Vadot 		}
10287113afc8SEmmanuel Vadot 
10297113afc8SEmmanuel Vadot 		if ((sys_op->tx_pending < XGBE_TX_DESC_CNT_MIN) ||
10307113afc8SEmmanuel Vadot 				(sys_op->tx_pending > XGBE_TX_DESC_CNT_MAX)) {
10317113afc8SEmmanuel Vadot 			axgbe_error("tx ring param must be between %u and %u\n",
10327113afc8SEmmanuel Vadot 			    XGBE_TX_DESC_CNT_MIN, XGBE_TX_DESC_CNT_MAX);
10337113afc8SEmmanuel Vadot 			return (-EINVAL);
10347113afc8SEmmanuel Vadot 		}
10357113afc8SEmmanuel Vadot 
1036*a527b9cbSDoug Moore 		rx = rounddown_pow_of_two(sys_op->rx_pending);
10377113afc8SEmmanuel Vadot 		if (rx != sys_op->rx_pending)
10387113afc8SEmmanuel Vadot 			axgbe_printf(1,	"rx ring param rounded to power of 2: %u\n",
10397113afc8SEmmanuel Vadot 			    rx);
10407113afc8SEmmanuel Vadot 
1041*a527b9cbSDoug Moore 		tx = rounddown_pow_of_two(sys_op->tx_pending);
10427113afc8SEmmanuel Vadot 		if (tx != sys_op->tx_pending)
10437113afc8SEmmanuel Vadot 			axgbe_printf(1, "tx ring param rounded to power of 2: %u\n",
10447113afc8SEmmanuel Vadot 			    tx);
10457113afc8SEmmanuel Vadot 
10467113afc8SEmmanuel Vadot 		if ((rx == pdata->rx_desc_count) &&
10477113afc8SEmmanuel Vadot 		    (tx == pdata->tx_desc_count))
10487113afc8SEmmanuel Vadot 			goto out;
10497113afc8SEmmanuel Vadot 
10507113afc8SEmmanuel Vadot 		pdata->rx_desc_count = rx;
10517113afc8SEmmanuel Vadot 		pdata->tx_desc_count = tx;
10527113afc8SEmmanuel Vadot 
10537113afc8SEmmanuel Vadot 		/* TODO - restart dev */
10547113afc8SEmmanuel Vadot 	}
10557113afc8SEmmanuel Vadot 
10567113afc8SEmmanuel Vadot out:
10577113afc8SEmmanuel Vadot 	return (0);
10587113afc8SEmmanuel Vadot }
10597113afc8SEmmanuel Vadot 
10607113afc8SEmmanuel Vadot static int
10617113afc8SEmmanuel Vadot sysctl_channels_handler(SYSCTL_HANDLER_ARGS)
10627113afc8SEmmanuel Vadot {
10637113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
10647113afc8SEmmanuel Vadot 	struct sysctl_op *sys_op = pdata->sys_op;
10657113afc8SEmmanuel Vadot 	struct sysctl_info sysctl_channels[] = {
10667113afc8SEmmanuel Vadot 		{ "rx", SYSL_S32, rx_count, "supported" },
10677113afc8SEmmanuel Vadot 		{ "tx", SYSL_S32, tx_count, "supported" },
10687113afc8SEmmanuel Vadot 		{ "other", SYSL_S32, other_count, "supported" },
10697113afc8SEmmanuel Vadot 		{ "combined", SYSL_S32, combined_count, "supported" },
10707113afc8SEmmanuel Vadot 	};
10717113afc8SEmmanuel Vadot 	unsigned int rx, tx, combined;
10727113afc8SEmmanuel Vadot 	ssize_t buf_size = 512;
10737113afc8SEmmanuel Vadot 	char buf[buf_size];
10747113afc8SEmmanuel Vadot 	struct sbuf *sb;
10757113afc8SEmmanuel Vadot 	int rc = 0;
10767113afc8SEmmanuel Vadot 
10777113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
10787113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
10797113afc8SEmmanuel Vadot 		if (sb == NULL) {
1080ce0a9d7cSWarner Losh 			rc = ENOMEM;
10817113afc8SEmmanuel Vadot 			return (rc);
10827113afc8SEmmanuel Vadot 		}
10837113afc8SEmmanuel Vadot 		rx = min(pdata->hw_feat.rx_ch_cnt, pdata->rx_max_channel_count);
10847113afc8SEmmanuel Vadot 		rx = min(rx, pdata->channel_irq_count);
10857113afc8SEmmanuel Vadot 		tx = min(pdata->hw_feat.tx_ch_cnt, pdata->tx_max_channel_count);
10867113afc8SEmmanuel Vadot 		tx = min(tx, pdata->channel_irq_count);
10877113afc8SEmmanuel Vadot 		tx = min(tx, pdata->tx_max_q_count);
10887113afc8SEmmanuel Vadot 
10897113afc8SEmmanuel Vadot 		combined = min(rx, tx);
10907113afc8SEmmanuel Vadot 
10917113afc8SEmmanuel Vadot 		sys_op->max_combined = combined;
10927113afc8SEmmanuel Vadot 		sys_op->max_rx = rx ? rx - 1 : 0;
10937113afc8SEmmanuel Vadot 		sys_op->max_tx = tx ? tx - 1 : 0;
10947113afc8SEmmanuel Vadot 
10957113afc8SEmmanuel Vadot 		/* Get current settings based on device state */
10967113afc8SEmmanuel Vadot 		rx = pdata->rx_ring_count;
10977113afc8SEmmanuel Vadot 		tx = pdata->tx_ring_count;
10987113afc8SEmmanuel Vadot 
10997113afc8SEmmanuel Vadot 		combined = min(rx, tx);
11007113afc8SEmmanuel Vadot 		rx -= combined;
11017113afc8SEmmanuel Vadot 		tx -= combined;
11027113afc8SEmmanuel Vadot 
11037113afc8SEmmanuel Vadot 		sys_op->combined_count = combined;
11047113afc8SEmmanuel Vadot 		sys_op->rx_count = rx;
11057113afc8SEmmanuel Vadot 		sys_op->tx_count = tx;
11067113afc8SEmmanuel Vadot 
11077113afc8SEmmanuel Vadot 		sbuf_printf(sb,
11087113afc8SEmmanuel Vadot 		    "\nPre-set maximums:\n"
11097113afc8SEmmanuel Vadot 		    "RX:		%u\n"
11107113afc8SEmmanuel Vadot 		    "TX:		%u\n"
11117113afc8SEmmanuel Vadot 		    "Other:		%u\n"
11127113afc8SEmmanuel Vadot 		    "Combined:	%u\n",
11137113afc8SEmmanuel Vadot 		    sys_op->max_rx, sys_op->max_tx,
11147113afc8SEmmanuel Vadot 		    sys_op->max_other,
11157113afc8SEmmanuel Vadot 		    sys_op->max_combined);
11167113afc8SEmmanuel Vadot 
11177113afc8SEmmanuel Vadot 		sbuf_printf(sb,
11187113afc8SEmmanuel Vadot 		    "\nCurrent hardware settings:\n"
11197113afc8SEmmanuel Vadot 		    "RX:		%u\n"
11207113afc8SEmmanuel Vadot 		    "TX:		%u\n"
11217113afc8SEmmanuel Vadot 		    "Other:		%u\n"
11227113afc8SEmmanuel Vadot 		    "Combined:	%u\n",
11237113afc8SEmmanuel Vadot 		    sys_op->rx_count, sys_op->tx_count,
11247113afc8SEmmanuel Vadot 		    sys_op->other_count,
11257113afc8SEmmanuel Vadot 		    sys_op->combined_count);
11267113afc8SEmmanuel Vadot 
11277113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
11287113afc8SEmmanuel Vadot 		sbuf_delete(sb);
11297113afc8SEmmanuel Vadot 		return (0);
11307113afc8SEmmanuel Vadot 	}
11317113afc8SEmmanuel Vadot 
11327113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
11337113afc8SEmmanuel Vadot 	if (rc == 0) {
11347113afc8SEmmanuel Vadot 		parse_generic_sysctl(pdata, buf, sysctl_channels,
11357113afc8SEmmanuel Vadot 		    ARRAY_SIZE(sysctl_channels));
11367113afc8SEmmanuel Vadot 
11377113afc8SEmmanuel Vadot 		axgbe_error( "channel inputs: combined=%u, rx-only=%u,"
11387113afc8SEmmanuel Vadot 		    " tx-only=%u\n", sys_op->combined_count,
11397113afc8SEmmanuel Vadot 		    sys_op->rx_count, sys_op->tx_count);
11407113afc8SEmmanuel Vadot 	}
11417113afc8SEmmanuel Vadot 
11427113afc8SEmmanuel Vadot 	return (rc);
11437113afc8SEmmanuel Vadot }
11447113afc8SEmmanuel Vadot 
11457113afc8SEmmanuel Vadot 
11467113afc8SEmmanuel Vadot static int
11477113afc8SEmmanuel Vadot sysctl_mac_stats_handler(SYSCTL_HANDLER_ARGS)
11487113afc8SEmmanuel Vadot {
11497113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
11507113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
11517113afc8SEmmanuel Vadot 	struct sbuf *sb;
11527113afc8SEmmanuel Vadot 	int rc = 0;
11537113afc8SEmmanuel Vadot 	int i;
11547113afc8SEmmanuel Vadot 
11557113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
11567113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
11577113afc8SEmmanuel Vadot 		if (sb == NULL) {
1158ce0a9d7cSWarner Losh 			rc = ENOMEM;
11597113afc8SEmmanuel Vadot 			return (rc);
11607113afc8SEmmanuel Vadot 		}
11617113afc8SEmmanuel Vadot 
11627113afc8SEmmanuel Vadot 		pdata->hw_if.read_mmc_stats(pdata);
11637113afc8SEmmanuel Vadot 		for (i = 0; i < XGBE_STATS_COUNT; i++) {
11647113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\n %s: %lu",
11657113afc8SEmmanuel Vadot 		    xgbe_gstring_stats[i].stat_string,
11667113afc8SEmmanuel Vadot 		    *(uint64_t *)((uint8_t *)pdata + xgbe_gstring_stats[i].stat_offset));
11677113afc8SEmmanuel Vadot 		}
11687113afc8SEmmanuel Vadot 		for (i = 0; i < pdata->tx_ring_count; i++) {
11697113afc8SEmmanuel Vadot 			sbuf_printf(sb,
11707113afc8SEmmanuel Vadot 			    "\n txq_packets[%d]: %lu"
11717113afc8SEmmanuel Vadot 			    "\n txq_bytes[%d]: %lu",
11727113afc8SEmmanuel Vadot 			    i, pdata->ext_stats.txq_packets[i],
11737113afc8SEmmanuel Vadot 			    i, pdata->ext_stats.txq_bytes[i]);
11747113afc8SEmmanuel Vadot 		}
11757113afc8SEmmanuel Vadot 		for (i = 0; i < pdata->rx_ring_count; i++) {
11767113afc8SEmmanuel Vadot 			sbuf_printf(sb,
11777113afc8SEmmanuel Vadot 			    "\n rxq_packets[%d]: %lu"
11787113afc8SEmmanuel Vadot 			    "\n rxq_bytes[%d]: %lu",
11797113afc8SEmmanuel Vadot 			    i, pdata->ext_stats.rxq_packets[i],
11807113afc8SEmmanuel Vadot 			    i, pdata->ext_stats.rxq_bytes[i]);
11817113afc8SEmmanuel Vadot 		}
11827113afc8SEmmanuel Vadot 
11837113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
11847113afc8SEmmanuel Vadot 		sbuf_delete(sb);
11857113afc8SEmmanuel Vadot 		return (rc);
11867113afc8SEmmanuel Vadot 	}
11877113afc8SEmmanuel Vadot 
11887113afc8SEmmanuel Vadot 	return (-EINVAL);
11897113afc8SEmmanuel Vadot }
11907113afc8SEmmanuel Vadot 
11917113afc8SEmmanuel Vadot static int
11927113afc8SEmmanuel Vadot sysctl_xgmac_reg_value_handler(SYSCTL_HANDLER_ARGS)
11937113afc8SEmmanuel Vadot {
11947113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
11957113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
11967113afc8SEmmanuel Vadot 	char buf[buf_size];
11977113afc8SEmmanuel Vadot 	unsigned int value;
11987113afc8SEmmanuel Vadot 	struct sbuf *sb;
11997113afc8SEmmanuel Vadot 	int rc = 0;
12007113afc8SEmmanuel Vadot 
12017113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
12027113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
12037113afc8SEmmanuel Vadot 		if (sb == NULL) {
1204ce0a9d7cSWarner Losh 			rc = ENOMEM;
12057113afc8SEmmanuel Vadot 			return (rc);
12067113afc8SEmmanuel Vadot 		}
12077113afc8SEmmanuel Vadot 
12087113afc8SEmmanuel Vadot 		value = XGMAC_IOREAD(pdata, pdata->sysctl_xgmac_reg);
12097113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
12107113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXGMAC reg_value:	0x%x\n", value);
12117113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
12127113afc8SEmmanuel Vadot 		sbuf_delete(sb);
12137113afc8SEmmanuel Vadot 		return (rc);
12147113afc8SEmmanuel Vadot 	}
12157113afc8SEmmanuel Vadot 
12167113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
12177113afc8SEmmanuel Vadot 	if (rc == 0) {
12187113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &value);
12197113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
12207113afc8SEmmanuel Vadot 		XGMAC_IOWRITE(pdata, pdata->sysctl_xgmac_reg, value);
12217113afc8SEmmanuel Vadot 	}
12227113afc8SEmmanuel Vadot 
12237113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
12247113afc8SEmmanuel Vadot 	return (rc);
12257113afc8SEmmanuel Vadot }
12267113afc8SEmmanuel Vadot 
12277113afc8SEmmanuel Vadot static int
12287113afc8SEmmanuel Vadot sysctl_xpcs_mmd_reg_handler(SYSCTL_HANDLER_ARGS)
12297113afc8SEmmanuel Vadot {
12307113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
12317113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
12327113afc8SEmmanuel Vadot 	char buf[buf_size];
12337113afc8SEmmanuel Vadot 	struct sbuf *sb;
12347113afc8SEmmanuel Vadot 	unsigned int reg;
12357113afc8SEmmanuel Vadot 	int rc = 0;
12367113afc8SEmmanuel Vadot 
12377113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
12387113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
12397113afc8SEmmanuel Vadot 		if (sb == NULL) {
1240ce0a9d7cSWarner Losh 			rc = ENOMEM;
12417113afc8SEmmanuel Vadot 			return (rc);
12427113afc8SEmmanuel Vadot 		}
12437113afc8SEmmanuel Vadot 
12447113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: xpcs_mmd: 0x%x\n",  __func__,
12457113afc8SEmmanuel Vadot 		    pdata->sysctl_xpcs_mmd);
12467113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXPCS mmd_reg:	0x%x\n",
12477113afc8SEmmanuel Vadot 		    pdata->sysctl_xpcs_mmd);
12487113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
12497113afc8SEmmanuel Vadot 		sbuf_delete(sb);
12507113afc8SEmmanuel Vadot 		return (rc);
12517113afc8SEmmanuel Vadot 	}
12527113afc8SEmmanuel Vadot 
12537113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
12547113afc8SEmmanuel Vadot 	if (rc == 0) {
12557113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &reg);
12567113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: mmd_reg: 0x%x\n",  __func__, reg);
12577113afc8SEmmanuel Vadot 		pdata->sysctl_xpcs_mmd = reg;
12587113afc8SEmmanuel Vadot 	}
12597113afc8SEmmanuel Vadot 
12607113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
12617113afc8SEmmanuel Vadot 	return (rc);
12627113afc8SEmmanuel Vadot }
12637113afc8SEmmanuel Vadot 
12647113afc8SEmmanuel Vadot static int
12657113afc8SEmmanuel Vadot sysctl_xpcs_reg_addr_handler(SYSCTL_HANDLER_ARGS)
12667113afc8SEmmanuel Vadot {
12677113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
12687113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
12697113afc8SEmmanuel Vadot 	char buf[buf_size];
12707113afc8SEmmanuel Vadot 	struct sbuf *sb;
12717113afc8SEmmanuel Vadot 	unsigned int reg;
12727113afc8SEmmanuel Vadot 	int rc = 0;
12737113afc8SEmmanuel Vadot 
12747113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
12757113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
12767113afc8SEmmanuel Vadot 		if (sb == NULL) {
1277ce0a9d7cSWarner Losh 			rc = ENOMEM;
12787113afc8SEmmanuel Vadot 			return (rc);
12797113afc8SEmmanuel Vadot 		}
12807113afc8SEmmanuel Vadot 
12817113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: sysctl_xpcs_reg: 0x%x\n",  __func__,
12827113afc8SEmmanuel Vadot 		    pdata->sysctl_xpcs_reg);
12837113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXPCS reg_addr:	0x%x\n",
12847113afc8SEmmanuel Vadot 		    pdata->sysctl_xpcs_reg);
12857113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
12867113afc8SEmmanuel Vadot 		sbuf_delete(sb);
12877113afc8SEmmanuel Vadot 		return (rc);
12887113afc8SEmmanuel Vadot 	}
12897113afc8SEmmanuel Vadot 
12907113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
12917113afc8SEmmanuel Vadot 	if (rc == 0) {
12927113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &reg);
12937113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
12947113afc8SEmmanuel Vadot 		pdata->sysctl_xpcs_reg = reg;
12957113afc8SEmmanuel Vadot 	}
12967113afc8SEmmanuel Vadot 
12977113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
12987113afc8SEmmanuel Vadot 	return (rc);
12997113afc8SEmmanuel Vadot }
13007113afc8SEmmanuel Vadot 
13017113afc8SEmmanuel Vadot static int
13027113afc8SEmmanuel Vadot sysctl_xpcs_reg_value_handler(SYSCTL_HANDLER_ARGS)
13037113afc8SEmmanuel Vadot {
13047113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
13057113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
13067113afc8SEmmanuel Vadot 	char buf[buf_size];
13077113afc8SEmmanuel Vadot 	unsigned int value;
13087113afc8SEmmanuel Vadot 	struct sbuf *sb;
13097113afc8SEmmanuel Vadot 	int rc = 0;
13107113afc8SEmmanuel Vadot 
13117113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
13127113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
13137113afc8SEmmanuel Vadot 		if (sb == NULL) {
1314ce0a9d7cSWarner Losh 			rc = ENOMEM;
13157113afc8SEmmanuel Vadot 			return (rc);
13167113afc8SEmmanuel Vadot 		}
13177113afc8SEmmanuel Vadot 
13187113afc8SEmmanuel Vadot 		value = XMDIO_READ(pdata, pdata->sysctl_xpcs_mmd,
13197113afc8SEmmanuel Vadot 		    pdata->sysctl_xpcs_reg);
13207113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
13217113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXPCS reg_value:	0x%x\n", value);
13227113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
13237113afc8SEmmanuel Vadot 		sbuf_delete(sb);
13247113afc8SEmmanuel Vadot 		return (rc);
13257113afc8SEmmanuel Vadot 	}
13267113afc8SEmmanuel Vadot 
13277113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
13287113afc8SEmmanuel Vadot 	if (rc == 0) {
13297113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &value);
13307113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
13317113afc8SEmmanuel Vadot 		XMDIO_WRITE(pdata, pdata->sysctl_xpcs_mmd,
13327113afc8SEmmanuel Vadot 		    pdata->sysctl_xpcs_reg, value);
13337113afc8SEmmanuel Vadot 	}
13347113afc8SEmmanuel Vadot 
13357113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
13367113afc8SEmmanuel Vadot 	return (rc);
13377113afc8SEmmanuel Vadot }
13387113afc8SEmmanuel Vadot 
13397113afc8SEmmanuel Vadot static int
13407113afc8SEmmanuel Vadot sysctl_xprop_reg_addr_handler(SYSCTL_HANDLER_ARGS)
13417113afc8SEmmanuel Vadot {
13427113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
13437113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
13447113afc8SEmmanuel Vadot 	char buf[buf_size];
13457113afc8SEmmanuel Vadot 	struct sbuf *sb;
13467113afc8SEmmanuel Vadot 	unsigned int reg;
13477113afc8SEmmanuel Vadot 	int rc = 0;
13487113afc8SEmmanuel Vadot 
13497113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
13507113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
13517113afc8SEmmanuel Vadot 		if (sb == NULL) {
1352ce0a9d7cSWarner Losh 			rc = ENOMEM;
13537113afc8SEmmanuel Vadot 			return (rc);
13547113afc8SEmmanuel Vadot 		}
13557113afc8SEmmanuel Vadot 
13567113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: sysctl_xprop_reg: 0x%x\n",  __func__,
13577113afc8SEmmanuel Vadot 		    pdata->sysctl_xprop_reg);
13587113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXPROP reg_addr:	0x%x\n",
13597113afc8SEmmanuel Vadot 		    pdata->sysctl_xprop_reg);
13607113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
13617113afc8SEmmanuel Vadot 		sbuf_delete(sb);
13627113afc8SEmmanuel Vadot 		return (rc);
13637113afc8SEmmanuel Vadot 	}
13647113afc8SEmmanuel Vadot 
13657113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
13667113afc8SEmmanuel Vadot 	if (rc == 0) {
13677113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &reg);
13687113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
13697113afc8SEmmanuel Vadot 		pdata->sysctl_xprop_reg = reg;
13707113afc8SEmmanuel Vadot 	}
13717113afc8SEmmanuel Vadot 
13727113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
13737113afc8SEmmanuel Vadot 	return (rc);
13747113afc8SEmmanuel Vadot }
13757113afc8SEmmanuel Vadot 
13767113afc8SEmmanuel Vadot static int
13777113afc8SEmmanuel Vadot sysctl_xprop_reg_value_handler(SYSCTL_HANDLER_ARGS)
13787113afc8SEmmanuel Vadot {
13797113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
13807113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
13817113afc8SEmmanuel Vadot 	char buf[buf_size];
13827113afc8SEmmanuel Vadot 	unsigned int value;
13837113afc8SEmmanuel Vadot 	struct sbuf *sb;
13847113afc8SEmmanuel Vadot 	int rc = 0;
13857113afc8SEmmanuel Vadot 
13867113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
13877113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
13887113afc8SEmmanuel Vadot 		if (sb == NULL) {
1389ce0a9d7cSWarner Losh 			rc = ENOMEM;
13907113afc8SEmmanuel Vadot 			return (rc);
13917113afc8SEmmanuel Vadot 		}
13927113afc8SEmmanuel Vadot 
13937113afc8SEmmanuel Vadot 		value = XP_IOREAD(pdata, pdata->sysctl_xprop_reg);
13947113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
13957113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXPROP reg_value:	0x%x\n", value);
13967113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
13977113afc8SEmmanuel Vadot 		sbuf_delete(sb);
13987113afc8SEmmanuel Vadot 		return (rc);
13997113afc8SEmmanuel Vadot 	}
14007113afc8SEmmanuel Vadot 
14017113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
14027113afc8SEmmanuel Vadot 	if (rc == 0) {
14037113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &value);
14047113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
14057113afc8SEmmanuel Vadot 		XP_IOWRITE(pdata, pdata->sysctl_xprop_reg, value);
14067113afc8SEmmanuel Vadot 	}
14077113afc8SEmmanuel Vadot 
14087113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
14097113afc8SEmmanuel Vadot 	return (rc);
14107113afc8SEmmanuel Vadot }
14117113afc8SEmmanuel Vadot 
14127113afc8SEmmanuel Vadot static int
14137113afc8SEmmanuel Vadot sysctl_xi2c_reg_addr_handler(SYSCTL_HANDLER_ARGS)
14147113afc8SEmmanuel Vadot {
14157113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
14167113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
14177113afc8SEmmanuel Vadot 	char buf[buf_size];
14187113afc8SEmmanuel Vadot 	struct sbuf *sb;
14197113afc8SEmmanuel Vadot 	unsigned int reg;
14207113afc8SEmmanuel Vadot 	int rc = 0;
14217113afc8SEmmanuel Vadot 
14227113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
14237113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
14247113afc8SEmmanuel Vadot 		if (sb == NULL) {
1425ce0a9d7cSWarner Losh 			rc = ENOMEM;
14267113afc8SEmmanuel Vadot 			return (rc);
14277113afc8SEmmanuel Vadot 		}
14287113afc8SEmmanuel Vadot 
14297113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: sysctl_xi2c_reg: 0x%x\n",  __func__,
14307113afc8SEmmanuel Vadot 		    pdata->sysctl_xi2c_reg);
14317113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXI2C reg_addr:	0x%x\n",
14327113afc8SEmmanuel Vadot 		    pdata->sysctl_xi2c_reg);
14337113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
14347113afc8SEmmanuel Vadot 		sbuf_delete(sb);
14357113afc8SEmmanuel Vadot 		return (rc);
14367113afc8SEmmanuel Vadot 	}
14377113afc8SEmmanuel Vadot 
14387113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
14397113afc8SEmmanuel Vadot 	if (rc == 0) {
14407113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &reg);
14417113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
14427113afc8SEmmanuel Vadot 		pdata->sysctl_xi2c_reg = reg;
14437113afc8SEmmanuel Vadot 	}
14447113afc8SEmmanuel Vadot 
14457113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
14467113afc8SEmmanuel Vadot 	return (rc);
14477113afc8SEmmanuel Vadot }
14487113afc8SEmmanuel Vadot 
14497113afc8SEmmanuel Vadot static int
14507113afc8SEmmanuel Vadot sysctl_xi2c_reg_value_handler(SYSCTL_HANDLER_ARGS)
14517113afc8SEmmanuel Vadot {
14527113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
14537113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
14547113afc8SEmmanuel Vadot 	char buf[buf_size];
14557113afc8SEmmanuel Vadot 	unsigned int value;
14567113afc8SEmmanuel Vadot 	struct sbuf *sb;
14577113afc8SEmmanuel Vadot 	int rc = 0;
14587113afc8SEmmanuel Vadot 
14597113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
14607113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
14617113afc8SEmmanuel Vadot 		if (sb == NULL) {
1462ce0a9d7cSWarner Losh 			rc = ENOMEM;
14637113afc8SEmmanuel Vadot 			return (rc);
14647113afc8SEmmanuel Vadot 		}
14657113afc8SEmmanuel Vadot 
14667113afc8SEmmanuel Vadot 		value = XI2C_IOREAD(pdata, pdata->sysctl_xi2c_reg);
14677113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
14687113afc8SEmmanuel Vadot 		sbuf_printf(sb, "\nXI2C reg_value:	0x%x\n", value);
14697113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
14707113afc8SEmmanuel Vadot 		sbuf_delete(sb);
14717113afc8SEmmanuel Vadot 		return (rc);
14727113afc8SEmmanuel Vadot 	}
14737113afc8SEmmanuel Vadot 
14747113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
14757113afc8SEmmanuel Vadot 	if (rc == 0) {
14767113afc8SEmmanuel Vadot 		sscanf(buf, "%x", &value);
14777113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
14787113afc8SEmmanuel Vadot 		XI2C_IOWRITE(pdata, pdata->sysctl_xi2c_reg, value);
14797113afc8SEmmanuel Vadot 	}
14807113afc8SEmmanuel Vadot 
14817113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
14827113afc8SEmmanuel Vadot 	return (rc);
14837113afc8SEmmanuel Vadot }
14847113afc8SEmmanuel Vadot 
14857113afc8SEmmanuel Vadot static int
14867113afc8SEmmanuel Vadot sysctl_an_cdr_wr_handler(SYSCTL_HANDLER_ARGS)
14877113afc8SEmmanuel Vadot {
14887113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
14897113afc8SEmmanuel Vadot 	unsigned int an_cdr_wr = 0;
14907113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
14917113afc8SEmmanuel Vadot 	char buf[buf_size];
14927113afc8SEmmanuel Vadot 	struct sbuf *sb;
14937113afc8SEmmanuel Vadot 	int rc = 0;
14947113afc8SEmmanuel Vadot 
14957113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
14967113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
14977113afc8SEmmanuel Vadot 		if (sb == NULL) {
1498ce0a9d7cSWarner Losh 			rc = ENOMEM;
14997113afc8SEmmanuel Vadot 			return (rc);
15007113afc8SEmmanuel Vadot 		}
15017113afc8SEmmanuel Vadot 
15027113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: an_cdr_wr: %d\n",  __func__,
15037113afc8SEmmanuel Vadot 		    pdata->sysctl_an_cdr_workaround);
15047113afc8SEmmanuel Vadot 		sbuf_printf(sb, "%d\n", pdata->sysctl_an_cdr_workaround);
15057113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
15067113afc8SEmmanuel Vadot 		sbuf_delete(sb);
15077113afc8SEmmanuel Vadot 		return (rc);
15087113afc8SEmmanuel Vadot 	}
15097113afc8SEmmanuel Vadot 
15107113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
15117113afc8SEmmanuel Vadot 	if (rc == 0) {
15127113afc8SEmmanuel Vadot 		sscanf(buf, "%u", &an_cdr_wr);
15137113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: an_cdr_wr: 0x%d\n",  __func__,
15147113afc8SEmmanuel Vadot 		    an_cdr_wr);
15157113afc8SEmmanuel Vadot 
15167113afc8SEmmanuel Vadot 		if (an_cdr_wr)
15177113afc8SEmmanuel Vadot 			pdata->sysctl_an_cdr_workaround = 1;
15187113afc8SEmmanuel Vadot 		else
15197113afc8SEmmanuel Vadot 			pdata->sysctl_an_cdr_workaround = 0;
15207113afc8SEmmanuel Vadot 	}
15217113afc8SEmmanuel Vadot 
15227113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
15237113afc8SEmmanuel Vadot 	return (rc);
15247113afc8SEmmanuel Vadot }
15257113afc8SEmmanuel Vadot 
15267113afc8SEmmanuel Vadot static int
15277113afc8SEmmanuel Vadot sysctl_an_cdr_track_early_handler(SYSCTL_HANDLER_ARGS)
15287113afc8SEmmanuel Vadot {
15297113afc8SEmmanuel Vadot 	struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
15307113afc8SEmmanuel Vadot 	unsigned int an_cdr_track_early = 0;
15317113afc8SEmmanuel Vadot 	ssize_t buf_size = 64;
15327113afc8SEmmanuel Vadot 	char buf[buf_size];
15337113afc8SEmmanuel Vadot 	struct sbuf *sb;
15347113afc8SEmmanuel Vadot 	int rc = 0;
15357113afc8SEmmanuel Vadot 
15367113afc8SEmmanuel Vadot 	if (req->newptr == NULL) {
15377113afc8SEmmanuel Vadot 		sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
15387113afc8SEmmanuel Vadot 		if (sb == NULL) {
1539ce0a9d7cSWarner Losh 			rc = ENOMEM;
15407113afc8SEmmanuel Vadot 			return (rc);
15417113afc8SEmmanuel Vadot 		}
15427113afc8SEmmanuel Vadot 
15437113afc8SEmmanuel Vadot 		axgbe_printf(2, "READ: %s: an_cdr_track_early %d\n",  __func__,
15447113afc8SEmmanuel Vadot 		    pdata->sysctl_an_cdr_track_early);
15457113afc8SEmmanuel Vadot 		sbuf_printf(sb, "%d\n", pdata->sysctl_an_cdr_track_early);
15467113afc8SEmmanuel Vadot 		rc = sbuf_finish(sb);
15477113afc8SEmmanuel Vadot 		sbuf_delete(sb);
15487113afc8SEmmanuel Vadot 		return (rc);
15497113afc8SEmmanuel Vadot 	}
15507113afc8SEmmanuel Vadot 
15517113afc8SEmmanuel Vadot 	rc = get_ubuf(req, buf);
15527113afc8SEmmanuel Vadot 	if (rc == 0) {
15537113afc8SEmmanuel Vadot 		sscanf(buf, "%u", &an_cdr_track_early);
15547113afc8SEmmanuel Vadot 		axgbe_printf(2, "WRITE: %s: an_cdr_track_early: %d\n",  __func__,
15557113afc8SEmmanuel Vadot 		    an_cdr_track_early);
15567113afc8SEmmanuel Vadot 
15577113afc8SEmmanuel Vadot 		if (an_cdr_track_early)
15587113afc8SEmmanuel Vadot 			pdata->sysctl_an_cdr_track_early = 1;
15597113afc8SEmmanuel Vadot 		else
15607113afc8SEmmanuel Vadot 			pdata->sysctl_an_cdr_track_early = 0;
15617113afc8SEmmanuel Vadot 	}
15627113afc8SEmmanuel Vadot 
15637113afc8SEmmanuel Vadot 	axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
15647113afc8SEmmanuel Vadot 	return (rc);
15657113afc8SEmmanuel Vadot }
15667113afc8SEmmanuel Vadot 
15677113afc8SEmmanuel Vadot void
15687113afc8SEmmanuel Vadot axgbe_sysctl_exit(struct xgbe_prv_data *pdata)
15697113afc8SEmmanuel Vadot {
15707113afc8SEmmanuel Vadot 
15717113afc8SEmmanuel Vadot 	if (pdata->sys_op)
15727113afc8SEmmanuel Vadot 		free(pdata->sys_op, M_AXGBE);
15737113afc8SEmmanuel Vadot }
15747113afc8SEmmanuel Vadot 
15757113afc8SEmmanuel Vadot void
15767113afc8SEmmanuel Vadot axgbe_sysctl_init(struct xgbe_prv_data *pdata)
15777113afc8SEmmanuel Vadot {
15787113afc8SEmmanuel Vadot 	struct sysctl_ctx_list *clist;
15797113afc8SEmmanuel Vadot 	struct sysctl_oid_list *top;
15807113afc8SEmmanuel Vadot 	struct sysctl_oid *parent;
15817113afc8SEmmanuel Vadot 	struct sysctl_op *sys_op;
15827113afc8SEmmanuel Vadot 
15837113afc8SEmmanuel Vadot 	sys_op = malloc(sizeof(*sys_op), M_AXGBE, M_WAITOK | M_ZERO);
15847113afc8SEmmanuel Vadot 	pdata->sys_op = sys_op;
15857113afc8SEmmanuel Vadot 
15867113afc8SEmmanuel Vadot 	clist = device_get_sysctl_ctx(pdata->dev);
15877113afc8SEmmanuel Vadot 	parent = device_get_sysctl_tree(pdata->dev);
15887113afc8SEmmanuel Vadot 	top = SYSCTL_CHILDREN(parent);
15897113afc8SEmmanuel Vadot 
15907113afc8SEmmanuel Vadot 	/* Set defaults */
15917113afc8SEmmanuel Vadot 	pdata->sysctl_xgmac_reg = 0;
15927113afc8SEmmanuel Vadot 	pdata->sysctl_xpcs_mmd = 1;
15937113afc8SEmmanuel Vadot 	pdata->sysctl_xpcs_reg = 0;
15942b8df536SStephan de Wit 	pdata->link_workaround = 1;
15952b8df536SStephan de Wit 	pdata->tx_pause = 1;
15962b8df536SStephan de Wit 	pdata->rx_pause = 1;
15972b8df536SStephan de Wit 	pdata->enable_rss = 1;
15987113afc8SEmmanuel Vadot 
15997113afc8SEmmanuel Vadot 	SYSCTL_ADD_UINT(clist, top, OID_AUTO, "axgbe_debug_level", CTLFLAG_RWTUN,
16007113afc8SEmmanuel Vadot 	    &pdata->debug_level, 0, "axgbe log level -- higher is verbose");
16017113afc8SEmmanuel Vadot 
16022968dde3SVincenzo Maffione 	SYSCTL_ADD_UINT(clist, top, OID_AUTO, "sph_enable",
16032968dde3SVincenzo Maffione 	    CTLFLAG_RDTUN, &pdata->sph_enable, 1,
16042968dde3SVincenzo Maffione 	    "shows the split header feature state (1 - enable, 0 - disable");
16052968dde3SVincenzo Maffione 
1606bfd75d45SVincenzo Maffione 	SYSCTL_ADD_UINT(clist, top, OID_AUTO, "link_workaround",
1607bfd75d45SVincenzo Maffione 	    CTLFLAG_RWTUN, &pdata->link_workaround, 0,
1608bfd75d45SVincenzo Maffione 	    "enable the workaround for link issue in coming up");
1609bfd75d45SVincenzo Maffione 
16102b8df536SStephan de Wit 	SYSCTL_ADD_UINT(clist, top, OID_AUTO, "rss_enabled",
16112b8df536SStephan de Wit 		CTLFLAG_RDTUN, &pdata->enable_rss, 1,
16122b8df536SStephan de Wit 		"shows the RSS feature state (1 - enable, 0 - disable)");
16132b8df536SStephan de Wit 
16142b8df536SStephan de Wit 	SYSCTL_ADD_UINT(clist, top, OID_AUTO, "tx_pause",
16152b8df536SStephan de Wit 		CTLFLAG_RDTUN, &pdata->tx_pause, 1,
16162b8df536SStephan de Wit 		"shows the Flow Control TX pause feature state (1 - enable, 0 - disable)");
16172b8df536SStephan de Wit 
16182b8df536SStephan de Wit 	SYSCTL_ADD_UINT(clist, top, OID_AUTO, "rx_pause",
16192b8df536SStephan de Wit 		CTLFLAG_RDTUN, &pdata->rx_pause, 1,
16202b8df536SStephan de Wit 		"shows the Flow Control RX pause feature state (1 - enable, 0 - disable)");
16212b8df536SStephan de Wit 
16227113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xgmac_register",
16237113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16247113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_xgmac_reg_addr_handler, "IU",
16257113afc8SEmmanuel Vadot 	    "xgmac register addr");
16267113afc8SEmmanuel Vadot 
16277113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xgmac_register_value",
16287113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16297113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_xgmac_reg_value_handler, "IU",
16307113afc8SEmmanuel Vadot 	    "xgmac register value");
16317113afc8SEmmanuel Vadot 
16327113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_mmd",
16337113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16347113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_xpcs_mmd_reg_handler, "IU", "xpcs mmd register");
16357113afc8SEmmanuel Vadot 
16367113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_register",
16377113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16387113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_xpcs_reg_addr_handler, "IU", "xpcs register");
16397113afc8SEmmanuel Vadot 
16407113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_register_value",
16417113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16427113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_xpcs_reg_value_handler, "IU",
16437113afc8SEmmanuel Vadot 	    "xpcs register value");
16447113afc8SEmmanuel Vadot 
16457113afc8SEmmanuel Vadot 	if (pdata->xpcs_res) {
16467113afc8SEmmanuel Vadot 		SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xprop_register",
16477113afc8SEmmanuel Vadot 		    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16487113afc8SEmmanuel Vadot 		    pdata, 0, sysctl_xprop_reg_addr_handler,
16497113afc8SEmmanuel Vadot 		    "IU", "xprop register");
16507113afc8SEmmanuel Vadot 
16517113afc8SEmmanuel Vadot 		SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xprop_register_value",
16527113afc8SEmmanuel Vadot 		    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16537113afc8SEmmanuel Vadot 		    pdata, 0, sysctl_xprop_reg_value_handler,
16547113afc8SEmmanuel Vadot 		    "IU", "xprop register value");
16557113afc8SEmmanuel Vadot 	}
16567113afc8SEmmanuel Vadot 
16577113afc8SEmmanuel Vadot 	if (pdata->xpcs_res) {
16587113afc8SEmmanuel Vadot 		SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xi2c_register",
16597113afc8SEmmanuel Vadot 		    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16607113afc8SEmmanuel Vadot 		    pdata, 0, sysctl_xi2c_reg_addr_handler,
16617113afc8SEmmanuel Vadot 		    "IU", "xi2c register");
16627113afc8SEmmanuel Vadot 
16637113afc8SEmmanuel Vadot 		SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xi2c_register_value",
16647113afc8SEmmanuel Vadot 		    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16657113afc8SEmmanuel Vadot 		    pdata, 0, sysctl_xi2c_reg_value_handler,
16667113afc8SEmmanuel Vadot 		    "IU", "xi2c register value");
16677113afc8SEmmanuel Vadot 	}
16687113afc8SEmmanuel Vadot 
16697113afc8SEmmanuel Vadot 	if (pdata->vdata->an_cdr_workaround) {
16707113afc8SEmmanuel Vadot 		SYSCTL_ADD_PROC(clist, top, OID_AUTO, "an_cdr_workaround",
16717113afc8SEmmanuel Vadot 		    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16727113afc8SEmmanuel Vadot 		    pdata, 0, sysctl_an_cdr_wr_handler, "IU",
16737113afc8SEmmanuel Vadot 		    "an cdr workaround");
16747113afc8SEmmanuel Vadot 
16757113afc8SEmmanuel Vadot 		SYSCTL_ADD_PROC(clist, top, OID_AUTO, "an_cdr_track_early",
16767113afc8SEmmanuel Vadot 		    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16777113afc8SEmmanuel Vadot 		    pdata, 0, sysctl_an_cdr_track_early_handler, "IU",
16787113afc8SEmmanuel Vadot 		    "an cdr track early");
16797113afc8SEmmanuel Vadot 	}
16807113afc8SEmmanuel Vadot 
16817113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "drv_info",
16827113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16837113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_get_drv_info_handler, "IU",
16847113afc8SEmmanuel Vadot 	    "xgbe drv info");
16857113afc8SEmmanuel Vadot 
16867113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "link_info",
16877113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16887113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_get_link_info_handler, "IU",
16897113afc8SEmmanuel Vadot 	    "xgbe link info");
16907113afc8SEmmanuel Vadot 
16917113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "coalesce_info",
16927113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16937113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_coalesce_handler, "IU",
16947113afc8SEmmanuel Vadot 	    "xgbe coalesce info");
16957113afc8SEmmanuel Vadot 
16967113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "pauseparam_info",
16977113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
16987113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_pauseparam_handler, "IU",
16997113afc8SEmmanuel Vadot 	    "xgbe pauseparam info");
17007113afc8SEmmanuel Vadot 
17017113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "link_ksettings_info",
17027113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
17037113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_link_ksettings_handler, "IU",
17047113afc8SEmmanuel Vadot 	    "xgbe link_ksettings info");
17057113afc8SEmmanuel Vadot 
17067113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "ringparam_info",
17077113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
17087113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_ringparam_handler, "IU",
17097113afc8SEmmanuel Vadot 	    "xgbe ringparam info");
17107113afc8SEmmanuel Vadot 
17117113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "channels_info",
17127113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
17137113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_channels_handler, "IU",
17147113afc8SEmmanuel Vadot 	    "xgbe channels info");
17157113afc8SEmmanuel Vadot 
17167113afc8SEmmanuel Vadot 	SYSCTL_ADD_PROC(clist, top, OID_AUTO, "mac_stats",
17177113afc8SEmmanuel Vadot 	    CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
17187113afc8SEmmanuel Vadot 	    pdata, 0, sysctl_mac_stats_handler, "IU",
17197113afc8SEmmanuel Vadot 	    "xgbe mac stats");
17207113afc8SEmmanuel Vadot }
1721