1 MAC_CAPAB_TRANSCEIVER(9E) Driver Entry Points MAC_CAPAB_TRANSCEIVER(9E) 2 3 NAME 4 mac_capab_transceiver, mct_info, mct_read - MAC capability for networking 5 transceivers 6 7 SYNOPSIS 8 #include <sys/mac_provider.h> 9 10 typedef struct mac_capab_transceiver mac_capab_transceiver_t; 11 12 int 13 mct_info(void *driver, uint_t id, mac_transceiver_info_t *infop); 14 15 int 16 mct_read(void *driver, uint_t id, uint_t page, void *buf, size_t nbytes, 17 off_t offset, size_t *nread); 18 19 INTERFACE LEVEL 20 Volatile - This interface is still evolving in illumos. API and ABI 21 stability is not guaranteed. 22 23 PARAMETERS 24 driver A pointer to the driver's private data that was passed in 25 via the m_pdata member of the mac_register(9S) structure to 26 the mac_register(9F) function. 27 28 id An integer value indicating which transceiver is being 29 inquired about. 30 31 infop An opaque structure which is used to set information about 32 the transceiver. 33 34 page A value that indicates which page from the i2c bus is being 35 requested. 36 37 buf A pointer to which data should be written to when reading 38 from the device. 39 40 nbytes A value indicating the number of bytes being asked to read 41 into buf. 42 43 offset A value indicating the offset into the page to start 44 reading data. 45 46 nread A value to be updated by the driver with the number of 47 successfully read bytes. 48 49 DESCRIPTION 50 The MAC_CAPAB_TRANSCEIVER capability allows for GLDv3 networking device 51 drivers to provide information to the system about their transceiver. 52 Implementing this capability is optional. For more information on how to 53 handle capabilities and how to indicate that a capability is not 54 supported, see mc_getcapab(9E). 55 56 This capability should be implemented if the device in question supports 57 a Small Form Factor (SFF) transceiver. These are more commonly known by 58 names such as SFP, SFP+, SFP28, QSFP+, and QSFP28. This interface does 59 not apply to traditional copper Ethernet phys. These transceivers 60 provide standardized information over the i2c bus at specific pages. 61 62 Supported Standards 63 INF-8074 64 The INF-8084 standard was the original multiple source agreement 65 (MSA) for SFP devices. It proposed the original series of 66 management pages at i2c page 0xa0. This page contained up to 512 67 bytes, however, only the first 96 bytes are standardized. Bytes 68 97 to 127 are reserved for the vendor. The remaining bytes are 69 reserved by the specification. The management page was 70 subsequently adopted by SFP+ devices. 71 72 SFF-8472 73 The SFF-8472 standard extended the original SFP MSA. This 74 standard added a second i2c page at 0xa2, while maintaining the 75 original page at 0xa0. The page at 0xa0 is now explicitly 256 76 bytes. The page at 0xa2 is also 256 bytes. This standard was 77 also adopted for all SFP28 parts, which are commonly used in 78 transceivers for 25 Gb/s Ethernet. 79 80 SFF-8436 81 The SFF-8436 standard was developed for QSFP+ transceivers, which 82 involve the bonding of 4 SFP+ links. QSFP+ is commonly used in 83 the transceivers for 40 Gb/s Ethernet. This standard uses i2c 84 page 0xa0 for read-only identification purposes. The lower half 85 of the page is used for control, while the upper 128 bytes is 86 similar to the INF-8084 and SFF-8472 standards. 87 88 SFF-8636 89 The SFF-8636 standard is a common management standard which is 90 shared between both SAS and QSFP+ 28 Gb/s transceivers. The 91 latter transceiver is commonly found in 100 Gb/s Ethernet. The 92 transceiver's memory map is similar to that found in the SFF-8436 93 specification. The identification information is found in the 94 upper 128 bytes of page 0xa0, while the lower part of the page is 95 used for control, among other purposes. 96 97 The following table summarizes the above information. 98 99 Standard Speeds Size i2c pages 100 INF-8074 1 Gb/s, 10 Gb/s 128 bytes 0xa0 101 SFF-8472 1 Gb/s, 10 Gb/s, 25 GB/s 512 bytes 0xa0, 0xa2 102 SFF-8436 40 Gb/s 256 bytes 0xa0 103 SFF-8636 100 Gb/s 256 bytes 0xa0 104 105 MAC Capability Structure 106 When the device driver's mc_getcapab(9E) function entry point is called 107 with the capability requested set to MAC_CAPAB_TRANSCEIVER, then the 108 value of the capability structure is the following structure: 109 110 typedef struct mac_capab_transceiver { 111 uint_t mct_flags; 112 uint_t mct_ntransceivers; 113 int (*mct_info)(void *driver, uint_t id, 114 mac_transceiver_info_t *infop), 115 int (*mct_read)(void *driver, uint_t id, uint_t page, 116 void *buf, size_t nbytes, off_t offset, 117 size_t *nread) 118 } mac_capab_transceiver_t; 119 120 If the device driver supports the MAC_CAPAB_TRANSCEIVER capability, it 121 should fill in this structure, based on the following rules: 122 123 mct_flags 124 The mct_flags member is used to negotiate extensions with the 125 driver. MAC will set the value of mct_flags to include all of 126 the currently known extensions. The driver should intersect this 127 list with the set that they actually support. At this time, no 128 such features are defined and the driver should set the member to 129 0. 130 131 mct_ntransceivers 132 The value of mct_ntransceivers indicates the number of 133 transceivers present in the device. For most devices, it is 134 expected that this value will be set to one. However, some 135 devices do support multiple transceivers and PHYs that show up 136 behind a single logical MAC. 137 138 It is expected that this value will not change across the 139 lifetime of the device being attached. It is important to 140 remember that this represents the total possible number of 141 transceivers in the device, not how many are currently present 142 and powered on. 143 144 The number of transceivers will influence the id argument used in 145 the mct_info() and mct_read() entry points. The transceiver IDs 146 will start at zero and go to the value of mct_ntransceivers - 1. 147 It is up to the driver to keep the mapping between actual 148 transceivers and the transceiver identifiers consistent. 149 150 mct_info 151 The mct_info() entry point is used to set basic information about 152 the transceiver. This entry point is required. If the device 153 driver cannot implement this entry point, then it should not 154 indicate that it supports the capability. 155 156 The mct_info() entry point should fill in information about the 157 transceiver with an identifier of id. See the description above 158 of mct_ntransceivers for more information on how the IDs are 159 determined. 160 161 The driver should then proceed to fill in basic information by 162 calling the functions described in the section Information 163 Functions. After successfully calling all of the functions, the 164 driver should return 0. Otherwise, it should return the 165 appropriate error number. For a full list of error numbers, see 166 Intro(2). Common values are: 167 168 EINVAL The transceiver identifier id was 169 invalid. 170 171 ENOTSUP This instance of the devices does not 172 support a transceiver. For example, a 173 device which sometimes has copper PHYs 174 and therefore this instance does not have 175 any PHYs. 176 177 EIO An error occurred while trying to read 178 device registers. For example, an FM- 179 aware device had an error. 180 181 mct_read 182 The mct_read() function is used to read information from a 183 transceiver's i2c bus. The mct_read() entry point is an optional 184 entry point. 185 186 The transceiver should first check the value of id, which 187 indicates which transceiver information is being requested. See 188 the description above of mct_ntransceivers for more information 189 on how the IDs are determined. 190 191 The driver should try to read up to nbytes of data from the i2c 192 bus at page page. The driver should start reading at offset 193 offset. Finally, it should update the value in nread with the 194 number of bytes written to the buffer buf. 195 196 If for some reason the driver cannot read all of the requested 197 bytes, that is acceptable. Instead it should perform a short 198 read. This may occur because the transceiver does not allow 199 reads at a requested region or the region is shorter than is 200 common for most devices. 201 202 Upon successful completion, the driver should ensure that nread 203 has been updated and then return 0. Otherwise, the driver should 204 return the appropriate error number. For a full list of error 205 numbers, see Intro(2). Common values are: 206 207 EINVAL The value of id represented an invalid 208 transceiver identifier. The transceiver 209 i2c page page is not valid for this type 210 of device. The value of offset is beyond 211 the range supported for this page. 212 213 EIO An error occurred while trying to read 214 the device i2c pages. 215 216 Transceiver Information Functions 217 The mct_info() entry point is the primary required entry point for a 218 device driver which supports this capability. The information structure 219 is opaque to the device driver. Instead, a series of informational 220 functions is available to the device driver to call on the transceiver. 221 The device drivers should try to call and fill in as many of these as 222 possible. There are two different properties that a driver can set: 223 224 1. Whether the transceiver is present. 225 226 2. Whether the transceiver is usable. 227 228 To set whether or not the transceiver is present, the driver should call 229 mac_transceiver_info_set_present(9F). This is used to indicate whether 230 the transceiver is plugged in or not. If the transceiver is a part of 231 the NIC, then this function should always be called with the value set to 232 B_TRUE. 233 234 Finally, the driver has the ability to provide information about whether 235 or not the transceiver is usable or not. A transceiver may be present, 236 but not usable, if the hardware and firmware support a limited number of 237 transceivers. To set this information, the driver should call 238 mac_transceiver_info_set_usable(9F). If the transceiver is not present, 239 then the driver should not call this function. 240 241 Opaque Transceivers 242 Some devices abstract the nature of the transceiver and do not allow 243 direct access to the transceiver. In this case, if the device driver 244 still has access to enough information to know if the transceiver is at 245 least present, then it should still implement the mct_info() entry point. 246 247 Locking and Data Access 248 Calls to get information about the transceivers may come at the same time 249 as general I/O requests to the device to send or receive data. The 250 driver should make sure that reading data from the i2c bus of the 251 transceiver does not interfere with the device's functionality in this 252 regard. Different locks should be used. 253 254 On some devices, reading from the transceiver's i2c bus might cause a 255 disruption of service to the device. For example, on some devices a phy 256 reset may be required or come about as a side effect of trying to read 257 the device. If any kind of disruption would be caused, then the driver 258 must not implement the mct_read entry point. 259 260 CONTEXT 261 The various callback functions will be called from kernel context. These 262 functions will never be called from interrupt context. 263 264 SEE ALSO 265 Intro(2), mac(9E), mc_getcapab(9E), mac_register(9F), 266 mac_transceiver_info_set_present(9F), 267 mac_transceiver_info_set_usable(9F), mac_register(9S) 268 269 SFP (Small Formfactor Pluggable) Interface, INF-8074i, SFF Committee, May 270 12, 2001, Revision 1.0. 271 272 Diagnostic Monitoring Interface for Optical Transceivers, SFF-8472, 273 November 21, 2014, Revision 12.2. 274 275 QSFP+ 10 Gbs 4X PLUGGABLE TRANSCEIVER, SFF-8436, October 31, 2013, 276 Revision 4.8. 277 278 Management Interface for Cabled Environments, SFF-8636, January 26, 2016, 279 Revision 2.7. 280 281 illumos February 15, 2020 illumos