The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/axgbe/xgbe-sysctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2020 Advanced Micro Devices, Inc.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * Contact Information :
   28  * Rajesh Kumar <rajesh1.kumar@amd.com>
   29  * Arpan Palit <Arpan.Palit@amd.com>
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 #include <sys/param.h>
   36 #include <sys/sysctl.h>
   37 #include <sys/sbuf.h>
   38 
   39 #include "xgbe.h"
   40 #include "xgbe-common.h"
   41 
   42 #define SYSCTL_BUF_LEN 64
   43 
   44 typedef enum{
   45         /* Coalesce flag */
   46         rx_coalesce_usecs = 1,
   47         rx_max_coalesced_frames,
   48         rx_coalesce_usecs_irq,
   49         rx_max_coalesced_frames_irq,
   50         tx_coalesce_usecs,
   51         tx_max_coalesced_frames,
   52         tx_coalesce_usecs_irq,
   53         tx_max_coalesced_frames_irq,
   54         stats_block_coalesce_usecs,
   55         use_adaptive_rx_coalesce,
   56         use_adaptive_tx_coalesce,
   57         pkt_rate_low,
   58         rx_coalesce_usecs_low,
   59         rx_max_coalesced_frames_low,
   60         tx_coalesce_usecs_low,
   61         tx_max_coalesced_frames_low,
   62         pkt_rate_high,
   63         rx_coalesce_usecs_high,
   64         rx_max_coalesced_frames_high,
   65         tx_coalesce_usecs_high,
   66         tx_max_coalesced_frames_high,
   67         rate_sample_interval,
   68 
   69         /* Pasue flag */
   70         autoneg,
   71         tx_pause,
   72         rx_pause,
   73 
   74         /* link settings */
   75         speed,
   76         duplex,
   77 
   78         /* Ring settings */
   79         rx_pending,
   80         rx_mini_pending,
   81         rx_jumbo_pending,
   82         tx_pending,
   83 
   84         /* Channels settings */
   85         rx_count,
   86         tx_count,
   87         other_count,
   88         combined_count,
   89 } sysctl_variable_t;
   90 
   91 typedef enum {
   92         SYSL_NONE,
   93         SYSL_BOOL,
   94         SYSL_S32,
   95         SYSL_U8,
   96         SYSL_U16,
   97         SYSL_U32,
   98         SYSL_U64,
   99         SYSL_BE16,
  100         SYSL_IP4,
  101         SYSL_STR,
  102         SYSL_FLAG,
  103         SYSL_MAC,
  104 } sysctl_type_t;
  105 
  106 struct sysctl_info {
  107         uint8_t name[32];
  108         sysctl_type_t type;
  109         sysctl_variable_t flag;
  110         uint8_t support[16];
  111 };
  112 
  113 struct sysctl_op {
  114         /* Coalesce options */
  115         unsigned int rx_coalesce_usecs;
  116         unsigned int rx_max_coalesced_frames;
  117         unsigned int rx_coalesce_usecs_irq;
  118         unsigned int rx_max_coalesced_frames_irq;
  119         unsigned int tx_coalesce_usecs;
  120         unsigned int tx_max_coalesced_frames;
  121         unsigned int tx_coalesce_usecs_irq;
  122         unsigned int tx_max_coalesced_frames_irq;
  123         unsigned int stats_block_coalesce_usecs;
  124         unsigned int use_adaptive_rx_coalesce;
  125         unsigned int use_adaptive_tx_coalesce;
  126         unsigned int pkt_rate_low;
  127         unsigned int rx_coalesce_usecs_low;
  128         unsigned int rx_max_coalesced_frames_low;
  129         unsigned int tx_coalesce_usecs_low;
  130         unsigned int tx_max_coalesced_frames_low;
  131         unsigned int pkt_rate_high;
  132         unsigned int rx_coalesce_usecs_high;
  133         unsigned int rx_max_coalesced_frames_high;
  134         unsigned int tx_coalesce_usecs_high;
  135         unsigned int tx_max_coalesced_frames_high;
  136         unsigned int rate_sample_interval;
  137 
  138         /* Pasue options */
  139         unsigned int autoneg;
  140         unsigned int tx_pause;
  141         unsigned int rx_pause;
  142 
  143         /* Link settings options */
  144         unsigned int speed;
  145         unsigned int duplex;
  146 
  147         /* Ring param options */
  148         unsigned int rx_max_pending;
  149         unsigned int rx_mini_max_pending;
  150         unsigned int rx_jumbo_max_pending;
  151         unsigned int tx_max_pending;
  152         unsigned int rx_pending;
  153         unsigned int rx_mini_pending;
  154         unsigned int rx_jumbo_pending;
  155         unsigned int tx_pending;
  156 
  157         /* Channels options */
  158         unsigned int max_rx;
  159         unsigned int max_tx;
  160         unsigned int max_other;
  161         unsigned int max_combined;
  162         unsigned int rx_count;
  163         unsigned int tx_count;
  164         unsigned int other_count;
  165         unsigned int combined_count;
  166 } sys_op;
  167 
  168 #define GSTRING_LEN 32
  169 
  170 struct xgbe_stats {
  171         char stat_string[GSTRING_LEN];
  172         int stat_size;
  173         int stat_offset;
  174 };
  175 
  176 #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
  177 
  178 #define XGMAC_MMC_STAT(_string, _var)                      \
  179         { _string,                                            \
  180           FIELD_SIZEOF(struct xgbe_mmc_stats, _var),        \
  181           offsetof(struct xgbe_prv_data, mmc_stats._var),       \
  182         }
  183 
  184 #define XGMAC_EXT_STAT(_string, _var)                      \
  185         { _string,                                            \
  186           FIELD_SIZEOF(struct xgbe_ext_stats, _var),        \
  187           offsetof(struct xgbe_prv_data, ext_stats._var),       \
  188         }
  189 static const struct xgbe_stats xgbe_gstring_stats[] = {
  190         XGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
  191         XGMAC_MMC_STAT("tx_packets", txframecount_gb),
  192         XGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
  193         XGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
  194         XGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
  195         XGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
  196         XGMAC_EXT_STAT("tx_vxlan_packets", tx_vxlan_packets),
  197         XGMAC_EXT_STAT("tx_tso_packets", tx_tso_packets),
  198         XGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
  199         XGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
  200         XGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
  201         XGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
  202         XGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
  203         XGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
  204         XGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
  205         XGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
  206 
  207         XGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
  208         XGMAC_MMC_STAT("rx_packets", rxframecount_gb),
  209         XGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
  210         XGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
  211         XGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
  212         XGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
  213         XGMAC_EXT_STAT("rx_vxlan_packets", rx_vxlan_packets),
  214         XGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
  215         XGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
  216         XGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
  217         XGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
  218         XGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
  219         XGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
  220         XGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
  221         XGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
  222         XGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
  223         XGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
  224         XGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
  225         XGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
  226         XGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
  227         XGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
  228         XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
  229         XGMAC_EXT_STAT("rx_csum_errors", rx_csum_errors),
  230         XGMAC_EXT_STAT("rx_vxlan_csum_errors", rx_vxlan_csum_errors),
  231         XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
  232         XGMAC_EXT_STAT("rx_split_header_packets", rx_split_header_packets),
  233         XGMAC_EXT_STAT("rx_buffer_unavailable", rx_buffer_unavailable),
  234 };
  235 
  236 #define XGBE_STATS_COUNT        ARRAY_SIZE(xgbe_gstring_stats)
  237 
  238 char** alloc_sysctl_buffer(void);
  239 void get_val(char *buf, char **op, char **val, int *n_op);
  240 void fill_data(struct sysctl_op *sys_op, int flag, unsigned int value);
  241 
  242 static int
  243 exit_bad_op(void)
  244 {
  245 
  246         printf("SYSCTL: bad command line option (s)\n");
  247         return(-EINVAL);
  248 }
  249 
  250 static inline unsigned
  251 fls_long(unsigned long l)
  252 {
  253 
  254         if (sizeof(l) == 4)
  255                 return (fls(l));
  256         return (fls64(l));
  257 }
  258 
  259 static inline __attribute__((const))
  260 unsigned long __rounddown_pow_of_two(unsigned long n)
  261 {
  262 
  263         return (1UL << (fls_long(n) - 1));
  264 }
  265 
  266 static inline int
  267 get_ubuf(struct sysctl_req *req, char *ubuf)
  268 {
  269         int rc;
  270 
  271         printf("%s: len:0x%li idx:0x%li\n", __func__, req->newlen,
  272             req->newidx);
  273         if (req->newlen >= SYSCTL_BUF_LEN)
  274                 return (-EINVAL);
  275 
  276         rc = SYSCTL_IN(req, ubuf, req->newlen);
  277         if (rc)
  278                 return (rc);
  279         ubuf[req->newlen] = '\0';
  280 
  281         return (0);
  282 }
  283 
  284 char**
  285 alloc_sysctl_buffer(void)
  286 {
  287         char **buffer;
  288         int i;
  289 
  290         buffer = malloc(sizeof(char *)*32, M_AXGBE, M_WAITOK | M_ZERO);
  291         for(i = 0; i < 32; i++)
  292                 buffer[i] = malloc(sizeof(char)*32, M_AXGBE, M_WAITOK | M_ZERO);
  293 
  294         return (buffer);
  295 }
  296 
  297 void
  298 get_val(char *buf, char **op, char **val, int *n_op)
  299 {
  300         int blen = strlen(buf);
  301         int count = 0;
  302         int i, j;
  303 
  304         *n_op = 0;
  305         for (i = 0; i < blen; i++) {
  306                 count++;
  307                 /* Get sysctl command option */
  308                 for (j = 0; buf[i] != ' '; j++) {
  309                         if (i >= blen)
  310                                 break;
  311                         op[*n_op][j] = buf[i++];
  312                 }
  313                 op[*n_op][j+1] = '\0';
  314                 if (i >= strlen(buf))
  315                         goto out;
  316 
  317                 /* Get sysctl value*/
  318                 i++;
  319                 for (j = 0; buf[i] != ' '; j++) {
  320                         if (i >= blen)
  321                                 break;
  322                         val[*n_op][j] = buf[i++]; 
  323                 }
  324                 val[*n_op][j+1] = '\0';
  325                 if (i >= strlen(buf))
  326                         goto out;
  327 
  328                 *n_op = count;
  329         }
  330 
  331 out:
  332         *n_op = count;
  333 }
  334 
  335 void
  336 fill_data(struct sysctl_op *sys_op, int flag, unsigned int value)
  337 {
  338 
  339         switch(flag) {
  340         case 1:
  341         sys_op->rx_coalesce_usecs = value;
  342         break;
  343         case 2:
  344         sys_op->rx_max_coalesced_frames = value;
  345         break;
  346         case 3:
  347         sys_op->rx_coalesce_usecs_irq = value;
  348         break;
  349         case 4:
  350         sys_op->rx_max_coalesced_frames_irq = value;
  351         break;
  352         case 5:
  353         sys_op->tx_coalesce_usecs = value;
  354         break;
  355         case 6:
  356         sys_op->tx_max_coalesced_frames = value;
  357         break;
  358         case 7:
  359         sys_op->tx_coalesce_usecs_irq = value;
  360         break;
  361         case 8:
  362         sys_op->tx_max_coalesced_frames_irq = value;
  363         break;
  364         case 9:
  365         sys_op->stats_block_coalesce_usecs = value;
  366         break;
  367         case 10:
  368         sys_op->use_adaptive_rx_coalesce = value;
  369         break;
  370         case 11:
  371         sys_op->use_adaptive_tx_coalesce = value;
  372         break;
  373         case 12:
  374         sys_op->pkt_rate_low = value;
  375         break;
  376         case 13:
  377         sys_op->rx_coalesce_usecs_low = value;
  378         break;
  379         case 14:
  380         sys_op->rx_max_coalesced_frames_low = value;
  381         break;
  382         case 15:
  383         sys_op->tx_coalesce_usecs_low = value;
  384         break;
  385         case 16:
  386         sys_op->tx_max_coalesced_frames_low = value;
  387         break;
  388         case 17:
  389         sys_op->pkt_rate_high = value;
  390         break;
  391         case 18:
  392         sys_op->rx_coalesce_usecs_high = value;
  393         break;
  394         case 19:
  395         sys_op->rx_max_coalesced_frames_high = value;
  396         break;
  397         case 20:
  398         sys_op->tx_coalesce_usecs_high = value;
  399         break;
  400         case 21:
  401         sys_op->tx_max_coalesced_frames_high = value;
  402         break;
  403         case 22:
  404         sys_op->rate_sample_interval = value;
  405         break;
  406         case 23:
  407         sys_op->autoneg = value;
  408         break;
  409         case 24:
  410         sys_op->rx_pause = value;
  411         break;
  412         case 25:
  413         sys_op->tx_pause = value;
  414         break;
  415         case 26:
  416         sys_op->speed = value;
  417         break;
  418         case 27:
  419         sys_op->duplex = value;
  420         break;
  421         case 28:
  422         sys_op->rx_pending = value;
  423         break;
  424         case 29:
  425         sys_op->rx_mini_pending = value;
  426         break;
  427         case 30:
  428         sys_op->rx_jumbo_pending = value;
  429         break;
  430         case 31:
  431         sys_op->tx_pending = value;
  432         break;
  433         default:
  434                 printf("Option error\n");
  435         }
  436 }
  437 
  438 static int
  439 parse_generic_sysctl(struct xgbe_prv_data *pdata, char *buf,
  440     struct sysctl_info *info, unsigned int n_info)
  441 {
  442         struct sysctl_op *sys_op = pdata->sys_op;
  443         unsigned int value;
  444         char **op, **val;
  445         int n_op = 0;
  446         int rc = 0;
  447         int i, idx;
  448 
  449         op = alloc_sysctl_buffer();
  450         val = alloc_sysctl_buffer();
  451         get_val(buf, op, val, &n_op);
  452 
  453         for (i = 0; i < n_op; i++) {
  454                 for (idx = 0; idx < n_info; idx++) {
  455                         if (strcmp(info[idx].name, op[i]) == 0) {
  456                                 if (strcmp(info[idx].support,
  457                                     "not-supported") == 0){
  458                                         axgbe_printf(1, "ignoring not-supported "
  459                                             "option \"%s\"\n", info[idx].name);
  460                                         break;
  461                                 }
  462                                 switch(info[idx].type) {
  463                                 case SYSL_BOOL: {
  464                                         if (!strcmp(val[i], "on"))
  465                                                 fill_data(sys_op,
  466                                                     info[idx].flag, 1);
  467                                         else if (!strcmp(val[i], "off"))
  468                                                 fill_data(sys_op,
  469                                                     info[idx].flag, 0);
  470                                         else
  471                                                 rc = exit_bad_op();
  472                                         break;
  473                                 }
  474                                 case SYSL_S32:
  475                                         sscanf(val[i], "%u", &value);
  476                                         fill_data(sys_op, info[idx].flag, value);
  477                                         break;
  478                                 case SYSL_U8:
  479                                         if (!strcmp(val[i], "half"))
  480                                                 fill_data(sys_op,
  481                                                     info[idx].flag, DUPLEX_HALF);
  482                                         else if (!strcmp(val[i], "full"))
  483                                                 fill_data(sys_op,
  484                                                     info[idx].flag, DUPLEX_FULL);
  485                                         else
  486                                                 exit_bad_op();
  487                                 default:
  488                                         rc = exit_bad_op();
  489                                 }
  490                         }
  491                 }
  492         }
  493 
  494         for(i = 0; i < 32; i++)
  495                 free(op[i], M_AXGBE);
  496         free(op, M_AXGBE);
  497 
  498         for(i = 0; i < 32; i++)
  499                 free(val[i], M_AXGBE);
  500         free(val, M_AXGBE);
  501         return (rc);
  502 }
  503 
  504 
  505 static int
  506 sysctl_xgmac_reg_addr_handler(SYSCTL_HANDLER_ARGS)
  507 {
  508         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
  509         ssize_t buf_size = 64;
  510         char buf[buf_size];
  511         struct sbuf *sb;
  512         unsigned int reg;
  513         int rc = 0;
  514 
  515         if (req->newptr == NULL) {
  516                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
  517                 if (sb == NULL) {
  518                         rc = ENOMEM;
  519                         return (rc);
  520                 }
  521 
  522                 axgbe_printf(2, "READ: %s: sysctl_xgmac_reg: 0x%x\n",  __func__,
  523                     pdata->sysctl_xgmac_reg);
  524                 sbuf_printf(sb, "\nXGMAC reg_addr:      0x%x\n",
  525                     pdata->sysctl_xgmac_reg);
  526                 rc = sbuf_finish(sb);
  527                 sbuf_delete(sb);
  528                 return (rc);
  529         }
  530 
  531         rc = get_ubuf(req, buf);
  532         if (rc == 0) {
  533                 sscanf(buf, "%x", &reg);
  534                 axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
  535                 pdata->sysctl_xgmac_reg = reg;
  536         }
  537 
  538         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
  539         return (rc);
  540 }
  541 
  542 static int
  543 sysctl_get_drv_info_handler(SYSCTL_HANDLER_ARGS)
  544 {
  545         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
  546         struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
  547         ssize_t buf_size = 64;
  548         struct sbuf *sb;
  549         int rc = 0;
  550 
  551         if (req->newptr == NULL) {
  552                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
  553                 if (sb == NULL) {
  554                         rc = ENOMEM;
  555                         return (rc);
  556                 }
  557 
  558                 sbuf_printf(sb, "\ndriver:      %s", XGBE_DRV_NAME);
  559                 sbuf_printf(sb, "\nversion: %s", XGBE_DRV_VERSION);
  560                 sbuf_printf(sb, "\nfirmware-version: %d.%d.%d",
  561                     XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
  562                     XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
  563                     XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
  564                 sbuf_printf(sb, "\nbus-info: %04d:%02d:%02d",
  565                     pdata->pcie_bus, pdata->pcie_device, pdata->pcie_func);
  566 
  567                 rc = sbuf_finish(sb);
  568                 sbuf_delete(sb);
  569                 return (rc);
  570         }
  571 
  572         return (-EINVAL);
  573 }
  574 
  575 static int
  576 sysctl_get_link_info_handler(SYSCTL_HANDLER_ARGS)
  577 {
  578         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
  579         ssize_t buf_size = 64;
  580         struct sbuf *sb;
  581         int rc = 0;
  582 
  583         if (req->newptr == NULL) {
  584                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
  585                 if (sb == NULL) {
  586                         rc = ENOMEM;
  587                         return (rc);
  588                 }
  589                 
  590                 sbuf_printf(sb, "\nLink is %s", pdata->phy.link ? "Up" : "Down");
  591                 rc = sbuf_finish(sb);
  592                 sbuf_delete(sb);
  593                 return (0);
  594         }
  595 
  596         return (-EINVAL);
  597 }
  598 
  599 #define COALESCE_SYSCTL_INFO(__coalop)                                                  \
  600 {                                                                                       \
  601         { "adaptive-rx", SYSL_BOOL, use_adaptive_rx_coalesce, "not-supported" },        \
  602         { "adaptive-tx", SYSL_BOOL, use_adaptive_tx_coalesce, "not-supported" },        \
  603         { "sample-interval", SYSL_S32, rate_sample_interval, "not-supported" },         \
  604         { "stats-block-usecs", SYSL_S32, stats_block_coalesce_usecs, "not-supported" }, \
  605         { "pkt-rate-low", SYSL_S32, pkt_rate_low, "not-supported" },                    \
  606         { "pkt-rate-high", SYSL_S32, pkt_rate_high, "not-supported" },                  \
  607         { "rx-usecs", SYSL_S32, rx_coalesce_usecs, "supported" },                       \
  608         { "rx-frames", SYSL_S32, rx_max_coalesced_frames, "supported" },                \
  609         { "rx-usecs-irq", SYSL_S32, rx_coalesce_usecs_irq, "not-supported" },           \
  610         { "rx-frames-irq", SYSL_S32, rx_max_coalesced_frames_irq, "not-supported" },    \
  611         { "tx-usecs", SYSL_S32, tx_coalesce_usecs, "not-supported" },                   \
  612         { "tx-frames", SYSL_S32, tx_max_coalesced_frames, "supported" },                \
  613         { "tx-usecs-irq", SYSL_S32, tx_coalesce_usecs_irq, "not-supported" },           \
  614         { "tx-frames-irq", SYSL_S32, tx_max_coalesced_frames_irq, "not-supported" },    \
  615         { "rx-usecs-low", SYSL_S32, rx_coalesce_usecs_low, "not-supported" },           \
  616         { "rx-frames-low", SYSL_S32, rx_max_coalesced_frames_low, "not-supported"},     \
  617         { "tx-usecs-low", SYSL_S32, tx_coalesce_usecs_low, "not-supported" },           \
  618         { "tx-frames-low", SYSL_S32, tx_max_coalesced_frames_low, "not-supported" },    \
  619         { "rx-usecs-high", SYSL_S32, rx_coalesce_usecs_high, "not-supported" },         \
  620         { "rx-frames-high", SYSL_S32, rx_max_coalesced_frames_high, "not-supported" },  \
  621         { "tx-usecs-high", SYSL_S32, tx_coalesce_usecs_high, "not-supported" },         \
  622         { "tx-frames-high", SYSL_S32, tx_max_coalesced_frames_high, "not-supported" },  \
  623 }
  624 
  625 static int
  626 sysctl_coalesce_handler(SYSCTL_HANDLER_ARGS)
  627 {
  628         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
  629         struct xgbe_hw_if *hw_if = &pdata->hw_if;
  630         struct sysctl_op *sys_op = pdata->sys_op;
  631         struct sysctl_info sysctl_coalesce[] = COALESCE_SYSCTL_INFO(coalop);
  632         unsigned int rx_frames, rx_riwt, rx_usecs;
  633         unsigned int tx_frames;
  634         ssize_t buf_size = 64;
  635         char buf[buf_size];
  636         struct sbuf *sb;
  637         int rc = 0;
  638 
  639         if (req->newptr == NULL) {
  640                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
  641                 if (sb == NULL) {
  642                         rc = ENOMEM;
  643                         return (rc);
  644                 }
  645                 sys_op->rx_coalesce_usecs = pdata->rx_usecs;
  646                 sys_op->rx_max_coalesced_frames = pdata->rx_frames;
  647                 sys_op->tx_max_coalesced_frames = pdata->tx_frames;
  648 
  649                 sbuf_printf(sb, "\nAdaptive RX: %s  TX: %s\n",
  650                     sys_op->use_adaptive_rx_coalesce ? "on" : "off",
  651                     sys_op->use_adaptive_tx_coalesce ? "on" : "off");
  652 
  653                 sbuf_printf(sb, "stats-block-usecs: %u\n"
  654                     "sample-interval: %u\n"
  655                     "pkt-rate-low: %u\n"
  656                     "pkt-rate-high: %u\n"
  657                     "\n"
  658                     "rx-usecs: %u\n"
  659                     "rx-frames: %u\n"
  660                     "rx-usecs-irq: %u\n"
  661                     "rx-frames-irq: %u\n"
  662                     "\n"
  663                     "tx-usecs: %u\n"
  664                     "tx-frames: %u\n"
  665                     "tx-usecs-irq: %u\n"
  666                     "tx-frames-irq: %u\n"
  667                     "\n"
  668                     "rx-usecs-low: %u\n"
  669                     "rx-frames-low: %u\n"
  670                     "tx-usecs-low: %u\n"
  671                     "tx-frames-low: %u\n"
  672                     "\n"
  673                     "rx-usecs-high: %u\n"
  674                     "rx-frames-high: %u\n"
  675                     "tx-usecs-high: %u\n"
  676                     "tx-frames-high: %u\n",
  677                     sys_op->stats_block_coalesce_usecs,
  678                     sys_op->rate_sample_interval,
  679                     sys_op->pkt_rate_low,
  680                     sys_op->pkt_rate_high,
  681 
  682                     sys_op->rx_coalesce_usecs,
  683                     sys_op->rx_max_coalesced_frames,
  684                     sys_op->rx_coalesce_usecs_irq,
  685                     sys_op->rx_max_coalesced_frames_irq,
  686 
  687                     sys_op->tx_coalesce_usecs,
  688                     sys_op->tx_max_coalesced_frames,
  689                     sys_op->tx_coalesce_usecs_irq,
  690                     sys_op->tx_max_coalesced_frames_irq,
  691 
  692                     sys_op->rx_coalesce_usecs_low,
  693                     sys_op->rx_max_coalesced_frames_low,
  694                     sys_op->tx_coalesce_usecs_low,
  695                     sys_op->tx_max_coalesced_frames_low,
  696 
  697                     sys_op->rx_coalesce_usecs_high,
  698                     sys_op->rx_max_coalesced_frames_high,
  699                     sys_op->tx_coalesce_usecs_high,
  700                     sys_op->tx_max_coalesced_frames_high);
  701 
  702                 rc = sbuf_finish(sb);
  703                 sbuf_delete(sb);
  704                 return (0);
  705         }
  706 
  707         rc = get_ubuf(req, buf);
  708         if (rc == 0) {
  709                 parse_generic_sysctl(pdata, buf, sysctl_coalesce,
  710                     ARRAY_SIZE(sysctl_coalesce)); 
  711 
  712                 rx_riwt = hw_if->usec_to_riwt(pdata, sys_op->rx_coalesce_usecs);
  713                 rx_usecs = sys_op->rx_coalesce_usecs;
  714                 rx_frames = sys_op->rx_max_coalesced_frames;
  715 
  716                 /* Use smallest possible value if conversion resulted in zero */
  717                 if (rx_usecs && !rx_riwt)
  718                         rx_riwt = 1;
  719 
  720                 /* Check the bounds of values for Rx */
  721                 if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
  722                         axgbe_printf(2, "rx-usec is limited to %d usecs\n",
  723                             hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
  724                         return (-EINVAL);
  725                 }
  726                 if (rx_frames > pdata->rx_desc_count) {
  727                         axgbe_printf(2, "rx-frames is limited to %d frames\n",
  728                             pdata->rx_desc_count);
  729                         return (-EINVAL);
  730                 }
  731 
  732                 tx_frames = sys_op->tx_max_coalesced_frames;
  733 
  734                 /* Check the bounds of values for Tx */
  735                 if (tx_frames > pdata->tx_desc_count) {
  736                         axgbe_printf(2, "tx-frames is limited to %d frames\n",
  737                             pdata->tx_desc_count);
  738                         return (-EINVAL);
  739                 }
  740 
  741                 pdata->rx_riwt = rx_riwt;
  742                 pdata->rx_usecs = rx_usecs;
  743                 pdata->rx_frames = rx_frames;
  744                 hw_if->config_rx_coalesce(pdata);
  745 
  746                 pdata->tx_frames = tx_frames;
  747                 hw_if->config_tx_coalesce(pdata);
  748         }
  749 
  750         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
  751 
  752         return (rc);
  753 }
  754 
  755 static int
  756 sysctl_pauseparam_handler(SYSCTL_HANDLER_ARGS)
  757 {
  758         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
  759         struct sysctl_op *sys_op = pdata->sys_op;
  760         struct sysctl_info sysctl_pauseparam[] = {
  761                 { "autoneg", SYSL_BOOL, autoneg, "supported" },
  762                 { "rx", SYSL_BOOL, rx_pause, "supported" },
  763                 { "tx", SYSL_BOOL, tx_pause, "supported" },
  764         };
  765         ssize_t buf_size = 512;
  766         char buf[buf_size];
  767         struct sbuf *sb;
  768         int rc = 0;
  769 
  770         if (req->newptr == NULL) {
  771                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
  772                 if (sb == NULL) {
  773                         rc = ENOMEM;
  774                         return (rc);
  775                 }
  776                 sys_op->autoneg = pdata->phy.pause_autoneg;
  777                 sys_op->tx_pause = pdata->phy.tx_pause;
  778                 sys_op->rx_pause = pdata->phy.rx_pause;
  779 
  780                 sbuf_printf(sb,
  781                     "\nAutonegotiate:   %s\n"
  782                     "RX:                %s\n"
  783                     "TX:                %s\n",
  784                     sys_op->autoneg ? "on" : "off",
  785                     sys_op->rx_pause ? "on" : "off",
  786                     sys_op->tx_pause ? "on" : "off");
  787 
  788                 if (pdata->phy.lp_advertising) {
  789                         int an_rx = 0, an_tx = 0;
  790 
  791                         if (pdata->phy.advertising & pdata->phy.lp_advertising &
  792                             ADVERTISED_Pause) {
  793                                 an_tx = 1;
  794                                 an_rx = 1;
  795                         } else if (pdata->phy.advertising &
  796                             pdata->phy.lp_advertising & ADVERTISED_Asym_Pause) {
  797                                 if (pdata->phy.advertising & ADVERTISED_Pause)
  798                                         an_rx = 1;
  799                                 else if (pdata->phy.lp_advertising &
  800                                     ADVERTISED_Pause)
  801                                 an_tx = 1;
  802                         }
  803                         sbuf_printf(sb,
  804                             "\n->\nRX negotiated:       %s\n"
  805                             "TX negotiated:     %s\n",
  806                             an_rx ? "on" : "off",
  807                             an_tx ? "on" : "off");
  808                 }
  809                 rc = sbuf_finish(sb);
  810                 sbuf_delete(sb);
  811                 return (0);
  812         }
  813 
  814         rc = get_ubuf(req, buf);
  815         if (rc == 0) {
  816                 parse_generic_sysctl(pdata, buf, sysctl_pauseparam,
  817                     ARRAY_SIZE(sysctl_pauseparam));
  818 
  819                 if (sys_op->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE)) {
  820                         axgbe_error("autoneg disabled, pause autoneg not available\n");
  821                         return (-EINVAL);
  822                 }
  823 
  824                 pdata->phy.pause_autoneg = sys_op->autoneg;
  825                 pdata->phy.tx_pause = sys_op->tx_pause;
  826                 pdata->phy.rx_pause = sys_op->rx_pause;
  827 
  828                 XGBE_CLR_ADV(&pdata->phy, Pause);
  829                 XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
  830 
  831                 if (sys_op->rx_pause) {
  832                         XGBE_SET_ADV(&pdata->phy, Pause);
  833                         XGBE_SET_ADV(&pdata->phy, Asym_Pause);
  834                 }
  835 
  836                 if (sys_op->tx_pause) {
  837                         /* Equivalent to XOR of Asym_Pause */
  838                         if (XGBE_ADV(&pdata->phy, Asym_Pause))
  839                                 XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
  840                         else
  841                                 XGBE_SET_ADV(&pdata->phy, Asym_Pause);
  842                 }
  843 
  844                 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
  845                         rc = pdata->phy_if.phy_config_aneg(pdata);
  846 
  847         }
  848 
  849         return (rc);
  850 }
  851 
  852 static int
  853 sysctl_link_ksettings_handler(SYSCTL_HANDLER_ARGS)
  854 {
  855         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
  856         struct sysctl_op *sys_op = pdata->sys_op;
  857         struct sysctl_info sysctl_linksettings[] = {
  858                 { "autoneg", SYSL_BOOL, autoneg, "supported" },
  859                 { "speed", SYSL_U32, speed, "supported" },
  860                 { "duplex", SYSL_U8, duplex, "supported" },
  861         };
  862         ssize_t buf_size = 512;
  863         char buf[buf_size], link_modes[16], speed_modes[16];
  864         struct sbuf *sb;
  865         uint32_t speed;
  866         int rc = 0;
  867 
  868         if (req->newptr == NULL) {
  869                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
  870                 if (sb == NULL) {
  871                         rc = ENOMEM;
  872                         return (rc);
  873                 }
  874                 sys_op->autoneg = pdata->phy.autoneg;
  875                 sys_op->speed = pdata->phy.speed;
  876                 sys_op->duplex = pdata->phy.duplex;
  877 
  878                 XGBE_LM_COPY(&pdata->phy, supported, &pdata->phy, supported);
  879                 XGBE_LM_COPY(&pdata->phy, advertising, &pdata->phy, advertising);
  880                 XGBE_LM_COPY(&pdata->phy, lp_advertising, &pdata->phy, lp_advertising);
  881 
  882                 switch (sys_op->speed) {
  883                 case 1:
  884                         strcpy(link_modes, "Unknown");
  885                         strcpy(speed_modes, "Unknown");
  886                         break;
  887                 case 2:
  888                         strcpy(link_modes, "10Gbps/Full");
  889                         strcpy(speed_modes, "10000");
  890                         break;
  891                 case 3: 
  892                         strcpy(link_modes, "2.5Gbps/Full");
  893                         strcpy(speed_modes, "2500");
  894                         break;
  895                 case 4: 
  896                         strcpy(link_modes, "1Gbps/Full");
  897                         strcpy(speed_modes, "1000");
  898                         break;
  899                 case 5: 
  900                         strcpy(link_modes, "100Mbps/Full");
  901                         strcpy(speed_modes, "100");
  902                         break;
  903                 case 6:
  904                         strcpy(link_modes, "10Mbps/Full");
  905                         strcpy(speed_modes, "10");
  906                         break;
  907                 }
  908                         
  909                 sbuf_printf(sb,
  910                     "\nlink_modes: %s\n"
  911                     "autonegotiation: %s\n"
  912                     "speed: %sMbps\n",
  913                     link_modes,
  914                     (sys_op->autoneg == AUTONEG_DISABLE) ? "off" : "on",
  915                     speed_modes);
  916 
  917                 switch (sys_op->duplex) {
  918                         case DUPLEX_HALF:
  919                                 sbuf_printf(sb, "Duplex: Half\n");
  920                                 break;
  921                         case DUPLEX_FULL:
  922                                 sbuf_printf(sb, "Duplex: Full\n");
  923                                 break;
  924                         default:
  925                                 sbuf_printf(sb, "Duplex: Unknown\n");
  926                                 break;
  927                 }
  928                 rc = sbuf_finish(sb);
  929                 sbuf_delete(sb);
  930                 return (0);
  931         }
  932 
  933         rc = get_ubuf(req, buf);
  934         if (rc == 0) {
  935                 parse_generic_sysctl(pdata, buf, sysctl_linksettings,
  936                     ARRAY_SIZE(sysctl_linksettings));
  937 
  938                 speed = sys_op->speed;
  939 
  940                 if ((sys_op->autoneg != AUTONEG_ENABLE) &&
  941                     (sys_op->autoneg != AUTONEG_DISABLE)) {
  942                         axgbe_error("unsupported autoneg %hhu\n",
  943                             (unsigned char)sys_op->autoneg);
  944                         return (-EINVAL);
  945                 }
  946 
  947                 if (sys_op->autoneg == AUTONEG_DISABLE) {
  948                         if (!pdata->phy_if.phy_valid_speed(pdata, speed)) {
  949                                 axgbe_error("unsupported speed %u\n", speed);
  950                                 return (-EINVAL);
  951                         }
  952 
  953                         if (sys_op->duplex != DUPLEX_FULL) {
  954                                 axgbe_error("unsupported duplex %hhu\n",
  955                                     (unsigned char)sys_op->duplex);
  956                                 return (-EINVAL);
  957                         }
  958                 }
  959 
  960                 pdata->phy.autoneg = sys_op->autoneg;
  961                 pdata->phy.speed = speed;
  962                 pdata->phy.duplex = sys_op->duplex;
  963 
  964                 if (sys_op->autoneg == AUTONEG_ENABLE)
  965                         XGBE_SET_ADV(&pdata->phy, Autoneg);
  966                 else
  967                         XGBE_CLR_ADV(&pdata->phy, Autoneg);
  968 
  969                 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
  970                         rc = pdata->phy_if.phy_config_aneg(pdata);
  971         }
  972 
  973         return (rc);
  974 }
  975 
  976 static int
  977 sysctl_ringparam_handler(SYSCTL_HANDLER_ARGS)
  978 {
  979         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
  980         struct sysctl_op *sys_op = pdata->sys_op;
  981         struct sysctl_info sysctl_ringparam[] = {
  982                 { "rx", SYSL_S32, rx_pending, "supported" },
  983                 { "rx-mini", SYSL_S32, rx_mini_pending, "supported" },
  984                 { "rx-jumbo", SYSL_S32, rx_jumbo_pending, "supported" },
  985                 { "tx", SYSL_S32, tx_pending, "supported" },
  986         };
  987         ssize_t buf_size = 512;
  988         unsigned int rx, tx;
  989         char buf[buf_size];
  990         struct sbuf *sb;
  991         int rc = 0;
  992 
  993         if (req->newptr == NULL) {
  994                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
  995                 if (sb == NULL) {
  996                         rc = ENOMEM;
  997                         return (rc);
  998                 }
  999                 sys_op->rx_max_pending = XGBE_RX_DESC_CNT_MAX;
 1000                 sys_op->tx_max_pending = XGBE_TX_DESC_CNT_MAX;
 1001                 sys_op->rx_pending = pdata->rx_desc_count;
 1002                 sys_op->tx_pending = pdata->tx_desc_count;
 1003 
 1004                 sbuf_printf(sb,
 1005                     "\nPre-set maximums:\n"
 1006                     "RX:                %u\n"
 1007                     "RX Mini:   %u\n"
 1008                     "RX Jumbo:  %u\n"
 1009                     "TX:                %u\n",
 1010                     sys_op->rx_max_pending,
 1011                     sys_op->rx_mini_max_pending,
 1012                     sys_op->rx_jumbo_max_pending,
 1013                     sys_op->tx_max_pending);
 1014 
 1015                 sbuf_printf(sb,
 1016                     "\nCurrent hardware settings:\n"
 1017                     "RX:                %u\n"
 1018                     "RX Mini:   %u\n"
 1019                     "RX Jumbo:  %u\n"
 1020                     "TX:                %u\n",
 1021                     sys_op->rx_pending,
 1022                     sys_op->rx_mini_pending,
 1023                     sys_op->rx_jumbo_pending,
 1024                     sys_op->tx_pending);
 1025 
 1026                 rc = sbuf_finish(sb);
 1027                 sbuf_delete(sb);
 1028                 return (0);
 1029         }
 1030 
 1031         rc = get_ubuf(req, buf);
 1032         if (rc == 0) {
 1033                 parse_generic_sysctl(pdata, buf, sysctl_ringparam,
 1034                     ARRAY_SIZE(sysctl_ringparam));
 1035 
 1036                 if (sys_op->rx_mini_pending || sys_op->rx_jumbo_pending) {
 1037                         axgbe_error("unsupported ring parameter\n");
 1038                         return (-EINVAL);
 1039                 }
 1040 
 1041                 if ((sys_op->rx_pending < XGBE_RX_DESC_CNT_MIN) ||
 1042                                 (sys_op->rx_pending > XGBE_RX_DESC_CNT_MAX)) {
 1043                         axgbe_error("rx ring param must be between %u and %u\n",
 1044                             XGBE_RX_DESC_CNT_MIN, XGBE_RX_DESC_CNT_MAX);
 1045                         return (-EINVAL);
 1046                 }
 1047 
 1048                 if ((sys_op->tx_pending < XGBE_TX_DESC_CNT_MIN) ||
 1049                                 (sys_op->tx_pending > XGBE_TX_DESC_CNT_MAX)) {
 1050                         axgbe_error("tx ring param must be between %u and %u\n",
 1051                             XGBE_TX_DESC_CNT_MIN, XGBE_TX_DESC_CNT_MAX);
 1052                         return (-EINVAL);
 1053                 }
 1054 
 1055                 rx = __rounddown_pow_of_two(sys_op->rx_pending);
 1056                 if (rx != sys_op->rx_pending)
 1057                         axgbe_printf(1, "rx ring param rounded to power of 2: %u\n",
 1058                             rx);
 1059 
 1060                 tx = __rounddown_pow_of_two(sys_op->tx_pending);
 1061                 if (tx != sys_op->tx_pending)
 1062                         axgbe_printf(1, "tx ring param rounded to power of 2: %u\n",
 1063                             tx);
 1064 
 1065                 if ((rx == pdata->rx_desc_count) &&
 1066                     (tx == pdata->tx_desc_count))
 1067                         goto out;
 1068 
 1069                 pdata->rx_desc_count = rx;
 1070                 pdata->tx_desc_count = tx;
 1071 
 1072                 /* TODO - restart dev */
 1073         }
 1074 
 1075 out:
 1076         return (0);
 1077 }
 1078 
 1079 static int
 1080 sysctl_channels_handler(SYSCTL_HANDLER_ARGS)
 1081 {
 1082         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1083         struct sysctl_op *sys_op = pdata->sys_op;
 1084         struct sysctl_info sysctl_channels[] = {
 1085                 { "rx", SYSL_S32, rx_count, "supported" },
 1086                 { "tx", SYSL_S32, tx_count, "supported" },
 1087                 { "other", SYSL_S32, other_count, "supported" },
 1088                 { "combined", SYSL_S32, combined_count, "supported" },
 1089         };
 1090         unsigned int rx, tx, combined;
 1091         ssize_t buf_size = 512;
 1092         char buf[buf_size];
 1093         struct sbuf *sb;
 1094         int rc = 0;
 1095 
 1096         if (req->newptr == NULL) {
 1097                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1098                 if (sb == NULL) {
 1099                         rc = ENOMEM;
 1100                         return (rc);
 1101                 }
 1102                 rx = min(pdata->hw_feat.rx_ch_cnt, pdata->rx_max_channel_count);
 1103                 rx = min(rx, pdata->channel_irq_count);
 1104                 tx = min(pdata->hw_feat.tx_ch_cnt, pdata->tx_max_channel_count);
 1105                 tx = min(tx, pdata->channel_irq_count);
 1106                 tx = min(tx, pdata->tx_max_q_count);
 1107 
 1108                 combined = min(rx, tx);
 1109 
 1110                 sys_op->max_combined = combined;
 1111                 sys_op->max_rx = rx ? rx - 1 : 0;
 1112                 sys_op->max_tx = tx ? tx - 1 : 0;
 1113 
 1114                 /* Get current settings based on device state */
 1115                 rx = pdata->rx_ring_count;
 1116                 tx = pdata->tx_ring_count;
 1117 
 1118                 combined = min(rx, tx);
 1119                 rx -= combined;
 1120                 tx -= combined;
 1121 
 1122                 sys_op->combined_count = combined;
 1123                 sys_op->rx_count = rx;
 1124                 sys_op->tx_count = tx;
 1125 
 1126                 sbuf_printf(sb,
 1127                     "\nPre-set maximums:\n"
 1128                     "RX:                %u\n"
 1129                     "TX:                %u\n"
 1130                     "Other:             %u\n"
 1131                     "Combined:  %u\n",
 1132                     sys_op->max_rx, sys_op->max_tx,
 1133                     sys_op->max_other,
 1134                     sys_op->max_combined);
 1135 
 1136                 sbuf_printf(sb,
 1137                     "\nCurrent hardware settings:\n"
 1138                     "RX:                %u\n"
 1139                     "TX:                %u\n"
 1140                     "Other:             %u\n"
 1141                     "Combined:  %u\n",
 1142                     sys_op->rx_count, sys_op->tx_count,
 1143                     sys_op->other_count,
 1144                     sys_op->combined_count);
 1145 
 1146                 rc = sbuf_finish(sb);
 1147                 sbuf_delete(sb);
 1148                 return (0);
 1149         }
 1150 
 1151         rc = get_ubuf(req, buf);
 1152         if (rc == 0) {
 1153                 parse_generic_sysctl(pdata, buf, sysctl_channels,
 1154                     ARRAY_SIZE(sysctl_channels));
 1155 
 1156                 axgbe_error( "channel inputs: combined=%u, rx-only=%u,"
 1157                     " tx-only=%u\n", sys_op->combined_count,
 1158                     sys_op->rx_count, sys_op->tx_count);
 1159         }
 1160 
 1161         return (rc);
 1162 }
 1163 
 1164 
 1165 static int
 1166 sysctl_mac_stats_handler(SYSCTL_HANDLER_ARGS)
 1167 {
 1168         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1169         ssize_t buf_size = 64;
 1170         struct sbuf *sb;
 1171         int rc = 0;
 1172         int i;
 1173 
 1174         if (req->newptr == NULL) {
 1175                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1176                 if (sb == NULL) {
 1177                         rc = ENOMEM;
 1178                         return (rc);
 1179                 }
 1180 
 1181                 pdata->hw_if.read_mmc_stats(pdata);
 1182                 for (i = 0; i < XGBE_STATS_COUNT; i++) {
 1183                 sbuf_printf(sb, "\n %s: %lu",
 1184                     xgbe_gstring_stats[i].stat_string,
 1185                     *(uint64_t *)((uint8_t *)pdata + xgbe_gstring_stats[i].stat_offset));
 1186                 }
 1187                 for (i = 0; i < pdata->tx_ring_count; i++) {
 1188                         sbuf_printf(sb,
 1189                             "\n txq_packets[%d]: %lu"
 1190                             "\n txq_bytes[%d]: %lu",
 1191                             i, pdata->ext_stats.txq_packets[i],
 1192                             i, pdata->ext_stats.txq_bytes[i]);
 1193                 }
 1194                 for (i = 0; i < pdata->rx_ring_count; i++) {
 1195                         sbuf_printf(sb,
 1196                             "\n rxq_packets[%d]: %lu"
 1197                             "\n rxq_bytes[%d]: %lu",
 1198                             i, pdata->ext_stats.rxq_packets[i],
 1199                             i, pdata->ext_stats.rxq_bytes[i]);
 1200                 }
 1201 
 1202                 rc = sbuf_finish(sb);
 1203                 sbuf_delete(sb);
 1204                 return (rc);
 1205         }
 1206 
 1207         return (-EINVAL);
 1208 }
 1209 
 1210 static int
 1211 sysctl_xgmac_reg_value_handler(SYSCTL_HANDLER_ARGS)
 1212 {
 1213         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1214         ssize_t buf_size = 64;
 1215         char buf[buf_size];
 1216         unsigned int value;
 1217         struct sbuf *sb;
 1218         int rc = 0;
 1219 
 1220         if (req->newptr == NULL) {
 1221                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1222                 if (sb == NULL) {
 1223                         rc = ENOMEM;
 1224                         return (rc);
 1225                 }
 1226 
 1227                 value = XGMAC_IOREAD(pdata, pdata->sysctl_xgmac_reg);
 1228                 axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
 1229                 sbuf_printf(sb, "\nXGMAC reg_value:     0x%x\n", value);
 1230                 rc = sbuf_finish(sb);
 1231                 sbuf_delete(sb);
 1232                 return (rc);
 1233         }
 1234 
 1235         rc = get_ubuf(req, buf);
 1236         if (rc == 0) {
 1237                 sscanf(buf, "%x", &value);
 1238                 axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
 1239                 XGMAC_IOWRITE(pdata, pdata->sysctl_xgmac_reg, value);
 1240         }
 1241 
 1242         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1243         return (rc);
 1244 }
 1245 
 1246 static int
 1247 sysctl_xpcs_mmd_reg_handler(SYSCTL_HANDLER_ARGS)
 1248 {
 1249         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1250         ssize_t buf_size = 64;
 1251         char buf[buf_size];
 1252         struct sbuf *sb;
 1253         unsigned int reg;
 1254         int rc = 0;
 1255 
 1256         if (req->newptr == NULL) {
 1257                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1258                 if (sb == NULL) {
 1259                         rc = ENOMEM;
 1260                         return (rc);
 1261                 }
 1262 
 1263                 axgbe_printf(2, "READ: %s: xpcs_mmd: 0x%x\n",  __func__,
 1264                     pdata->sysctl_xpcs_mmd);
 1265                 sbuf_printf(sb, "\nXPCS mmd_reg:        0x%x\n",
 1266                     pdata->sysctl_xpcs_mmd);
 1267                 rc = sbuf_finish(sb);
 1268                 sbuf_delete(sb);
 1269                 return (rc);
 1270         }
 1271 
 1272         rc = get_ubuf(req, buf);
 1273         if (rc == 0) {
 1274                 sscanf(buf, "%x", &reg);
 1275                 axgbe_printf(2, "WRITE: %s: mmd_reg: 0x%x\n",  __func__, reg);
 1276                 pdata->sysctl_xpcs_mmd = reg;
 1277         }
 1278 
 1279         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1280         return (rc);
 1281 }
 1282 
 1283 static int
 1284 sysctl_xpcs_reg_addr_handler(SYSCTL_HANDLER_ARGS)
 1285 {
 1286         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1287         ssize_t buf_size = 64;
 1288         char buf[buf_size];
 1289         struct sbuf *sb;
 1290         unsigned int reg;
 1291         int rc = 0;
 1292 
 1293         if (req->newptr == NULL) {
 1294                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1295                 if (sb == NULL) {
 1296                         rc = ENOMEM;
 1297                         return (rc);
 1298                 }
 1299 
 1300                 axgbe_printf(2, "READ: %s: sysctl_xpcs_reg: 0x%x\n",  __func__,
 1301                     pdata->sysctl_xpcs_reg);
 1302                 sbuf_printf(sb, "\nXPCS reg_addr:       0x%x\n",
 1303                     pdata->sysctl_xpcs_reg);
 1304                 rc = sbuf_finish(sb);
 1305                 sbuf_delete(sb);
 1306                 return (rc);
 1307         }
 1308 
 1309         rc = get_ubuf(req, buf);
 1310         if (rc == 0) {
 1311                 sscanf(buf, "%x", &reg);
 1312                 axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
 1313                 pdata->sysctl_xpcs_reg = reg;
 1314         }
 1315 
 1316         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1317         return (rc);
 1318 }
 1319 
 1320 static int
 1321 sysctl_xpcs_reg_value_handler(SYSCTL_HANDLER_ARGS)
 1322 {
 1323         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1324         ssize_t buf_size = 64;
 1325         char buf[buf_size];
 1326         unsigned int value;
 1327         struct sbuf *sb;
 1328         int rc = 0;
 1329 
 1330         if (req->newptr == NULL) {
 1331                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1332                 if (sb == NULL) {
 1333                         rc = ENOMEM;
 1334                         return (rc);
 1335                 }
 1336 
 1337                 value = XMDIO_READ(pdata, pdata->sysctl_xpcs_mmd,
 1338                     pdata->sysctl_xpcs_reg);
 1339                 axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
 1340                 sbuf_printf(sb, "\nXPCS reg_value:      0x%x\n", value);
 1341                 rc = sbuf_finish(sb);
 1342                 sbuf_delete(sb);
 1343                 return (rc);
 1344         }
 1345 
 1346         rc = get_ubuf(req, buf);
 1347         if (rc == 0) {
 1348                 sscanf(buf, "%x", &value);
 1349                 axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
 1350                 XMDIO_WRITE(pdata, pdata->sysctl_xpcs_mmd,
 1351                     pdata->sysctl_xpcs_reg, value);
 1352         }
 1353 
 1354         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1355         return (rc);
 1356 }
 1357 
 1358 static int
 1359 sysctl_xprop_reg_addr_handler(SYSCTL_HANDLER_ARGS)
 1360 {
 1361         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1362         ssize_t buf_size = 64;
 1363         char buf[buf_size];
 1364         struct sbuf *sb;
 1365         unsigned int reg;
 1366         int rc = 0;
 1367 
 1368         if (req->newptr == NULL) {
 1369                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1370                 if (sb == NULL) {
 1371                         rc = ENOMEM;
 1372                         return (rc);
 1373                 }
 1374 
 1375                 axgbe_printf(2, "READ: %s: sysctl_xprop_reg: 0x%x\n",  __func__,
 1376                     pdata->sysctl_xprop_reg);
 1377                 sbuf_printf(sb, "\nXPROP reg_addr:      0x%x\n",
 1378                     pdata->sysctl_xprop_reg);
 1379                 rc = sbuf_finish(sb);
 1380                 sbuf_delete(sb);
 1381                 return (rc);
 1382         }
 1383 
 1384         rc = get_ubuf(req, buf);
 1385         if (rc == 0) {
 1386                 sscanf(buf, "%x", &reg);
 1387                 axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
 1388                 pdata->sysctl_xprop_reg = reg;
 1389         }
 1390 
 1391         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1392         return (rc);
 1393 }
 1394 
 1395 static int
 1396 sysctl_xprop_reg_value_handler(SYSCTL_HANDLER_ARGS)
 1397 {
 1398         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1399         ssize_t buf_size = 64;
 1400         char buf[buf_size];
 1401         unsigned int value;
 1402         struct sbuf *sb;
 1403         int rc = 0;
 1404 
 1405         if (req->newptr == NULL) {
 1406                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1407                 if (sb == NULL) {
 1408                         rc = ENOMEM;
 1409                         return (rc);
 1410                 }
 1411 
 1412                 value = XP_IOREAD(pdata, pdata->sysctl_xprop_reg);
 1413                 axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
 1414                 sbuf_printf(sb, "\nXPROP reg_value:     0x%x\n", value);
 1415                 rc = sbuf_finish(sb);
 1416                 sbuf_delete(sb);
 1417                 return (rc);
 1418         }
 1419 
 1420         rc = get_ubuf(req, buf);
 1421         if (rc == 0) {
 1422                 sscanf(buf, "%x", &value);
 1423                 axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
 1424                 XP_IOWRITE(pdata, pdata->sysctl_xprop_reg, value);
 1425         }
 1426 
 1427         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1428         return (rc);
 1429 }
 1430 
 1431 static int
 1432 sysctl_xi2c_reg_addr_handler(SYSCTL_HANDLER_ARGS)
 1433 {
 1434         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1435         ssize_t buf_size = 64;
 1436         char buf[buf_size];
 1437         struct sbuf *sb;
 1438         unsigned int reg;
 1439         int rc = 0;
 1440 
 1441         if (req->newptr == NULL) {
 1442                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1443                 if (sb == NULL) {
 1444                         rc = ENOMEM;
 1445                         return (rc);
 1446                 }
 1447 
 1448                 axgbe_printf(2, "READ: %s: sysctl_xi2c_reg: 0x%x\n",  __func__,
 1449                     pdata->sysctl_xi2c_reg);
 1450                 sbuf_printf(sb, "\nXI2C reg_addr:       0x%x\n",
 1451                     pdata->sysctl_xi2c_reg);
 1452                 rc = sbuf_finish(sb);
 1453                 sbuf_delete(sb);
 1454                 return (rc);
 1455         }
 1456 
 1457         rc = get_ubuf(req, buf);
 1458         if (rc == 0) {
 1459                 sscanf(buf, "%x", &reg);
 1460                 axgbe_printf(2, "WRITE: %s: reg: 0x%x\n",  __func__, reg);
 1461                 pdata->sysctl_xi2c_reg = reg;
 1462         }
 1463 
 1464         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1465         return (rc);
 1466 }
 1467 
 1468 static int
 1469 sysctl_xi2c_reg_value_handler(SYSCTL_HANDLER_ARGS)
 1470 {
 1471         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1472         ssize_t buf_size = 64;
 1473         char buf[buf_size];
 1474         unsigned int value;
 1475         struct sbuf *sb;
 1476         int rc = 0;
 1477 
 1478         if (req->newptr == NULL) {
 1479                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1480                 if (sb == NULL) {
 1481                         rc = ENOMEM;
 1482                         return (rc);
 1483                 }
 1484 
 1485                 value = XI2C_IOREAD(pdata, pdata->sysctl_xi2c_reg);
 1486                 axgbe_printf(2, "READ: %s: value: 0x%x\n",  __func__, value);
 1487                 sbuf_printf(sb, "\nXI2C reg_value:      0x%x\n", value);
 1488                 rc = sbuf_finish(sb);
 1489                 sbuf_delete(sb);
 1490                 return (rc);
 1491         }
 1492 
 1493         rc = get_ubuf(req, buf);
 1494         if (rc == 0) {
 1495                 sscanf(buf, "%x", &value);
 1496                 axgbe_printf(2, "WRITE: %s: value: 0x%x\n",  __func__, value);
 1497                 XI2C_IOWRITE(pdata, pdata->sysctl_xi2c_reg, value);
 1498         }
 1499 
 1500         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1501         return (rc);
 1502 }
 1503 
 1504 static int
 1505 sysctl_an_cdr_wr_handler(SYSCTL_HANDLER_ARGS)
 1506 {
 1507         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1508         unsigned int an_cdr_wr = 0;
 1509         ssize_t buf_size = 64;
 1510         char buf[buf_size];
 1511         struct sbuf *sb;
 1512         int rc = 0;
 1513 
 1514         if (req->newptr == NULL) {
 1515                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1516                 if (sb == NULL) {
 1517                         rc = ENOMEM;
 1518                         return (rc);
 1519                 }
 1520 
 1521                 axgbe_printf(2, "READ: %s: an_cdr_wr: %d\n",  __func__,
 1522                     pdata->sysctl_an_cdr_workaround);
 1523                 sbuf_printf(sb, "%d\n", pdata->sysctl_an_cdr_workaround);
 1524                 rc = sbuf_finish(sb);
 1525                 sbuf_delete(sb);
 1526                 return (rc);
 1527         }
 1528 
 1529         rc = get_ubuf(req, buf);
 1530         if (rc == 0) {
 1531                 sscanf(buf, "%u", &an_cdr_wr);
 1532                 axgbe_printf(2, "WRITE: %s: an_cdr_wr: 0x%d\n",  __func__,
 1533                     an_cdr_wr);
 1534 
 1535                 if (an_cdr_wr)
 1536                         pdata->sysctl_an_cdr_workaround = 1;
 1537                 else
 1538                         pdata->sysctl_an_cdr_workaround = 0;
 1539         }
 1540 
 1541         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1542         return (rc);
 1543 }
 1544 
 1545 static int
 1546 sysctl_an_cdr_track_early_handler(SYSCTL_HANDLER_ARGS)
 1547 {
 1548         struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
 1549         unsigned int an_cdr_track_early = 0;
 1550         ssize_t buf_size = 64;
 1551         char buf[buf_size];
 1552         struct sbuf *sb;
 1553         int rc = 0;
 1554 
 1555         if (req->newptr == NULL) {
 1556                 sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
 1557                 if (sb == NULL) {
 1558                         rc = ENOMEM;
 1559                         return (rc);
 1560                 }
 1561 
 1562                 axgbe_printf(2, "READ: %s: an_cdr_track_early %d\n",  __func__,
 1563                     pdata->sysctl_an_cdr_track_early);
 1564                 sbuf_printf(sb, "%d\n", pdata->sysctl_an_cdr_track_early);                      
 1565                 rc = sbuf_finish(sb);
 1566                 sbuf_delete(sb);
 1567                 return (rc);
 1568         }
 1569 
 1570         rc = get_ubuf(req, buf);
 1571         if (rc == 0) {
 1572                 sscanf(buf, "%u", &an_cdr_track_early);
 1573                 axgbe_printf(2, "WRITE: %s: an_cdr_track_early: %d\n",  __func__,
 1574                     an_cdr_track_early);
 1575 
 1576                 if (an_cdr_track_early)
 1577                         pdata->sysctl_an_cdr_track_early = 1;
 1578                 else
 1579                         pdata->sysctl_an_cdr_track_early = 0;
 1580         }
 1581 
 1582         axgbe_printf(2, "%s: rc= %d\n",  __func__, rc);
 1583         return (rc);
 1584 }
 1585 
 1586 void
 1587 axgbe_sysctl_exit(struct xgbe_prv_data *pdata)
 1588 {
 1589 
 1590         if (pdata->sys_op)
 1591                 free(pdata->sys_op, M_AXGBE);
 1592 }
 1593 
 1594 void 
 1595 axgbe_sysctl_init(struct xgbe_prv_data *pdata)
 1596 {
 1597         struct sysctl_ctx_list *clist;
 1598         struct sysctl_oid_list *top;
 1599         struct sysctl_oid *parent; 
 1600         struct sysctl_op *sys_op;
 1601 
 1602         sys_op = malloc(sizeof(*sys_op), M_AXGBE, M_WAITOK | M_ZERO);
 1603         pdata->sys_op = sys_op;
 1604 
 1605         clist = device_get_sysctl_ctx(pdata->dev); 
 1606         parent = device_get_sysctl_tree(pdata->dev);
 1607         top = SYSCTL_CHILDREN(parent);
 1608 
 1609         /* Set defaults */
 1610         pdata->sysctl_xgmac_reg = 0;
 1611         pdata->sysctl_xpcs_mmd = 1;
 1612         pdata->sysctl_xpcs_reg = 0;
 1613 
 1614         SYSCTL_ADD_UINT(clist, top, OID_AUTO, "axgbe_debug_level", CTLFLAG_RWTUN,
 1615             &pdata->debug_level, 0, "axgbe log level -- higher is verbose");
 1616 
 1617         SYSCTL_ADD_UINT(clist, top, OID_AUTO, "sph_enable",
 1618             CTLFLAG_RDTUN, &pdata->sph_enable, 1,
 1619             "shows the split header feature state (1 - enable, 0 - disable");
 1620 
 1621         SYSCTL_ADD_UINT(clist, top, OID_AUTO, "link_workaround",
 1622             CTLFLAG_RWTUN, &pdata->link_workaround, 0,
 1623             "enable the workaround for link issue in coming up");
 1624 
 1625         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xgmac_register",
 1626             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1627             pdata, 0, sysctl_xgmac_reg_addr_handler, "IU",
 1628             "xgmac register addr");
 1629 
 1630         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xgmac_register_value",
 1631             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1632             pdata, 0, sysctl_xgmac_reg_value_handler, "IU",
 1633             "xgmac register value");
 1634 
 1635         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_mmd",
 1636             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1637             pdata, 0, sysctl_xpcs_mmd_reg_handler, "IU", "xpcs mmd register");
 1638 
 1639         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_register",
 1640             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1641             pdata, 0, sysctl_xpcs_reg_addr_handler, "IU", "xpcs register");
 1642 
 1643         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_register_value",
 1644             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1645             pdata, 0, sysctl_xpcs_reg_value_handler, "IU",
 1646             "xpcs register value");
 1647 
 1648         if (pdata->xpcs_res) {
 1649                 SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xprop_register",
 1650                     CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1651                     pdata, 0, sysctl_xprop_reg_addr_handler,
 1652                     "IU", "xprop register");
 1653 
 1654                 SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xprop_register_value",
 1655                     CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1656                     pdata, 0, sysctl_xprop_reg_value_handler,
 1657                     "IU", "xprop register value");
 1658         }
 1659 
 1660         if (pdata->xpcs_res) {
 1661                 SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xi2c_register",
 1662                     CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1663                     pdata, 0, sysctl_xi2c_reg_addr_handler,
 1664                     "IU", "xi2c register");
 1665 
 1666                 SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xi2c_register_value",
 1667                     CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1668                     pdata, 0, sysctl_xi2c_reg_value_handler,
 1669                     "IU", "xi2c register value");
 1670         }
 1671 
 1672         if (pdata->vdata->an_cdr_workaround) {
 1673                 SYSCTL_ADD_PROC(clist, top, OID_AUTO, "an_cdr_workaround",
 1674                     CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1675                     pdata, 0, sysctl_an_cdr_wr_handler, "IU",
 1676                     "an cdr workaround");
 1677 
 1678                 SYSCTL_ADD_PROC(clist, top, OID_AUTO, "an_cdr_track_early",
 1679                     CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1680                     pdata, 0, sysctl_an_cdr_track_early_handler, "IU",
 1681                     "an cdr track early");
 1682         }
 1683 
 1684         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "drv_info",
 1685             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1686             pdata, 0, sysctl_get_drv_info_handler, "IU",
 1687             "xgbe drv info");
 1688 
 1689         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "link_info",
 1690             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1691             pdata, 0, sysctl_get_link_info_handler, "IU",
 1692             "xgbe link info");
 1693 
 1694         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "coalesce_info",
 1695             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1696             pdata, 0, sysctl_coalesce_handler, "IU",
 1697             "xgbe coalesce info");
 1698 
 1699         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "pauseparam_info",
 1700             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1701             pdata, 0, sysctl_pauseparam_handler, "IU",
 1702             "xgbe pauseparam info");
 1703 
 1704         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "link_ksettings_info",
 1705             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1706             pdata, 0, sysctl_link_ksettings_handler, "IU",
 1707             "xgbe link_ksettings info");
 1708 
 1709         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "ringparam_info",
 1710             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1711             pdata, 0, sysctl_ringparam_handler, "IU",
 1712             "xgbe ringparam info");
 1713 
 1714         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "channels_info",
 1715             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1716             pdata, 0, sysctl_channels_handler, "IU",
 1717             "xgbe channels info");
 1718 
 1719         SYSCTL_ADD_PROC(clist, top, OID_AUTO, "mac_stats",
 1720             CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 1721             pdata, 0, sysctl_mac_stats_handler, "IU",
 1722             "xgbe mac stats");
 1723 }

Cache object: 9804fe6d9fae5b4b583578c36a7d843a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.