2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright (c) 2017, Joyent, Inc.
17 * Routines to get access to the phy and transceiver that require routines and
18 * definitions that aren't part of the common ixgbe API.
22 #include "ixgbe_phy.h"
25 ixgbe_transceiver_is_8472(ixgbe_t
*ixgbe
, boolean_t
*valp
)
29 struct ixgbe_hw
*hw
= &ixgbe
->hw
;
31 ASSERT(MUTEX_HELD(&ixgbe
->gen_lock
));
32 if (hw
->phy
.ops
.read_i2c_eeprom
== NULL
)
35 ret
= hw
->phy
.ops
.read_i2c_eeprom(hw
, IXGBE_SFF_SFF_8472_COMP
, &rev
);
39 ret
= hw
->phy
.ops
.read_i2c_eeprom(hw
, IXGBE_SFF_SFF_8472_SWAP
, &swap
);
43 if (swap
& IXGBE_SFF_ADDRESSING_MODE
) {
44 ixgbe_log(ixgbe
, "transceiver requires unsupported address "
45 "change for page 0xa2. Access will only be allowed to "
49 if (rev
== IXGBE_SFF_SFF_8472_UNSUP
||
50 (swap
& IXGBE_SFF_ADDRESSING_MODE
)) {
60 * Note, we presume that the mac perimeter is held during these calls. As such,
61 * we rely on that for guaranteeing that only one thread is calling the i2c
62 * routines at any time.
65 ixgbe_transceiver_info(void *arg
, uint_t id
, mac_transceiver_info_t
*infop
)
68 struct ixgbe_hw
*hw
= &ixgbe
->hw
;
69 boolean_t present
, usable
;
71 if (id
!= 0 || infop
== NULL
)
74 mutex_enter(&ixgbe
->gen_lock
);
75 if (ixgbe_get_media_type(&ixgbe
->hw
) == ixgbe_media_type_copper
) {
76 mutex_exit(&ixgbe
->gen_lock
);
81 * Make sure we have the latest sfp information. This is especially
82 * important if the SFP is removed as that doesn't trigger interrupts in
83 * our current configuration.
85 (void) hw
->phy
.ops
.identify_sfp(hw
);
86 if (hw
->phy
.type
== ixgbe_phy_none
||
87 (hw
->phy
.type
== ixgbe_phy_unknown
&&
88 hw
->phy
.sfp_type
== ixgbe_sfp_type_not_present
)) {
93 usable
= hw
->phy
.type
!= ixgbe_phy_sfp_unsupported
;
96 mutex_exit(&ixgbe
->gen_lock
);
98 mac_transceiver_info_set_present(infop
, present
);
99 mac_transceiver_info_set_usable(infop
, usable
);
105 * Note, we presume that the mac perimeter is held during these calls. As such,
106 * we rely on that for guaranteeing that only one thread is calling the i2c
107 * routines at any time.
110 ixgbe_transceiver_read(void *arg
, uint_t id
, uint_t page
, void *bp
,
111 size_t nbytes
, off_t offset
, size_t *nread
)
113 ixgbe_t
*ixgbe
= arg
;
114 struct ixgbe_hw
*hw
= &ixgbe
->hw
;
119 if (id
!= 0 || buf
== NULL
|| nbytes
== 0 || nread
== NULL
||
120 (page
!= 0xa0 && page
!= 0xa2) || offset
< 0)
124 * Both supported pages have a length of 256 bytes, ensure nothing asks
125 * us to go beyond that.
127 if (nbytes
> 256 || offset
>= 256 || (offset
+ nbytes
> 256)) {
131 mutex_enter(&ixgbe
->gen_lock
);
132 if (ixgbe_get_media_type(&ixgbe
->hw
) == ixgbe_media_type_copper
) {
133 mutex_exit(&ixgbe
->gen_lock
);
137 if (hw
->phy
.ops
.read_i2c_eeprom
== NULL
) {
138 mutex_exit(&ixgbe
->gen_lock
);
142 if (ixgbe_transceiver_is_8472(ixgbe
, &is8472
) != 0) {
143 mutex_exit(&ixgbe
->gen_lock
);
147 if (!is8472
&& page
== 0xa2) {
148 mutex_exit(&ixgbe
->gen_lock
);
152 for (i
= 0; i
< nbytes
; i
++, offset
++, buf
++) {
156 ret
= hw
->phy
.ops
.read_i2c_eeprom(hw
, offset
, buf
);
158 ret
= hw
->phy
.ops
.read_i2c_sff8472(hw
, offset
, buf
);
161 mutex_exit(&ixgbe
->gen_lock
);
165 mutex_exit(&ixgbe
->gen_lock
);