summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2013-07-05 01:53:51 +0000
committernp <np@FreeBSD.org>2013-07-05 01:53:51 +0000
commit5b502b74adf11cc0ff5856ca1bf8f71adbb787fd (patch)
tree83da85e621aadc3d3b380fbdcde207a3fdf01570
parent92088d5133847b621fa4af1ca6d428ae57875b01 (diff)
downloadFreeBSD-src-5b502b74adf11cc0ff5856ca1bf8f71adbb787fd.zip
FreeBSD-src-5b502b74adf11cc0ff5856ca1bf8f71adbb787fd.tar.gz
- Show the reason why link is down if this information is available.
- Display the temperature and PHY firmware version of the BT PHY. MFC after: 1 day
-rw-r--r--sys/dev/cxgbe/adapter.h3
-rw-r--r--sys/dev/cxgbe/common/t4_hw.c9
-rw-r--r--sys/dev/cxgbe/t4_main.c48
3 files changed, 55 insertions, 5 deletions
diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h
index 38af49f..c67570f 100644
--- a/sys/dev/cxgbe/adapter.h
+++ b/sys/dev/cxgbe/adapter.h
@@ -218,6 +218,7 @@ struct port_info {
int qsize_rxq;
int qsize_txq;
+ int linkdnrc;
struct link_config link_cfg;
struct port_stats stats;
@@ -776,7 +777,7 @@ int t4_os_find_pci_capability(struct adapter *, int);
int t4_os_pci_save_state(struct adapter *);
int t4_os_pci_restore_state(struct adapter *);
void t4_os_portmod_changed(const struct adapter *, int);
-void t4_os_link_changed(struct adapter *, int, int);
+void t4_os_link_changed(struct adapter *, int, int, int);
void t4_iterate(void (*)(struct adapter *, void *), void *);
int t4_register_cpl_handler(struct adapter *, int, cpl_handler_t);
int t4_register_an_handler(struct adapter *, an_handler_t);
diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c
index 50bfba7..3005f63 100644
--- a/sys/dev/cxgbe/common/t4_hw.c
+++ b/sys/dev/cxgbe/common/t4_hw.c
@@ -5351,11 +5351,18 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
if (link_ok != lc->link_ok || speed != lc->speed ||
fc != lc->fc) { /* something changed */
+ int reason;
+
+ if (!link_ok && lc->link_ok)
+ reason = G_FW_PORT_CMD_LINKDNRC(stat);
+ else
+ reason = -1;
+
lc->link_ok = link_ok;
lc->speed = speed;
lc->fc = fc;
lc->supported = ntohs(p->u.info.pcap);
- t4_os_link_changed(adap, i, link_ok);
+ t4_os_link_changed(adap, i, link_ok, reason);
}
if (mod != pi->mod_type) {
pi->mod_type = mod;
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index fde79c4..762540e 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -373,6 +373,7 @@ static int t4_sysctls(struct adapter *);
static int cxgbe_sysctls(struct port_info *);
static int sysctl_int_array(SYSCTL_HANDLER_ARGS);
static int sysctl_bitfield(SYSCTL_HANDLER_ARGS);
+static int sysctl_btphy(SYSCTL_HANDLER_ARGS);
static int sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS);
static int sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS);
static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS);
@@ -679,6 +680,7 @@ t4_attach(device_t dev)
}
pi->xact_addr_filt = -1;
+ pi->linkdnrc = -1;
pi->qsize_rxq = t4_qsize_rxq;
pi->qsize_txq = t4_qsize_txq;
@@ -2931,7 +2933,8 @@ cxgbe_uninit_synchronized(struct port_info *pi)
pi->link_cfg.link_ok = 0;
pi->link_cfg.speed = 0;
- t4_os_link_changed(sc, pi->port_id, 0);
+ pi->linkdnrc = -1;
+ t4_os_link_changed(sc, pi->port_id, 0, -1);
return (0);
}
@@ -4408,6 +4411,16 @@ cxgbe_sysctls(struct port_info *pi)
oid = device_get_sysctl_tree(pi->dev);
children = SYSCTL_CHILDREN(oid);
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO, "linkdnrc", CTLFLAG_RD,
+ &pi->linkdnrc, 0, "reason why link is down");
+ if (pi->port_type == FW_PORT_TYPE_BT_XAUI) {
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "temperature",
+ CTLTYPE_INT | CTLFLAG_RD, pi, 0, sysctl_btphy, "I",
+ "PHY temperature (in Celsius)");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fw_version",
+ CTLTYPE_INT | CTLFLAG_RD, pi, 1, sysctl_btphy, "I",
+ "PHY firmware version");
+ }
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nrxq", CTLFLAG_RD,
&pi->nrxq, 0, "# of rx queues");
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "ntxq", CTLFLAG_RD,
@@ -4645,6 +4658,31 @@ sysctl_bitfield(SYSCTL_HANDLER_ARGS)
}
static int
+sysctl_btphy(SYSCTL_HANDLER_ARGS)
+{
+ struct port_info *pi = arg1;
+ int op = arg2;
+ struct adapter *sc = pi->adapter;
+ u_int v;
+ int rc;
+
+ rc = begin_synchronized_op(sc, pi, SLEEP_OK | INTR_OK, "t4btt");
+ if (rc)
+ return (rc);
+ /* XXX: magic numbers */
+ rc = -t4_mdio_rd(sc, sc->mbox, pi->mdio_addr, 0x1e, op ? 0x20 : 0xc820,
+ &v);
+ end_synchronized_op(sc, 0);
+ if (rc)
+ return (rc);
+ if (op == 0)
+ v /= 256;
+
+ rc = sysctl_handle_int(oidp, &v, 0, req);
+ return (rc);
+}
+
+static int
sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS)
{
struct port_info *pi = arg1;
@@ -7191,16 +7229,20 @@ t4_os_portmod_changed(const struct adapter *sc, int idx)
}
void
-t4_os_link_changed(struct adapter *sc, int idx, int link_stat)
+t4_os_link_changed(struct adapter *sc, int idx, int link_stat, int reason)
{
struct port_info *pi = sc->port[idx];
struct ifnet *ifp = pi->ifp;
if (link_stat) {
+ pi->linkdnrc = -1;
ifp->if_baudrate = IF_Mbps(pi->link_cfg.speed);
if_link_state_change(ifp, LINK_STATE_UP);
- } else
+ } else {
+ if (reason >= 0)
+ pi->linkdnrc = reason;
if_link_state_change(ifp, LINK_STATE_DOWN);
+ }
}
void
OpenPOWER on IntegriCloud