diff options
author | Robert Mustacchi <rm@joyent.com> | 2017-09-07 02:14:05 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2017-09-13 21:05:14 +0000 |
commit | 16ee9a3d03358376b04be02470c63268cabf6bab (patch) | |
tree | 047752417fd23941027f9d5081b92a879fac866b | |
parent | b34e44c2aefdd578084f80084c5ad0566f74694f (diff) | |
download | illumos-joyent-16ee9a3d03358376b04be02470c63268cabf6bab.tar.gz |
OS-6332 add MAC_CAPAB_TRANSCIEVER support for cxgbe
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Vishal Kulkarni <vishal@chelsio.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r-- | usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c b/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c index 0515aed173..ff9e7418e7 100644 --- a/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c +++ b/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c @@ -755,11 +755,78 @@ t4_mc_tx(void *arg, mblk_t *m) return (t4_eth_tx(txq, m)); } +static int +t4_mc_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop) +{ + struct port_info *pi = arg; + + if (id != 0 || infop == NULL) + return (EINVAL); + + switch (pi->mod_type) { + case FW_PORT_MOD_TYPE_NONE: + mac_transceiver_info_set_present(infop, B_FALSE); + break; + case FW_PORT_MOD_TYPE_NOTSUPPORTED: + mac_transceiver_info_set_present(infop, B_TRUE); + mac_transceiver_info_set_usable(infop, B_FALSE); + break; + default: + mac_transceiver_info_set_present(infop, B_TRUE); + mac_transceiver_info_set_usable(infop, B_TRUE); + break; + } + + return (0); +} + +static int +t4_mc_transceiver_read(void *arg, uint_t id, uint_t page, void *bp, + size_t nbytes, off_t offset, size_t *nread) +{ + struct port_info *pi = arg; + struct adapter *sc = pi->adapter; + int rc; + size_t i, maxread; + struct fw_ldst_cmd ldst; + + if (id != 0 || bp == NULL || nbytes == 0 || nread == NULL || + (page != 0xa0 && page != 0xa2) || offset < 0) + return (EINVAL); + + if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) + return (EINVAL); + + rc = begin_synchronized_op(pi, 0, 1); + if (rc != 0) + return (rc); + + /* + * Firmware has a maximum size that we can read. Don't read more than it + * allows. + */ + maxread = sizeof (ldst.u.i2c.data); + for (i = 0; i < nbytes; i += maxread) { + size_t toread = MIN(maxread, nbytes - i); + rc = -t4_i2c_rd(sc, sc->mbox, pi->port_id, page, offset, toread, + bp); + if (rc != 0) + break; + offset += toread; + bp = (void *)((uintptr_t)bp + toread); + } + end_synchronized_op(pi, 0); + if (rc == 0) + *nread = nbytes; + return (rc); +} + static boolean_t t4_mc_getcapab(void *arg, mac_capab_t cap, void *data) { struct port_info *pi = arg; boolean_t status = B_TRUE; + mac_capab_transceiver_t *mct; switch (cap) { case MAC_CAPAB_HCKSUM: @@ -809,6 +876,15 @@ t4_mc_getcapab(void *arg, mac_capab_t cap, void *data) } break; } + case MAC_CAPAB_TRANSCEIVER: + mct = data; + + mct->mct_flags = 0; + mct->mct_ntransceivers = 1; + mct->mct_info = t4_mc_transceiver_info; + mct->mct_read = t4_mc_transceiver_read; + break; + default: status = B_FALSE; /* cap not supported */ } |