t4_main.c (515a40d5d9bfae91e4c063cf862894d16dae20e5) t4_main.c (e3338dee08af91800023933673a920a729ce8438)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2011 Chelsio Communications, Inc.
5 * All rights reserved.
6 * Written by: Navdeep Parhar <np@FreeBSD.org>
7 *
8 * Redistribution and use in source and binary forms, with or without

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

673static int sysctl_btphy(SYSCTL_HANDLER_ARGS);
674static int sysctl_noflowq(SYSCTL_HANDLER_ARGS);
675static int sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS);
676static int sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS);
677static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS);
678static int sysctl_qsize_txq(SYSCTL_HANDLER_ARGS);
679static int sysctl_pause_settings(SYSCTL_HANDLER_ARGS);
680static int sysctl_fec(SYSCTL_HANDLER_ARGS);
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2011 Chelsio Communications, Inc.
5 * All rights reserved.
6 * Written by: Navdeep Parhar <np@FreeBSD.org>
7 *
8 * Redistribution and use in source and binary forms, with or without

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

673static int sysctl_btphy(SYSCTL_HANDLER_ARGS);
674static int sysctl_noflowq(SYSCTL_HANDLER_ARGS);
675static int sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS);
676static int sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS);
677static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS);
678static int sysctl_qsize_txq(SYSCTL_HANDLER_ARGS);
679static int sysctl_pause_settings(SYSCTL_HANDLER_ARGS);
680static int sysctl_fec(SYSCTL_HANDLER_ARGS);
681static int sysctl_module_fec(SYSCTL_HANDLER_ARGS);
681static int sysctl_autoneg(SYSCTL_HANDLER_ARGS);
682static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS);
683static int sysctl_temperature(SYSCTL_HANDLER_ARGS);
684static int sysctl_vdd(SYSCTL_HANDLER_ARGS);
685static int sysctl_reset_sensor(SYSCTL_HANDLER_ARGS);
686static int sysctl_loadavg(SYSCTL_HANDLER_ARGS);
687static int sysctl_cctrl(SYSCTL_HANDLER_ARGS);
688static int sysctl_cim_ibq_obq(SYSCTL_HANDLER_ARGS);

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

2388 int rc;
2389
2390 rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4mec");
2391 if (rc != 0)
2392 return (rc);
2393 PORT_LOCK(pi);
2394 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) {
2395 /* ifconfig .. media autoselect */
682static int sysctl_autoneg(SYSCTL_HANDLER_ARGS);
683static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS);
684static int sysctl_temperature(SYSCTL_HANDLER_ARGS);
685static int sysctl_vdd(SYSCTL_HANDLER_ARGS);
686static int sysctl_reset_sensor(SYSCTL_HANDLER_ARGS);
687static int sysctl_loadavg(SYSCTL_HANDLER_ARGS);
688static int sysctl_cctrl(SYSCTL_HANDLER_ARGS);
689static int sysctl_cim_ibq_obq(SYSCTL_HANDLER_ARGS);

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

2389 int rc;
2390
2391 rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4mec");
2392 if (rc != 0)
2393 return (rc);
2394 PORT_LOCK(pi);
2395 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) {
2396 /* ifconfig .. media autoselect */
2396 if (!(lc->supported & FW_PORT_CAP32_ANEG)) {
2397 if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
2397 rc = ENOTSUP; /* AN not supported by transceiver */
2398 goto done;
2399 }
2400 lc->requested_aneg = AUTONEG_ENABLE;
2401 lc->requested_speed = 0;
2402 lc->requested_fc |= PAUSE_AUTONEG;
2403 } else {
2404 lc->requested_aneg = AUTONEG_DISABLE;

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

4758 /* Leave current media alone if it's already set to IFM_NONE. */
4759 ifm = &pi->media;
4760 if (ifm->ifm_cur != NULL &&
4761 IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_NONE)
4762 return;
4763
4764 lc = &pi->link_cfg;
4765 if (lc->requested_aneg != AUTONEG_DISABLE &&
2398 rc = ENOTSUP; /* AN not supported by transceiver */
2399 goto done;
2400 }
2401 lc->requested_aneg = AUTONEG_ENABLE;
2402 lc->requested_speed = 0;
2403 lc->requested_fc |= PAUSE_AUTONEG;
2404 } else {
2405 lc->requested_aneg = AUTONEG_DISABLE;

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

4759 /* Leave current media alone if it's already set to IFM_NONE. */
4760 ifm = &pi->media;
4761 if (ifm->ifm_cur != NULL &&
4762 IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_NONE)
4763 return;
4764
4765 lc = &pi->link_cfg;
4766 if (lc->requested_aneg != AUTONEG_DISABLE &&
4766 lc->supported & FW_PORT_CAP32_ANEG) {
4767 lc->pcaps & FW_PORT_CAP32_ANEG) {
4767 ifmedia_set(ifm, IFM_ETHER | IFM_AUTO);
4768 return;
4769 }
4770 mword = IFM_ETHER | IFM_FDX;
4771 if (lc->requested_fc & PAUSE_TX)
4772 mword |= IFM_ETH_TXPAUSE;
4773 if (lc->requested_fc & PAUSE_RX)
4774 mword |= IFM_ETH_RXPAUSE;

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

4815 return;
4816
4817 /*
4818 * Rebuild the ifmedia list.
4819 */
4820 ifm = &pi->media;
4821 ifmedia_removeall(ifm);
4822 lc = &pi->link_cfg;
4768 ifmedia_set(ifm, IFM_ETHER | IFM_AUTO);
4769 return;
4770 }
4771 mword = IFM_ETHER | IFM_FDX;
4772 if (lc->requested_fc & PAUSE_TX)
4773 mword |= IFM_ETH_TXPAUSE;
4774 if (lc->requested_fc & PAUSE_RX)
4775 mword |= IFM_ETH_RXPAUSE;

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

4816 return;
4817
4818 /*
4819 * Rebuild the ifmedia list.
4820 */
4821 ifm = &pi->media;
4822 ifmedia_removeall(ifm);
4823 lc = &pi->link_cfg;
4823 ss = G_FW_PORT_CAP32_SPEED(lc->supported); /* Supported Speeds */
4824 ss = G_FW_PORT_CAP32_SPEED(lc->pcaps); /* Supported Speeds */
4824 if (__predict_false(ss == 0)) { /* not supposed to happen. */
4825 MPASS(ss != 0);
4826no_media:
4827 MPASS(LIST_EMPTY(&ifm->ifm_list));
4828 ifmedia_add(ifm, IFM_ETHER | IFM_NONE, 0, NULL);
4829 ifmedia_set(ifm, IFM_ETHER | IFM_NONE);
4830 return;
4831 }

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

4841 } else if (mword == IFM_UNKNOWN)
4842 unknown++;
4843 else
4844 ifmedia_add4(ifm, IFM_ETHER | IFM_FDX | mword);
4845 }
4846 }
4847 if (unknown > 0) /* Add one unknown for all unknown media types. */
4848 ifmedia_add4(ifm, IFM_ETHER | IFM_FDX | IFM_UNKNOWN);
4825 if (__predict_false(ss == 0)) { /* not supposed to happen. */
4826 MPASS(ss != 0);
4827no_media:
4828 MPASS(LIST_EMPTY(&ifm->ifm_list));
4829 ifmedia_add(ifm, IFM_ETHER | IFM_NONE, 0, NULL);
4830 ifmedia_set(ifm, IFM_ETHER | IFM_NONE);
4831 return;
4832 }

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

4842 } else if (mword == IFM_UNKNOWN)
4843 unknown++;
4844 else
4845 ifmedia_add4(ifm, IFM_ETHER | IFM_FDX | mword);
4846 }
4847 }
4848 if (unknown > 0) /* Add one unknown for all unknown media types. */
4849 ifmedia_add4(ifm, IFM_ETHER | IFM_FDX | IFM_UNKNOWN);
4849 if (lc->supported & FW_PORT_CAP32_ANEG)
4850 if (lc->pcaps & FW_PORT_CAP32_ANEG)
4850 ifmedia_add(ifm, IFM_ETHER | IFM_AUTO, 0, NULL);
4851
4852 set_current_media(pi);
4853}
4854
4855/*
4856 * Initialize the requested fields in the link config based on driver tunables.
4857 */

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

4869 else if (t4_autoneg == 1)
4870 lc->requested_aneg = AUTONEG_ENABLE;
4871 else
4872 lc->requested_aneg = AUTONEG_AUTO;
4873
4874 lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX |
4875 PAUSE_AUTONEG);
4876
4851 ifmedia_add(ifm, IFM_ETHER | IFM_AUTO, 0, NULL);
4852
4853 set_current_media(pi);
4854}
4855
4856/*
4857 * Initialize the requested fields in the link config based on driver tunables.
4858 */

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

4870 else if (t4_autoneg == 1)
4871 lc->requested_aneg = AUTONEG_ENABLE;
4872 else
4873 lc->requested_aneg = AUTONEG_AUTO;
4874
4875 lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX |
4876 PAUSE_AUTONEG);
4877
4877 if (t4_fec == -1 || t4_fec & FEC_AUTO)
4878 if (t4_fec & FEC_AUTO)
4878 lc->requested_fec = FEC_AUTO;
4879 lc->requested_fec = FEC_AUTO;
4879 else {
4880 else if (t4_fec == 0)
4880 lc->requested_fec = FEC_NONE;
4881 lc->requested_fec = FEC_NONE;
4881 if (t4_fec & FEC_RS)
4882 lc->requested_fec |= FEC_RS;
4883 if (t4_fec & FEC_BASER_RS)
4884 lc->requested_fec |= FEC_BASER_RS;
4882 else {
4883 /* -1 is handled by the FEC_AUTO block above and not here. */
4884 lc->requested_fec = t4_fec &
4885 (FEC_RS | FEC_BASER_RS | FEC_NONE | FEC_MODULE);
4886 if (lc->requested_fec == 0)
4887 lc->requested_fec = FEC_AUTO;
4885 }
4886}
4887
4888/*
4889 * Makes sure that all requested settings comply with what's supported by the
4890 * port. Returns the number of settings that were invalid and had to be fixed.
4891 */
4892static int
4893fixup_link_config(struct port_info *pi)
4894{
4895 int n = 0;
4896 struct link_config *lc = &pi->link_cfg;
4897 uint32_t fwspeed;
4898
4899 PORT_LOCK_ASSERT_OWNED(pi);
4900
4901 /* Speed (when not autonegotiating) */
4902 if (lc->requested_speed != 0) {
4903 fwspeed = speed_to_fwcap(lc->requested_speed);
4888 }
4889}
4890
4891/*
4892 * Makes sure that all requested settings comply with what's supported by the
4893 * port. Returns the number of settings that were invalid and had to be fixed.
4894 */
4895static int
4896fixup_link_config(struct port_info *pi)
4897{
4898 int n = 0;
4899 struct link_config *lc = &pi->link_cfg;
4900 uint32_t fwspeed;
4901
4902 PORT_LOCK_ASSERT_OWNED(pi);
4903
4904 /* Speed (when not autonegotiating) */
4905 if (lc->requested_speed != 0) {
4906 fwspeed = speed_to_fwcap(lc->requested_speed);
4904 if ((fwspeed & lc->supported) == 0) {
4907 if ((fwspeed & lc->pcaps) == 0) {
4905 n++;
4906 lc->requested_speed = 0;
4907 }
4908 }
4909
4910 /* Link autonegotiation */
4911 MPASS(lc->requested_aneg == AUTONEG_ENABLE ||
4912 lc->requested_aneg == AUTONEG_DISABLE ||
4913 lc->requested_aneg == AUTONEG_AUTO);
4914 if (lc->requested_aneg == AUTONEG_ENABLE &&
4908 n++;
4909 lc->requested_speed = 0;
4910 }
4911 }
4912
4913 /* Link autonegotiation */
4914 MPASS(lc->requested_aneg == AUTONEG_ENABLE ||
4915 lc->requested_aneg == AUTONEG_DISABLE ||
4916 lc->requested_aneg == AUTONEG_AUTO);
4917 if (lc->requested_aneg == AUTONEG_ENABLE &&
4915 !(lc->supported & FW_PORT_CAP32_ANEG)) {
4918 !(lc->pcaps & FW_PORT_CAP32_ANEG)) {
4916 n++;
4917 lc->requested_aneg = AUTONEG_AUTO;
4918 }
4919
4920 /* Flow control */
4921 MPASS((lc->requested_fc & ~(PAUSE_TX | PAUSE_RX | PAUSE_AUTONEG)) == 0);
4922 if (lc->requested_fc & PAUSE_TX &&
4919 n++;
4920 lc->requested_aneg = AUTONEG_AUTO;
4921 }
4922
4923 /* Flow control */
4924 MPASS((lc->requested_fc & ~(PAUSE_TX | PAUSE_RX | PAUSE_AUTONEG)) == 0);
4925 if (lc->requested_fc & PAUSE_TX &&
4923 !(lc->supported & FW_PORT_CAP32_FC_TX)) {
4926 !(lc->pcaps & FW_PORT_CAP32_FC_TX)) {
4924 n++;
4925 lc->requested_fc &= ~PAUSE_TX;
4926 }
4927 if (lc->requested_fc & PAUSE_RX &&
4927 n++;
4928 lc->requested_fc &= ~PAUSE_TX;
4929 }
4930 if (lc->requested_fc & PAUSE_RX &&
4928 !(lc->supported & FW_PORT_CAP32_FC_RX)) {
4931 !(lc->pcaps & FW_PORT_CAP32_FC_RX)) {
4929 n++;
4930 lc->requested_fc &= ~PAUSE_RX;
4931 }
4932 if (!(lc->requested_fc & PAUSE_AUTONEG) &&
4932 n++;
4933 lc->requested_fc &= ~PAUSE_RX;
4934 }
4935 if (!(lc->requested_fc & PAUSE_AUTONEG) &&
4933 !(lc->supported & FW_PORT_CAP32_FORCE_PAUSE)) {
4936 !(lc->pcaps & FW_PORT_CAP32_FORCE_PAUSE)) {
4934 n++;
4935 lc->requested_fc |= PAUSE_AUTONEG;
4936 }
4937
4938 /* FEC */
4939 if ((lc->requested_fec & FEC_RS &&
4937 n++;
4938 lc->requested_fc |= PAUSE_AUTONEG;
4939 }
4940
4941 /* FEC */
4942 if ((lc->requested_fec & FEC_RS &&
4940 !(lc->supported & FW_PORT_CAP32_FEC_RS)) ||
4943 !(lc->pcaps & FW_PORT_CAP32_FEC_RS)) ||
4941 (lc->requested_fec & FEC_BASER_RS &&
4944 (lc->requested_fec & FEC_BASER_RS &&
4942 !(lc->supported & FW_PORT_CAP32_FEC_BASER_RS))) {
4945 !(lc->pcaps & FW_PORT_CAP32_FEC_BASER_RS))) {
4943 n++;
4944 lc->requested_fec = FEC_AUTO;
4945 }
4946
4947 return (n);
4948}
4949
4950/*

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

4958 struct link_config *lc = &pi->link_cfg;
4959 int rc;
4960
4961#ifdef INVARIANTS
4962 ASSERT_SYNCHRONIZED_OP(sc);
4963 PORT_LOCK_ASSERT_OWNED(pi);
4964
4965 if (lc->requested_aneg == AUTONEG_ENABLE)
4946 n++;
4947 lc->requested_fec = FEC_AUTO;
4948 }
4949
4950 return (n);
4951}
4952
4953/*

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

4961 struct link_config *lc = &pi->link_cfg;
4962 int rc;
4963
4964#ifdef INVARIANTS
4965 ASSERT_SYNCHRONIZED_OP(sc);
4966 PORT_LOCK_ASSERT_OWNED(pi);
4967
4968 if (lc->requested_aneg == AUTONEG_ENABLE)
4966 MPASS(lc->supported & FW_PORT_CAP32_ANEG);
4969 MPASS(lc->pcaps & FW_PORT_CAP32_ANEG);
4967 if (!(lc->requested_fc & PAUSE_AUTONEG))
4970 if (!(lc->requested_fc & PAUSE_AUTONEG))
4968 MPASS(lc->supported & FW_PORT_CAP32_FORCE_PAUSE);
4971 MPASS(lc->pcaps & FW_PORT_CAP32_FORCE_PAUSE);
4969 if (lc->requested_fc & PAUSE_TX)
4972 if (lc->requested_fc & PAUSE_TX)
4970 MPASS(lc->supported & FW_PORT_CAP32_FC_TX);
4973 MPASS(lc->pcaps & FW_PORT_CAP32_FC_TX);
4971 if (lc->requested_fc & PAUSE_RX)
4974 if (lc->requested_fc & PAUSE_RX)
4972 MPASS(lc->supported & FW_PORT_CAP32_FC_RX);
4975 MPASS(lc->pcaps & FW_PORT_CAP32_FC_RX);
4973 if (lc->requested_fec & FEC_RS)
4976 if (lc->requested_fec & FEC_RS)
4974 MPASS(lc->supported & FW_PORT_CAP32_FEC_RS);
4977 MPASS(lc->pcaps & FW_PORT_CAP32_FEC_RS);
4975 if (lc->requested_fec & FEC_BASER_RS)
4978 if (lc->requested_fec & FEC_BASER_RS)
4976 MPASS(lc->supported & FW_PORT_CAP32_FEC_BASER_RS);
4979 MPASS(lc->pcaps & FW_PORT_CAP32_FEC_BASER_RS);
4977#endif
4978 rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc);
4979 if (rc != 0) {
4980 /* Don't complain if the VF driver gets back an EPERM. */
4981 if (!(sc->flags & IS_VF) || rc != FW_EPERM)
4982 device_printf(pi->dev, "l1cfg failed: %d\n", rc);
4983 } else {
4984 /*

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

6745 "PHY firmware version");
6746 }
6747
6748 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "pause_settings",
6749 CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_pause_settings, "A",
6750 "PAUSE settings (bit 0 = rx_pause, 1 = tx_pause, 2 = pause_autoneg)");
6751 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fec",
6752 CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_fec, "A",
4980#endif
4981 rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc);
4982 if (rc != 0) {
4983 /* Don't complain if the VF driver gets back an EPERM. */
4984 if (!(sc->flags & IS_VF) || rc != FW_EPERM)
4985 device_printf(pi->dev, "l1cfg failed: %d\n", rc);
4986 } else {
4987 /*

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

6748 "PHY firmware version");
6749 }
6750
6751 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "pause_settings",
6752 CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_pause_settings, "A",
6753 "PAUSE settings (bit 0 = rx_pause, 1 = tx_pause, 2 = pause_autoneg)");
6754 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fec",
6755 CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_fec, "A",
6753 "Forward Error Correction (bit 0 = RS, bit 1 = BASER_RS)");
6756 "FECs to use (bit 0 = RS, 1 = FC, 2 = none, 5 = auto, 6 = module)");
6757 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "module_fec",
6758 CTLTYPE_STRING, pi, 0, sysctl_module_fec, "A",
6759 "FEC recommended by the cable/transceiver");
6754 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "autoneg",
6755 CTLTYPE_INT | CTLFLAG_RW, pi, 0, sysctl_autoneg, "I",
6756 "autonegotiation (-1 = not supported)");
6757
6760 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "autoneg",
6761 CTLTYPE_INT | CTLFLAG_RW, pi, 0, sysctl_autoneg, "I",
6762 "autonegotiation (-1 = not supported)");
6763
6764 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "pcaps", CTLFLAG_RD,
6765 &pi->link_cfg.pcaps, 0, "port capabilities");
6766 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "acaps", CTLFLAG_RD,
6767 &pi->link_cfg.acaps, 0, "advertised capabilities");
6768 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "lpacaps", CTLFLAG_RD,
6769 &pi->link_cfg.lpacaps, 0, "link partner advertised capabilities");
6770
6758 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "max_speed", CTLFLAG_RD, NULL,
6759 port_top_speed(pi), "max speed (in Gbps)");
6760 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "mps_bg_map", CTLFLAG_RD, NULL,
6761 pi->mps_bg_map, "MPS buffer group map");
6762 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "rx_e_chan_map", CTLFLAG_RD,
6763 NULL, pi->rx_e_chan_map, "TP rx e-channel map");
6764
6765 if (sc->flags & IS_VF)

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

7270 struct port_info *pi = arg1;
7271 struct adapter *sc = pi->adapter;
7272 struct link_config *lc = &pi->link_cfg;
7273 int rc;
7274 int8_t old;
7275
7276 if (req->newptr == NULL) {
7277 struct sbuf *sb;
6771 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "max_speed", CTLFLAG_RD, NULL,
6772 port_top_speed(pi), "max speed (in Gbps)");
6773 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "mps_bg_map", CTLFLAG_RD, NULL,
6774 pi->mps_bg_map, "MPS buffer group map");
6775 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "rx_e_chan_map", CTLFLAG_RD,
6776 NULL, pi->rx_e_chan_map, "TP rx e-channel map");
6777
6778 if (sc->flags & IS_VF)

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

7283 struct port_info *pi = arg1;
7284 struct adapter *sc = pi->adapter;
7285 struct link_config *lc = &pi->link_cfg;
7286 int rc;
7287 int8_t old;
7288
7289 if (req->newptr == NULL) {
7290 struct sbuf *sb;
7278 static char *bits = "\20\1RS\2BASE-R\3RSVD1\4RSVD2\5RSVD3\6AUTO";
7291 static char *bits = "\20\1RS-FEC\2FC-FEC\3NO-FEC\4RSVD2"
7292 "\5RSVD3\6auto\7module";
7279
7280 rc = sysctl_wire_old_buffer(req, 0);
7281 if (rc != 0)
7282 return(rc);
7283
7284 sb = sbuf_new_for_sysctl(NULL, NULL, 128, req);
7285 if (sb == NULL)
7286 return (ENOMEM);
7287
7288 /*
7289 * Display the requested_fec when the link is down -- the actual
7290 * FEC makes sense only when the link is up.
7291 */
7292 if (lc->link_ok) {
7293 sbuf_printf(sb, "%b", (lc->fec & M_FW_PORT_CAP32_FEC) |
7293
7294 rc = sysctl_wire_old_buffer(req, 0);
7295 if (rc != 0)
7296 return(rc);
7297
7298 sb = sbuf_new_for_sysctl(NULL, NULL, 128, req);
7299 if (sb == NULL)
7300 return (ENOMEM);
7301
7302 /*
7303 * Display the requested_fec when the link is down -- the actual
7304 * FEC makes sense only when the link is up.
7305 */
7306 if (lc->link_ok) {
7307 sbuf_printf(sb, "%b", (lc->fec & M_FW_PORT_CAP32_FEC) |
7294 (lc->requested_fec & FEC_AUTO), bits);
7308 (lc->requested_fec & (FEC_AUTO | FEC_MODULE)),
7309 bits);
7295 } else {
7296 sbuf_printf(sb, "%b", lc->requested_fec, bits);
7297 }
7298 rc = sbuf_finish(sb);
7299 sbuf_delete(sb);
7300 } else {
7310 } else {
7311 sbuf_printf(sb, "%b", lc->requested_fec, bits);
7312 }
7313 rc = sbuf_finish(sb);
7314 sbuf_delete(sb);
7315 } else {
7301 char s[3];
7316 char s[8];
7302 int n;
7303
7304 snprintf(s, sizeof(s), "%d",
7305 lc->requested_fec == FEC_AUTO ? -1 :
7317 int n;
7318
7319 snprintf(s, sizeof(s), "%d",
7320 lc->requested_fec == FEC_AUTO ? -1 :
7306 lc->requested_fec & M_FW_PORT_CAP32_FEC);
7321 lc->requested_fec & (M_FW_PORT_CAP32_FEC | FEC_MODULE));
7307
7308 rc = sysctl_handle_string(oidp, s, sizeof(s), req);
7309 if (rc != 0)
7310 return(rc);
7311
7312 n = strtol(&s[0], NULL, 0);
7313 if (n < 0 || n & FEC_AUTO)
7314 n = FEC_AUTO;
7322
7323 rc = sysctl_handle_string(oidp, s, sizeof(s), req);
7324 if (rc != 0)
7325 return(rc);
7326
7327 n = strtol(&s[0], NULL, 0);
7328 if (n < 0 || n & FEC_AUTO)
7329 n = FEC_AUTO;
7315 else {
7316 if (n & ~M_FW_PORT_CAP32_FEC)
7317 return (EINVAL);/* some other bit is set too */
7318 if (!powerof2(n))
7319 return (EINVAL);/* one bit can be set at most */
7320 }
7330 else if (n & ~(M_FW_PORT_CAP32_FEC | FEC_MODULE))
7331 return (EINVAL);/* some other bit is set too */
7321
7322 rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK,
7323 "t4fec");
7324 if (rc)
7325 return (rc);
7326 PORT_LOCK(pi);
7327 old = lc->requested_fec;
7328 if (n == FEC_AUTO)
7329 lc->requested_fec = FEC_AUTO;
7332
7333 rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK,
7334 "t4fec");
7335 if (rc)
7336 return (rc);
7337 PORT_LOCK(pi);
7338 old = lc->requested_fec;
7339 if (n == FEC_AUTO)
7340 lc->requested_fec = FEC_AUTO;
7330 else if (n == 0)
7341 else if (n == 0 || n == FEC_NONE)
7331 lc->requested_fec = FEC_NONE;
7332 else {
7342 lc->requested_fec = FEC_NONE;
7343 else {
7333 if ((lc->supported | V_FW_PORT_CAP32_FEC(n)) !=
7334 lc->supported) {
7344 if ((lc->pcaps |
7345 V_FW_PORT_CAP32_FEC(n & M_FW_PORT_CAP32_FEC)) !=
7346 lc->pcaps) {
7335 rc = ENOTSUP;
7336 goto done;
7337 }
7347 rc = ENOTSUP;
7348 goto done;
7349 }
7338 lc->requested_fec = n;
7350 lc->requested_fec = n & (M_FW_PORT_CAP32_FEC |
7351 FEC_MODULE);
7339 }
7340 fixup_link_config(pi);
7341 if (pi->up_vis > 0) {
7342 rc = apply_link_config(pi);
7343 if (rc != 0) {
7344 lc->requested_fec = old;
7345 if (rc == FW_EPROTO)
7346 rc = ENOTSUP;
7347 }
7348 }
7349done:
7350 PORT_UNLOCK(pi);
7351 end_synchronized_op(sc, 0);
7352 }
7353
7354 return (rc);
7355}
7356
7357static int
7352 }
7353 fixup_link_config(pi);
7354 if (pi->up_vis > 0) {
7355 rc = apply_link_config(pi);
7356 if (rc != 0) {
7357 lc->requested_fec = old;
7358 if (rc == FW_EPROTO)
7359 rc = ENOTSUP;
7360 }
7361 }
7362done:
7363 PORT_UNLOCK(pi);
7364 end_synchronized_op(sc, 0);
7365 }
7366
7367 return (rc);
7368}
7369
7370static int
7371sysctl_module_fec(SYSCTL_HANDLER_ARGS)
7372{
7373 struct port_info *pi = arg1;
7374 struct adapter *sc = pi->adapter;
7375 struct link_config *lc = &pi->link_cfg;
7376 int rc;
7377 int8_t fec;
7378 struct sbuf *sb;
7379 static char *bits = "\20\1RS-FEC\2FC-FEC\3NO-FEC\4RSVD2\5RSVD3";
7380
7381 rc = sysctl_wire_old_buffer(req, 0);
7382 if (rc != 0)
7383 return (rc);
7384
7385 sb = sbuf_new_for_sysctl(NULL, NULL, 128, req);
7386 if (sb == NULL)
7387 return (ENOMEM);
7388
7389 if (begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4mfec") != 0)
7390 return (EBUSY);
7391 PORT_LOCK(pi);
7392 if (pi->up_vis == 0) {
7393 /*
7394 * If all the interfaces are administratively down the firmware
7395 * does not report transceiver changes. Refresh port info here.
7396 * This is the only reason we have a synchronized op in this
7397 * function. Just PORT_LOCK would have been enough otherwise.
7398 */
7399 t4_update_port_info(pi);
7400 }
7401
7402 fec = lc->fec_hint;
7403 if (pi->mod_type == FW_PORT_MOD_TYPE_NONE ||
7404 !fec_supported(lc->pcaps)) {
7405 sbuf_printf(sb, "n/a");
7406 } else {
7407 if (fec == 0)
7408 fec = FEC_NONE;
7409 sbuf_printf(sb, "%b", fec & M_FW_PORT_CAP32_FEC, bits);
7410 }
7411 rc = sbuf_finish(sb);
7412 sbuf_delete(sb);
7413
7414 PORT_UNLOCK(pi);
7415 end_synchronized_op(sc, 0);
7416
7417 return (rc);
7418}
7419
7420static int
7358sysctl_autoneg(SYSCTL_HANDLER_ARGS)
7359{
7360 struct port_info *pi = arg1;
7361 struct adapter *sc = pi->adapter;
7362 struct link_config *lc = &pi->link_cfg;
7363 int rc, val;
7364
7421sysctl_autoneg(SYSCTL_HANDLER_ARGS)
7422{
7423 struct port_info *pi = arg1;
7424 struct adapter *sc = pi->adapter;
7425 struct link_config *lc = &pi->link_cfg;
7426 int rc, val;
7427
7365 if (lc->supported & FW_PORT_CAP32_ANEG)
7428 if (lc->pcaps & FW_PORT_CAP32_ANEG)
7366 val = lc->requested_aneg == AUTONEG_DISABLE ? 0 : 1;
7367 else
7368 val = -1;
7369 rc = sysctl_handle_int(oidp, &val, 0, req);
7370 if (rc != 0 || req->newptr == NULL)
7371 return (rc);
7372 if (val == 0)
7373 val = AUTONEG_DISABLE;
7374 else if (val == 1)
7375 val = AUTONEG_ENABLE;
7376 else
7377 val = AUTONEG_AUTO;
7378
7379 rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK,
7380 "t4aneg");
7381 if (rc)
7382 return (rc);
7383 PORT_LOCK(pi);
7429 val = lc->requested_aneg == AUTONEG_DISABLE ? 0 : 1;
7430 else
7431 val = -1;
7432 rc = sysctl_handle_int(oidp, &val, 0, req);
7433 if (rc != 0 || req->newptr == NULL)
7434 return (rc);
7435 if (val == 0)
7436 val = AUTONEG_DISABLE;
7437 else if (val == 1)
7438 val = AUTONEG_ENABLE;
7439 else
7440 val = AUTONEG_AUTO;
7441
7442 rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK,
7443 "t4aneg");
7444 if (rc)
7445 return (rc);
7446 PORT_LOCK(pi);
7384 if (val == AUTONEG_ENABLE && !(lc->supported & FW_PORT_CAP32_ANEG)) {
7447 if (val == AUTONEG_ENABLE && !(lc->pcaps & FW_PORT_CAP32_ANEG)) {
7385 rc = ENOTSUP;
7386 goto done;
7387 }
7388 lc->requested_aneg = val;
7389 fixup_link_config(pi);
7390 if (pi->up_vis > 0)
7391 rc = apply_link_config(pi);
7392 set_current_media(pi);

--- 3793 unchanged lines hidden ---
7448 rc = ENOTSUP;
7449 goto done;
7450 }
7451 lc->requested_aneg = val;
7452 fixup_link_config(pi);
7453 if (pi->up_vis > 0)
7454 rc = apply_link_config(pi);
7455 set_current_media(pi);

--- 3793 unchanged lines hidden ---