Compare commits

...

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

41 changed files with 290 additions and 5097 deletions

View File

@ -1 +0,0 @@
2414cbdb4b767da4612a2608d22ad17502cd3d37 SOURCES/ethtool-5.13.tar.xz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/ethtool-5.13.tar.xz
/ethtool-*.tar.*

View File

@ -0,0 +1,127 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBF69o70BEADQ5d4FWhqMjvj6EKA5yqj8PPIMjpL+JIGLaWcx6EiZVYR9Eoow
LdCbprkWejsBdHkRaUtsxCoc9LI9cBLSjAEm3MfKLyBLiW+53VXDsH/Yx7f87sza
kTIz1w/l8dXYKqcUOaeJ9qOY0jqyFsKVqaIMN0dkhJOYM4tyOxaut1ykfu3Dwe1L
L71fhakLSmdujX/O5MMFxZQdN2RYxgpWovmetkxsnFx6hI6sA1spQxYuJXXde6i1
6A/iLgUygwg6uy0lMJNY02okTv5uMzq/j24iNedD5+CM8fC5OY+dr2xkFgn35qP7
OTgWwGLsmseSJTfjKZssn3HTYIZpuv5Y/E5W5jg0oowQQZ7l7DUTDNsm2n0Xwvwl
L5AzOet+01PJKoXXBftHLSov8l80YXPDOX8VXwWtA8oG97/pJDPG0WGODlaQTKiy
susPG45e3jjy0ahtHP25T2Ubs0xp3p8eKRQ8J8NcrJDGDIyycN/JDRpwzfEHRIxo
J+Fvtt+L8PVXvEHwxfA1Xs/e8mOKE3cmHhvFK47hEnLtqUWVu9jw1XSCtfns/h1s
ifrMy3qm1AmL1dRWINpnzVa5V5snbEzA0Hti/J7aJyPcoNQw3Bi97XSUylT/X8T2
2+bLtGa1HIjHlSfTn8B9skanBt9cH/DxaQVtOYLUvssS+h1ans4ReSFHxwARAQAB
zR9NaWNoYWwgS3ViZWNlayA8bWlrZUBtay1zeXMuY3o+wsGOBBMBCAA4FiEE0ssS
CrRZV7chzZWW9FVFZ7kd6TQFAl69pLACGwEFCwkIBwIGFQoJCAsCBBYCAwECHgEC
F4AACgkQ9FVFZ7kd6TQNCg//a9OAoDsNPNeQcFgLxM7I+nG94HEUgH3FNqSHBsaR
gVExA1tQC1YzSPyA4GsgPkZherabcJL5awZ9XZsAsQW9zn0nHLqz50SS0cTWnBUq
/W64L3NdDtucqGXOqqqvBUljY8z/N0FnfOF4PP03mvm1uuxDAE2bEI6PMz+UjbFT
L1/TfvIPayTC5gBM7KpakYVDnxDj1+uItmErKBMLyz8qgKeRIPC89h7tcrqalFwl
kahNGFEi5f67kVI1ZR+5sCr4LXJ0ANqRw/g79Kk/ADXAx++ep766n1dkG+VkdaKY
jhdnjZlR60WMulqDzrF4unFSbGoNgCiLcN3a+kP5lm0MRlRtXLllrDGPaR0ujO72
221m+0+0SopVO1awUJRoD0TY48lL3hyjNy+tdCooFEyjCmvv4FiLfveDnSDDT67O
75RONfM1w1kwcDZY5fKHKucTBN8ZLlZgLj15kAVUqoikS2z7NkxavE4dxjVFfh1G
pFUK79b2kI9WGwGwUPrlzxGjh6RTTyCUL664EKXG28gIq3nmZfnEjxoqx4CbGsLI
gHF6RoWPg86isl4uwSBUJjQBlUbutGPyWU5MD+KP6dStKlcZH/9ND7qMCfOrPsIy
qkRP0YamCp+/1ZD6yjrJUgVvt5H67P0y9QLlbtQV4uusOoSqbnOaccp5wmCH5ojy
c63NIk1pY2hhbCBLdWJlY2VrIDxta3ViZWNla0BzdXNlLmNvbT7CwY4EEwEIADgW
IQTSyxIKtFlXtyHNlZb0VUVnuR3pNAUCXr2lJAIbAQULCQgHAgYVCgkICwIEFgID
AQIeAQIXgAAKCRD0VUVnuR3pNNZgEACT8w5n2KcDvvkR7ePyu2654TApe3I8xsBD
bU8okW8PIKGUmI2KX5La6+uSYkJ1tCaBK1TWEa4eqdWp1ZZW5fQ53l5ofBowxOVZ
qieoKCoEJ8MoT8lCq77TJKwnKQ2QNhxcjLGjOrbaLrjrvZb4rpw263R/djo2AwPY
yrye8dmfEHsysk7+0mtKhBRw2guJe9xkoyCDDvlvkPORBh23vP/rERHh68pw2G4R
Zmx01G7WOHotaJneItaqbLI3B7IEma92N5Ql9WlWQKxYnDSmJ867uZh83hn5PMLH
V8mbGhz4pcxtoALwe9DUCcFQi7vZP+QhdB6aGn9cOa5J8VqvYSvMRmQcW7HoP4bb
yjHe7PFTsjtWPCLPKrPj8Om3g2psB8ll0lGVq7r4CWoCcxbmDusbQbUgNN0J7/pt
P3mz6yucMxO/RqIIJacfhedpkYlbSe47K2dQgxHj7KQ9if23WVdwVKl6xknwyPHF
2JoH3t+Dd5LGQpAs6lzcmjolyzQlV1DLqfaiZNDtPMWaELNLyFDq4HY0S6jOsX5h
saZF5qW6ghj1T84RzpeIO/DJ4Pnm8Ii5iOpzqkjJx3gLwAlo7RPUVVPiiSfLs7V4
UASEPKlBYZvw1ceYXt8i4y+87z0qopwHtA4L4QvSEgCa6vykYYw/JQTj8OvW+V+P
b71D1lR3Ic0hTWljaGFsIEt1YmVjZWsgPG1rdWJlY2VrQHN1c2UuY3o+wsGRBBMB
CAA7AhsBBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE0ssSCrRZV7chzZWW9FVF
Z7kd6TQFAl69q/wCGQEACgkQ9FVFZ7kd6TQ5BhAAhtMfjMMWFY7lEzBY/olxAeED
SGtBb3PDfZltZfFn/acYexlFneGGRwRN60GWZAyqjONaZvvKvJ7qzwIpk74WcaQu
gP2gooqmu4bPSAs/wXeJOnfLU7r8WFinzoUBzlDuwCGKoXDsDNUE3N0sMA3zco7g
P2kg8Acahvp8tgDY5J15xccD8FjxxcpFtyd552kDrRxVBFBIg2abISje19d8Bn/o
joEMeJJfTagUMgN3ZbM3jfwqKLlQXU57e6c8YsumFGrg7rOv4gCznyWiDGrMUjRd
xr2LAxq7sn10dWEAbee48YMPGGD2SWCDsL6D4paabqsSfSKrxxN5kQhmyC42NF/u
XAwi3gVcxJQAQczMqepOLieO0gQcZLQrw0C/xUeMjeoSgIHViLEENr7bNhJccfVZ
HyAiXoIZ59aL6kBfDDPL+skfynGS/A1N11Az3yPiPzuAIO7p7lvJLpKf4fitHHJS
TGca2SDaSCFRmH0TyUhMlXjyFzIWcOip+d3yUKyPnNzAyITlyuKFB2AN3IuDQ87n
J8Bqss0SvNtyzoBEfcOid7Y3LzjwI4/ovjA7QBO3BoA4OfCPHAdiykwDPkbpCIuJ
UPKp+cUbQfOJ4Lk2iCtWsKPxhWTZbE/RQf4T+s56dHzPwNbl0xVnpGP8G+MrBoEI
A5pCQ/U23GjDvzjJ5IvNIU1pY2hhbCBLdWJlY2VrIDxta3ViZWNla0BzdXNlLmRl
PsLBjgQTAQgAOBYhBNLLEgq0WVe3Ic2VlvRVRWe5Hek0BQJevbraAhsBBQsJCAcC
BhUKCQgLAgQWAgMBAh4BAheAAAoJEPRVRWe5Hek01H8P/RANdyVvQ3puaN0YNMB1
dncI+5x/zm8TPlPh1fEhqFqs/6XsNaKG2nmxtzL2EXI943qyfe86uuDzt+35BUWX
V8mOGm0+u57q1XvHHyxGH0csd75fS4sLCFdEnbWf4evK3eP7F8rfaheotqK2gbHx
LMFHaQ1tOkrOKT5G6W/eLxCzap13vyqXLgOrXRAeZ8LhxCyeRfKNcf5vdIfWVhJO
r+bfjcTPvzc6yUfdR87PS/kLYZNq5G+Xu6C/fzu7eBzdJLyBFA66Syd65nr1gCDR
G3MQNYMlhYPh3ys6MtJef5koBnkHKJUVjCRvMAMrifxrOcCE3OCN+h6vZLCRV48D
vUGc9tLNmTApzygTk+Dsy63AAZX+UcWuOmZl62/TXgcVGmsbGsQ7Qb+TWzHoBt1h
4JuM8sEbdMTW/switwa8LeH4m7xNNsIqKS7Uc/A5kop6NRSCDbWE8LnrP8fwoWxw
etVEW9EgSkAY+45BW+ZoGkTtZXk7ItePSytJyJstBMLk24U9Uzn2G/D7V/pLuguW
HzrJj6KUSNpWPZL4t2txBY8/Knwlki+nSB04uzwcBJOxAHYHncsX79/fJMq2R/Af
rNzaY6TBUpBVZ6AI6yQJYjJNSFwUXmtzWpcC/og9lxuP8ylWBitbdv8ivAhARRV5
mt/PakcQleXogB/itMJ/gTHfzsBNBF69pucBCADDjRbI0lrgnOXHuAUlzME9lXbR
T6I6wNukUSfYo+uWh/x9xx2QWX4BppAizGQ599DaGzFAtPMDeodW2BRhqJ/CK/I2
6KFEjM1dRZLaLiym1MlTuBwC5O5fRYgxe6Z0BVssABNhK3g5mp7awnVsUzMuSIAV
i8uzGxByDS/zRjTsHUSW/t+PdJlfP+OgIxCYGGR4nuLhxft1X/pmZhkZS5R//yrl
h6+0gXTw2M7mF5q0H5j427pi+s3u8h7b9/nLJ2Zf3SRtGfInOnyOi9p10WQCN7jv
PkFegTc2KrXjY1i2hjWQ9SGuUrIsUCBZWa9WTia0z/NtIedtwZM43zZhs2vxABEB
AAHCwXYEGAEIACAWIQTSyxIKtFlXtyHNlZb0VUVnuR3pNAUCXr2m5wIbIAAKCRD0
VUVnuR3pNGCREADKZKtXVMOexR1RZXfGsQXhTIeT+yyETP+yweOqjDAGUf9qg42O
yvT9mnUVuHj8GbGExdnCty/9D7HS4qsJzbvesRuO5pJtxO5d+hU/3FQSdHrOBdYw
DjdfKuxhqPyPLcFrZCzn/g4MVpznfh5lQ+Em/wf7szn4zLowJMKPV6tuP85YvdHe
Qjpp8F110JPPYpbrfGdkEmAIAiitrLp2MNu7aWLyrsuYJQ457MdZPvLT307mlGfq
fO6KQ6jEaPefD8jIV23Vs7MX3R6w7HdbYN0ENLJBDteRynf0mH132As9D8ViKrih
97l4GB6Xd6VAPwrhCm3n6m6NoQX6UuDYnXiinWtUzU8j00E3A1sjoGVJns9HrIQT
x2TCCE/kDKE+AzlVZ1MUbJu7kAzdXe1XAa6r/M4Zh232568o6daBdGOoXWyAiLHj
P5xj4i0weAC+peF1tBRQzokoVzQWqvUyAVKeCM9nIyE/NPsUjJsBzZrFf0SM75yp
Uva9AQ7l+vDW9FwugdBsgPY3LeN4treukNqUohDIoBEGifcGdkfbngksQBCR5LDx
0NMzmGm0B0dmpBBd7ZRfgISsfmkN1t6QGypVQpjLMmoz2AGkPDnIueHqubc3n+L3
61rNorw94RdYWLgofdRxHScN8WCke0BmqSANbZbIGNNgrZvgTEmnZBQfYM7ATQRe
vaVYAQgA1SMyEkRyW2QZ/JAwmNENZeAjJQ+QaeQKYMbqPz4v+CPOkU3BaLQCgd1d
HOpaucRwkJwAML2BNoM0dQGNPfPVA6VG9dVaBqbSaMTSQszSbwDIyITuEBexulZS
G2iptnps5idw881FUZTrerW5PNbZsy5YTPJ/z8JR4WjNRBK2yA/JITI51bMGsk9a
MDGpo9CRv9CLayxoT9CgpUG/Wa6o79e0HrWeItVNTQH+04ZEtiUsho0611/71qLE
pgJke4SANUeq3NNgqwJ49aU6Uu4mQ0um823DuntXwRLWQEuzYBdoZpjHe0oNhGkY
/ptPkAmUCXVHjTWcCw6QxMGjNpZ3+QARAQABwsKsBBgBCAAgFiEE0ssSCrRZV7ch
zZWW9FVFZ7kd6TQFAl69pVgCGwIBQAkQ9FVFZ7kd6TTAdCAEGQEIAB0WIQRY3ePd
uJ5WanbqYo7nfywb8tF2lQUCXr2lWAAKCRDnfywb8tF2lQINB/98B6eyjEcFRT7I
wsWVkin1fKIu1oME0nMxidvW/G/xXI0eeo4ZaS7TeJmeunsT9ufOfHNkahhbYfnT
9GLKX8chbHRq0C5pEyVSEKvovcfku4FirGh613luR0V32NiKAdFI9DpjEey0G70H
r+a26JRbPwzextBi+q/zspA2vSWVPJF4KQlGuANg/TBt3hb3lGH0IGtRK2YXQZrs
rys8zT+YKmJLhnjZwhFTPnJ+qM9dZ6/qu9z5o3SeQeAR9DQSzbMa977DQsVTGBC2
H5PPV9Wyy9OQqhRakc9ZEhg7xP9Cpmu+3WX9+Z1ksXK0QtGPr80fEvoGx1i7wyjp
93fr38Xz6xAP/iZd7tD7NkibNRod30rX45YkOvAPcNf4Xj3T2MdPowu4RLyiNo28
kSo5KoJH9uyOIxfx3BZSjFUO/ie6tkhqetOXPe34NZA6PLObZVlSO6imJqzbDDtX
5LU4vEZJU7seAL7yRum8LwkDO/OFoOCvIqbAhVSJc7EakSHr9CGcrcjkq+NElH97
g75PxObZsxw3iqB/1nPcvJ546SJA/OVeH5amT+XcA0FiSJqHMx9vO3/A0yui+1Gv
JaS3QEoVNrIega54WPHMmwqbFSuBED0PpTrjx6ojCf/JWx8yPhMIgFj4Ep+RsxKv
JnHBPBMA6ifeZnxXe69DagQRCTShw6bfxgNHoJvQjBODRjDzxs1A6RSee8EJr9Qj
3j2qbRgueJBbTF+eRMq9gTpwJmJ25ILF/B3AsiJrRcFOZCPoCK5ZM3/lVhoP5N4B
ILrAJAmS7gLg5jPRxJC04snuXYLjFQ+qxDJRovkB3jN7XaXa2wBYsJSs7XLpo/ar
lwOSCGUAXwOm/PYpw9kuQFXDO3HZ5ephkZhUPb95s8plFFMjmB9YW49iEWI0ICV1
A0MoMdhwjamKYvKlCqxquh2KRawM0NANKVd9YBrfKOE0OV2HHKhhQMdnPECt6A0z
IdOMjJwJp1mY0Qi2oa5j1yl5Z4yDCmHrz0kdFUhB7niR/1F5DLrGVJ1rzsBNBF69
pccBCADtKArhg1arSCGVHA3U7i2YIml51Bg56ipWO920iYja2/AIf457tmhxYShP
Ny0jyJk21rCfFfbzdLcb/nB0+71plcnxU91A302vYAVX3G0wPcaNnAXOzoFumKFz
DDZoP1sJymPt7ofbDOR7oayvRibWEmnlmJ2xfx2vsTZ/o+Y8jRHfwFatOVF3dGBE
h5koz3iggYf4O48mGjrTsyDqvYsWGt1Zme5dQOdEeP7rP/3CWC2C7W5ZDUZTtVlD
6QJqNp1Rvh405oHD5fuMHUjR2xh2IPS7Nmq+gZJSdiUlR13W7vHZORnhZxAd7SHi
xFG4lxDcIMX24RjzSC8LYvHP7yw7ABEBAAHCwXYEGAEIACAWIQTSyxIKtFlXtyHN
lZb0VUVnuR3pNAUCXr2lxwIbDAAKCRD0VUVnuR3pNGkdD/4j4at/SVO/y497oeIl
RX2nDZInQ73PR6KxHgdc0vpgUbIRFOUc8uYFc9/O1sMg6PKFIBifTmEpIFKqZ3NH
mfGC7dKXzwqVKpnfbv6ZT2ANvILT8yycs1Y35ffoAUbqir2dXDLEavA85pU46Ymk
lSMir9CYYbqky82/TyIBibwLCDHxlVUBkftzKNVEpsrnVYeTcDTaZ40QOMoi9p5A
+JxqsJxCsLDm3/MzJbphUtmVmL3qNTNEY7v9l7P3a6IuHvgagNc+tX61yS5isbnK
88uhbPekuHOeUitz/GvjPFi0m/+uzU4owK3UsiXfus+S0jnFznA5KoiMo01qSZ6s
mbkxAWmcbsRM6k8/jVm0ZW9Aft10lpx2xKzzEA31+LuY9Cn9OeLVRswxM2b0dqZV
pqixJcBR+wSF7qO5kCnOqhL9z6d9sqhExaQHBfa6Thma5mBzmDnAqr79ujkqvf/y
0nFegZhTJ8IcY0W/uY66zf/5WlP7c9qxb78Sh1oV+AATTVEuaffX/shZ3vdfo9gi
mfF31W5BUNQ7K3LiG8bNG5k0vH9hqdj3juAkTssg7RwlLBcmeBd5OXANOlx3Kmqq
JU8+sSOM6iOb9nQ4iSAvxKkaKs2oFwFfz6r0/04Us6ZUiu4lMY07ILOWWMCyOY8B
fhGy2vPIn3wuZuneEjTLeTR7SA==
=T0xz
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,110 +0,0 @@
From bb89624c1a62de701f87d7deb669e40586c920d2 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 14 Sep 2021 14:27:34 +0300
Subject: [PATCH 01/35] sff-8636: Fix parsing of Page 03h in IOCTL path
The offset of Page 03h compared to the base address of the Lower Memory
is 512 bytes. However, all the offsets to the page start at address 128,
which is the address that separates Lower and Upper memory (see Figure
6-1 in SFF-8636). Therefore, reading these offsets compared to the start
of Page 03h results in incorrect memory accesses as can be seen in the
output below.
Instead, pass Page 03h with the correct offset.
This is a temporary solution until SFF-8636 is refactored to use a
memory map for parsing.
Before patch:
# ethtool -m swp13
...
Laser bias current high alarm threshold : 16.448 mA
Laser bias current low alarm threshold : 16.500 mA
Laser bias current high warning threshold : 16.480 mA
Laser bias current low warning threshold : 61.538 mA
Laser output power high alarm threshold : 1.2576 mW / 1.00 dBm
Laser output power low alarm threshold : 1.0321 mW / 0.14 dBm
Laser output power high warning threshold : 2.1318 mW / 3.29 dBm
Laser output power low warning threshold : 2.0530 mW / 3.12 dBm
Module temperature high alarm threshold : 0.00 degrees C / 32.00 degrees F
Module temperature low alarm threshold : 0.00 degrees C / 32.00 degrees F
Module temperature high warning threshold : 0.00 degrees C / 32.00 degrees F
Module temperature low warning threshold : 0.00 degrees C / 32.00 degrees F
Module voltage high alarm threshold : 0.2377 V
Module voltage low alarm threshold : 2.5701 V
Module voltage high warning threshold : 2.8276 V
Module voltage low warning threshold : 2.6982 V
Laser rx power high alarm threshold : 0.8224 mW / -0.85 dBm
Laser rx power low alarm threshold : 0.8224 mW / -0.85 dBm
Laser rx power high warning threshold : 0.8224 mW / -0.85 dBm
Laser rx power low warning threshold : 0.8224 mW / -0.85 dBm
After patch:
# ethtool -m swp13
...
Laser bias current high alarm threshold : 8.500 mA
Laser bias current low alarm threshold : 5.492 mA
Laser bias current high warning threshold : 8.000 mA
Laser bias current low warning threshold : 6.000 mA
Laser output power high alarm threshold : 3.4673 mW / 5.40 dBm
Laser output power low alarm threshold : 0.0724 mW / -11.40 dBm
Laser output power high warning threshold : 1.7378 mW / 2.40 dBm
Laser output power low warning threshold : 0.1445 mW / -8.40 dBm
Module temperature high alarm threshold : 80.00 degrees C / 176.00 degrees F
Module temperature low alarm threshold : -10.00 degrees C / 14.00 degrees F
Module temperature high warning threshold : 70.00 degrees C / 158.00 degrees F
Module temperature low warning threshold : 0.00 degrees C / 32.00 degrees F
Module voltage high alarm threshold : 3.5000 V
Module voltage low alarm threshold : 3.1000 V
Module voltage high warning threshold : 3.4650 V
Module voltage low warning threshold : 3.1350 V
Laser rx power high alarm threshold : 3.4673 mW / 5.40 dBm
Laser rx power low alarm threshold : 0.0467 mW / -13.31 dBm
Laser rx power high warning threshold : 1.7378 mW / 2.40 dBm
Laser rx power low warning threshold : 0.0933 mW / -10.30 dBm
The following AddressSanitizer report is fixed:
==44670==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x617000000320 at pc 0x00000047ad93 bp 0x7ffcb4dc0070 sp 0x7ffcb4dc0068
READ of size 1 at 0x617000000320 thread T0
#0 0x47ad92 in sff8636_dom_parse qsfp.c:683
#1 0x47c5d6 in sff8636_show_dom qsfp.c:771
#2 0x47d21f in sff8636_show_all qsfp.c:870
#3 0x42130b in do_getmodule ethtool.c:4908
#4 0x42a38a in main ethtool.c:6383
#5 0x7f500bf421e1 in __libc_start_main (/lib64/libc.so.6+0x281e1)
#6 0x40258d in _start (ethtool+0x40258d)
0x617000000320 is located 16 bytes to the right of 656-byte region [0x617000000080,0x617000000310)
allocated by thread T0 here:
#0 0x7f500c2d6527 in __interceptor_calloc (/lib64/libasan.so.6+0xab527)
#1 0x420d8c in do_getmodule ethtool.c:4859
#2 0x42a38a in main ethtool.c:6383
#3 0x7f500bf421e1 in __libc_start_main (/lib64/libc.so.6+0x281e1)
SUMMARY: AddressSanitizer: heap-buffer-overflow qsfp.c:683 in sff8636_dom_parse
Fixes: fc47fdb7c364 ("ethtool: Refactor human-readable module EEPROM output for new API")
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qsfp.c b/qsfp.c
index 644fe148a5aa..e84226bc1554 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -867,7 +867,7 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_PLUS) ||
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP28)) {
sff6836_show_page_zero(id);
- sff8636_show_dom(id, id + SFF8636_PAGE03H_OFFSET, eeprom_len);
+ sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
}
}
--
2.35.1

View File

@ -1,55 +0,0 @@
From 1c14a6d8ebad07bc6ff090164ca15ab7656e7167 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 14 Sep 2021 14:27:35 +0300
Subject: [PATCH 02/35] cmis: Fix invalid memory access in IOCTL path
Page 01h is an optional page that is not available for flat memory
modules. Trying to blindly access it results in the following report
from AddressSanitizer [1].
Instead, pass the base address of the Lower Memory. This results in
wrong information being parsed, but this never worked correctly since
CMIS support first appeared in cited commit.
The information will be parsed correctly in a follow-up submission that
reworks the EEPROM parsing code to use a memory map with pointers to
individual pages instead of passing one large buffer.
[1]
==968785==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6120000001d4 at pc 0x0000004806ee bp 0x7ffefbc977a0 sp 0x7ffefbc97798
READ of size 1 at 0x6120000001d4 thread T0
#0 0x4806ed in cmis_print_smf_cbl_len cmis.c:127
#1 0x48113e in cmis_show_link_len_from_page cmis.c:279
#2 0x4811e3 in cmis_show_link_len cmis.c:300
#3 0x481358 in qsfp_dd_show_all cmis.c:336
#4 0x47d190 in sff8636_show_all qsfp.c:861
#5 0x42130b in do_getmodule ethtool.c:4908
#6 0x42a38a in main ethtool.c:6383
#7 0x7f11db6c51e1 in __libc_start_main (/lib64/libc.so.6+0x281e1)
#8 0x40258d in _start (ethtool+0x40258d)
Address 0x6120000001d4 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow cmis.c:127 in cmis_print_smf_cbl_len
Fixes: 88ca347ef35a ("Add QSFP-DD support").
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmis.c b/cmis.c
index 361b721f332f..1a91e798e4b8 100644
--- a/cmis.c
+++ b/cmis.c
@@ -297,7 +297,7 @@ static void cmis_show_link_len_from_page(const __u8 *page_one_data)
*/
static void cmis_show_link_len(const __u8 *id)
{
- cmis_show_link_len_from_page(id + PAG01H_UPPER_OFFSET);
+ cmis_show_link_len_from_page(id);
}
/**
--
2.35.1

View File

@ -1,87 +0,0 @@
From 04d36d7c373db7069554a6d21ece628e2cf6b21c Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 14 Sep 2021 14:27:36 +0300
Subject: [PATCH 03/35] netlink: eeprom: Fallback to IOCTL when a complete
hex/raw dump is requested
The IOCTL backend provides a complete hex/raw dump of the module EEPROM
contents:
# ethtool -m swp11 hex on | wc -l
34
# ethtool -m swp11 raw on | wc -c
512
With the netlink backend, only the first 128 bytes from I2C address 0x50
are dumped:
# ethtool -m swp11 hex on | wc -l
10
# ethtool -m swp11 raw on | wc -c
128
The presence of optional / banked pages is unknown without parsing the
EEPROM contents which is unavailable when pretty printing is disabled
(i.e., configure --disable-pretty-dump). With the IOCTL backend, this
parsing happens inside the kernel.
Therefore, when a complete hex/raw dump is requested, fallback to the
IOCTL backend.
After the patch:
# ethtool -m swp11 hex on | wc -l
34
# ethtool -m swp11 raw on | wc -c
512
This avoids breaking users that are relying on current behavior.
If users want a hex/raw dump of optional/banked pages that are not
returned with the IOCTL backend, they will be required to request these
explicitly via the netlink backend. For example:
# ethtool -m swp11 hex on page 0x2
This is desirable as that way there is no ambiguity regarding the
location of optional/banked pages in the dump.
Another way to implement the above would be to use the 'nlchk' callback
added in commit 67a9ef551661 ("ethtool: add nlchk for redirecting to
netlink"). However, it is called before the netlink instance is
initialized and before the command line parameters are parsed via
nl_parser().
Fixes: 25b64c66f58d ("ethtool: Add netlink handler for getmodule (-m)")
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
netlink/module-eeprom.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index 38e7d2cd6cf3..e9a122df3259 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -365,6 +365,16 @@ int nl_getmodule(struct cmd_context *ctx)
return -EINVAL;
}
+ /* When complete hex/raw dump of the EEPROM is requested, fallback to
+ * ioctl. Netlink can only request specific pages.
+ */
+ if ((getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) &&
+ !getmodule_cmd_params.page && !getmodule_cmd_params.bank &&
+ !getmodule_cmd_params.i2c_address) {
+ nlctx->ioctl_fallback = true;
+ return -EOPNOTSUPP;
+ }
+
request.i2c_address = ETH_I2C_ADDRESS_LOW;
request.length = 128;
ret = page_fetch(nlctx, &request);
--
2.35.1

View File

@ -1,84 +0,0 @@
From 3960c91ade7b1ca9979eec5200a90dc11f339cfd Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 14 Sep 2021 14:27:37 +0300
Subject: [PATCH 04/35] ethtool: Fix compilation warning when pretty dump is
disabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When pretty dump is disabled (i.e., configure --disable-pretty-dump),
gcc 11.2.1 emits the following warning:
ethtool.c: In function dump_regs:
ethtool.c:1160:31: warning: comparison is always false due to limited range of data type [-Wtype-limits]
1160 | for (i = 0; i < ARRAY_SIZE(driver_list); i++)
| ^
Fix it by avoiding iterating over 'driver_list' when pretty dump is
disabled.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
ethtool.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 33a0a492cb15..1b79e9f8d958 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1089,12 +1089,12 @@ static int parse_hkey(char **rss_hkey, u32 key_size,
return 0;
}
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
static const struct {
const char *name;
int (*func)(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
} driver_list[] = {
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
{ "8139cp", realtek_dump_regs },
{ "8139too", realtek_dump_regs },
{ "r8169", realtek_dump_regs },
@@ -1129,8 +1129,8 @@ static const struct {
{ "fec", fec_dump_regs },
{ "igc", igc_dump_regs },
{ "bnxt_en", bnxt_dump_regs },
-#endif
};
+#endif
void dump_hex(FILE *file, const u8 *data, int len, int offset)
{
@@ -1149,14 +1149,15 @@ void dump_hex(FILE *file, const u8 *data, int len, int offset)
static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
struct ethtool_drvinfo *info, struct ethtool_regs *regs)
{
- unsigned int i;
-
if (gregs_dump_raw) {
fwrite(regs->data, regs->len, 1, stdout);
goto nested;
}
- if (!gregs_dump_hex)
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
+ if (!gregs_dump_hex) {
+ unsigned int i;
+
for (i = 0; i < ARRAY_SIZE(driver_list); i++)
if (!strncmp(driver_list[i].name, info->driver,
ETHTOOL_BUSINFO_LEN)) {
@@ -1168,6 +1169,8 @@ static int dump_regs(int gregs_dump_raw, int gregs_dump_hex,
*/
break;
}
+ }
+#endif
dump_hex(stdout, regs->data, regs->len, 0);
--
2.35.1

View File

@ -1,62 +0,0 @@
From 08d9f72f5e4ce12e2cc1fc47d1ffde9aa1326c8c Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 14 Sep 2021 14:27:38 +0300
Subject: [PATCH 05/35] netlink: eeprom: Fix compilation when pretty dump is
disabled
When pretty dump is disabled (i.e., configure --disable-pretty-dump),
the following errors are emitted:
/usr/bin/ld: netlink/module-eeprom.o: in function `decoder_print':
netlink/module-eeprom.c:330: undefined reference to `sff8636_show_all_paged'
netlink/module-eeprom.c:334: undefined reference to `cmis_show_all'
netlink/module-eeprom.c:325: undefined reference to `sff8079_show_all'
The else clause is unreachable when pretty dump is disabled, so wrap it
with ifdef directive.
This will be re-worked in future patches where the netlink code only
queries the SFF-8024 Identifier Value and defers page requests to
individual parsers.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
netlink/module-eeprom.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index e9a122df3259..48cd2cc55bee 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -275,6 +275,7 @@ static int page_fetch(struct nl_context *nlctx, const struct ethtool_module_eepr
return nlsock_process_reply(nlsock, nomsg_reply_cb, NULL);
}
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
static int decoder_prefetch(struct nl_context *nlctx)
{
struct ethtool_module_eeprom *page_zero_lower = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
@@ -338,6 +339,7 @@ static void decoder_print(void)
break;
}
}
+#endif
int nl_getmodule(struct cmd_context *ctx)
{
@@ -414,10 +416,12 @@ int nl_getmodule(struct cmd_context *ctx)
else
dump_hex(stdout, eeprom_data, dump_length, request.offset);
} else {
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
ret = decoder_prefetch(nlctx);
if (ret)
goto cleanup;
decoder_print();
+#endif
}
cleanup:
--
2.35.1

View File

@ -1,66 +0,0 @@
From 5b46ca06c9888c663a74bdd804b0ecb7199cfb62 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Fri, 1 Oct 2021 18:06:21 +0300
Subject: [PATCH 06/35] cmis: Fix CLEI code parsing
In CMIS, unlike SFF-8636, there is no presence indication for the CLEI
code (Common Language Equipment Identification) field. The field is
always present, but might not be supported. In which case, "a value of
all ASCII 20h (spaces) shall be entered".
Therefore, remove the erroneous check which seems to be influenced from
SFF-8636 and only print the string if it is supported and has a non-zero
length.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 8 +++++---
cmis.h | 4 ++--
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/cmis.c b/cmis.c
index 1a91e798e4b8..499355d0e024 100644
--- a/cmis.c
+++ b/cmis.c
@@ -307,6 +307,8 @@ static void cmis_show_link_len(const __u8 *id)
*/
static void cmis_show_vendor_info(const __u8 *id)
{
+ const char *clei = (const char *)(id + CMIS_CLEI_START_OFFSET);
+
sff_show_ascii(id, CMIS_VENDOR_NAME_START_OFFSET,
CMIS_VENDOR_NAME_END_OFFSET, "Vendor name");
cmis_show_oui(id);
@@ -319,9 +321,9 @@ static void cmis_show_vendor_info(const __u8 *id)
sff_show_ascii(id, CMIS_DATE_YEAR_OFFSET,
CMIS_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
- if (id[CMIS_CLEI_PRESENT_BYTE] & CMIS_CLEI_PRESENT_MASK)
- sff_show_ascii(id, CMIS_CLEI_START_OFFSET,
- CMIS_CLEI_END_OFFSET, "CLEI code");
+ if (*clei && strncmp(clei, CMIS_CLEI_BLANK, CMIS_CLEI_LEN))
+ sff_show_ascii(id, CMIS_CLEI_START_OFFSET, CMIS_CLEI_END_OFFSET,
+ "CLEI code");
}
void qsfp_dd_show_all(const __u8 *id)
diff --git a/cmis.h b/cmis.h
index 78ee1495bc33..cfac08f42904 100644
--- a/cmis.h
+++ b/cmis.h
@@ -34,10 +34,10 @@
#define CMIS_DATE_VENDOR_LOT_OFFSET 0xBC
/* CLEI Code (Page 0) */
-#define CMIS_CLEI_PRESENT_BYTE 0x02
-#define CMIS_CLEI_PRESENT_MASK 0x20
#define CMIS_CLEI_START_OFFSET 0xBE
#define CMIS_CLEI_END_OFFSET 0xC7
+#define CMIS_CLEI_BLANK " "
+#define CMIS_CLEI_LEN 0x0A
/* Cable assembly length */
#define CMIS_CBL_ASM_LEN_OFFSET 0xCA
--
2.35.1

View File

@ -1,42 +0,0 @@
From a934091a0b42cd7c71c9e71a235e57af718c9952 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Fri, 1 Oct 2021 18:06:22 +0300
Subject: [PATCH 07/35] cmis: Fix wrong define name
Offset 0x10 in the Lower Memory stores the "VccMonVoltage".
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 2 +-
cmis.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cmis.c b/cmis.c
index 499355d0e024..408db6f26c3b 100644
--- a/cmis.c
+++ b/cmis.c
@@ -271,7 +271,7 @@ static void cmis_show_mod_lvl_monitors(const __u8 *id)
PRINT_TEMP("Module temperature",
OFFSET_TO_TEMP(CMIS_CURR_TEMP_OFFSET));
PRINT_VCC("Module voltage",
- OFFSET_TO_U16(CMIS_CURR_CURR_OFFSET));
+ OFFSET_TO_U16(CMIS_CURR_VCC_OFFSET));
}
static void cmis_show_link_len_from_page(const __u8 *page_one_data)
diff --git a/cmis.h b/cmis.h
index cfac08f42904..e3012ccfdd79 100644
--- a/cmis.h
+++ b/cmis.h
@@ -11,7 +11,7 @@
/* Module-Level Monitors (Page 0) */
#define CMIS_CURR_TEMP_OFFSET 0x0E
-#define CMIS_CURR_CURR_OFFSET 0x10
+#define CMIS_CURR_VCC_OFFSET 0x10
#define CMIS_CTOR_OFFSET 0xCB
--
2.35.1

View File

@ -1,29 +0,0 @@
From 030ba06f12761d13722a12773bb8063748242b50 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Fri, 1 Oct 2021 18:06:23 +0300
Subject: [PATCH 08/35] cmis: Correct comment
The file is concerned with CMIS support, not QSFP-DD which is the
physical form factor.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmis.c b/cmis.c
index 408db6f26c3b..591cc72953b7 100644
--- a/cmis.c
+++ b/cmis.c
@@ -1,7 +1,7 @@
/**
* Description:
*
- * This module adds QSFP-DD support to ethtool. The changes are similar to
+ * This module adds CMIS support to ethtool. The changes are similar to
* the ones already existing in qsfp.c, but customized to use the memory
* addresses and logic as defined in the specification's document.
*
--
2.35.1

View File

@ -1,30 +0,0 @@
From f1b4bafbb30e77fedb10a23d1b70119b9059f684 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Fri, 1 Oct 2021 18:06:24 +0300
Subject: [PATCH 09/35] sff-8636: Remove incorrect comment
The comment was copied from SFF-8472 (i.e., sfpdiag.c) where the
diagnostic page is at I2C address 0x51. SFF-8636 only uses I2C address
0x50.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qsfp.c b/qsfp.c
index e84226bc1554..263cf188377d 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -64,7 +64,7 @@
static struct sff8636_aw_flags {
const char *str; /* Human-readable string, null at the end */
- int offset; /* A2-relative address offset */
+ int offset;
__u8 value; /* Alarm is on if (offset & value) != 0. */
} sff8636_aw_flags[] = {
{ "Laser bias current high alarm (Chan 1)",
--
2.35.1

View File

@ -1,48 +0,0 @@
From dc4a75242e8674da02a579e6c875ad4ac77a8c20 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Fri, 1 Oct 2021 18:06:25 +0300
Subject: [PATCH 10/35] sff-8636: Fix incorrect function name
The specification is called SFF-8636, not SFF-6836.
Rename the function accordingly.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/qsfp.c b/qsfp.c
index 263cf188377d..3401db84352d 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -820,7 +820,7 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
}
-static void sff6836_show_page_zero(const __u8 *id)
+static void sff8636_show_page_zero(const __u8 *id)
{
sff8636_show_ext_identifier(id);
sff8636_show_connector(id);
@@ -866,7 +866,7 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
if ((id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP) ||
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_PLUS) ||
(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP28)) {
- sff6836_show_page_zero(id);
+ sff8636_show_page_zero(id);
sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
}
}
@@ -875,7 +875,7 @@ void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
const struct ethtool_module_eeprom *page_three)
{
sff8636_show_identifier(page_zero->data);
- sff6836_show_page_zero(page_zero->data);
+ sff8636_show_page_zero(page_zero->data);
if (page_three)
sff8636_show_dom(page_zero->data, page_three->data - 0x80,
ETH_MODULE_SFF_8636_MAX_LEN);
--
2.35.1

View File

@ -1,37 +0,0 @@
From 9d6316a62b6ab24dfd3cb800841df7fbbdc648ae Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Fri, 1 Oct 2021 18:06:26 +0300
Subject: [PATCH 11/35] sff-8636: Convert if statement to switch-case
The indentation is wrong and the statement can be more clearly
represented using a switch-case statement. Convert it.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/qsfp.c b/qsfp.c
index 3401db84352d..d1464cb50fdc 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -863,11 +863,13 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
}
sff8636_show_identifier(id);
- if ((id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP) ||
- (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_PLUS) ||
- (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP28)) {
+ switch (id[SFF8636_ID_OFFSET]) {
+ case SFF8024_ID_QSFP:
+ case SFF8024_ID_QSFP_PLUS:
+ case SFF8024_ID_QSFP28:
sff8636_show_page_zero(id);
sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
+ break;
}
}
--
2.35.1

View File

@ -1,35 +0,0 @@
From 539a255fab8401a197e2a98c0c3dd39800ca65e5 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Fri, 1 Oct 2021 18:06:27 +0300
Subject: [PATCH 12/35] sff-8636: Remove extra blank lines
Not needed, so remove them.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/qsfp.c b/qsfp.c
index d1464cb50fdc..3f37f1036e96 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -738,7 +738,6 @@ static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff
sd->scd[i].rx_power = OFFSET_TO_U16(rx_power_offset);
sd->scd[i].tx_power = OFFSET_TO_U16(tx_power_offset);
}
-
}
static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eeprom_len)
@@ -819,7 +818,6 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
}
}
-
static void sff8636_show_page_zero(const __u8 *id)
{
sff8636_show_ext_identifier(id);
--
2.35.1

View File

@ -1,95 +0,0 @@
From 56c6dc7ab5f9170c6d399c12a87bbdb4c8de8958 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:12 +0300
Subject: [PATCH 13/35] cmis: Rename CMIS parsing functions
Currently, there are two CMIS parsing functions. qsfp_dd_show_all() and
cmis_show_all(). The former is called from the IOCTL path with a buffer
containing EEPROM contents and the latter is called from the netlink
path with pointer to individual EEPROM pages.
Rename them with '_ioctl' and '_nl' suffixes to make the distinction
clear.
In subsequent patches, these two functions will only differ in the way
they initialize the CMIS memory map for parsing, while the parsing code
itself will be shared between the two.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 6 +++---
cmis.h | 6 +++---
netlink/module-eeprom.c | 2 +-
qsfp.c | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/cmis.c b/cmis.c
index 591cc72953b7..68c5b2d3277b 100644
--- a/cmis.c
+++ b/cmis.c
@@ -326,7 +326,7 @@ static void cmis_show_vendor_info(const __u8 *id)
"CLEI code");
}
-void qsfp_dd_show_all(const __u8 *id)
+void cmis_show_all_ioctl(const __u8 *id)
{
cmis_show_identifier(id);
cmis_show_power_info(id);
@@ -340,8 +340,8 @@ void qsfp_dd_show_all(const __u8 *id)
cmis_show_rev_compliance(id);
}
-void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_one)
+void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
+ const struct ethtool_module_eeprom *page_one)
{
const __u8 *page_zero_data = page_zero->data;
diff --git a/cmis.h b/cmis.h
index e3012ccfdd79..734b90f4ddb4 100644
--- a/cmis.h
+++ b/cmis.h
@@ -120,9 +120,9 @@
#define YESNO(x) (((x) != 0) ? "Yes" : "No")
#define ONOFF(x) (((x) != 0) ? "On" : "Off")
-void qsfp_dd_show_all(const __u8 *id);
+void cmis_show_all_ioctl(const __u8 *id);
-void cmis_show_all(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_one);
+void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
+ const struct ethtool_module_eeprom *page_one);
#endif /* CMIS_H__ */
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index 48cd2cc55bee..fc4ef1a53aff 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -332,7 +332,7 @@ static void decoder_print(void)
break;
case SFF8024_ID_QSFP_DD:
case SFF8024_ID_DSFP:
- cmis_show_all(page_zero, page_one);
+ cmis_show_all_nl(page_zero, page_one);
break;
default:
dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
diff --git a/qsfp.c b/qsfp.c
index 3f37f1036e96..27fdd3bd1771 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -856,7 +856,7 @@ static void sff8636_show_page_zero(const __u8 *id)
void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
{
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
- qsfp_dd_show_all(id);
+ cmis_show_all_ioctl(id);
return;
}
--
2.35.1

View File

@ -1,145 +0,0 @@
From 912115ebf8ca6eb76dfdadbe8881b7c348743f27 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:13 +0300
Subject: [PATCH 14/35] cmis: Initialize CMIS memory map
The CMIS memory map [1] consists of Lower Memory and Upper Memory.
The content of the Lower Memory is fixed and can be addressed using an
offset between 0 and 127 (inclusive).
The Upper Memory is variable and optional and can be addressed by
specifying a bank number, a page number and an offset between 128 and
255 (inclusive).
Create a structure describing this memory map and initialize it with
pointers to available pages.
In the IOCTL path, the structure holds pointers to regions of the
continuous buffer passed to user space via the 'ETHTOOL_GMODULEEEPROM'
command.
In the netlink path, the structure holds pointers to individual pages
passed to user space via the 'MODULE_EEPROM_GET' message.
This structure will later allow us to consolidate the IOCTL and netlink
parsing code paths and also easily support additional EEPROM pages.
[1] CMIS Rev. 5, pag. 97, section 8.1.1, Figure 8-1
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmis.h | 2 ++
2 files changed, 65 insertions(+)
diff --git a/cmis.c b/cmis.c
index 68c5b2d3277b..8a6788416a00 100644
--- a/cmis.c
+++ b/cmis.c
@@ -13,6 +13,15 @@
#include "sff-common.h"
#include "cmis.h"
+struct cmis_memory_map {
+ const __u8 *lower_memory;
+ const __u8 *upper_memory[1][2]; /* Bank, Page */
+#define page_00h upper_memory[0x0][0x0]
+#define page_01h upper_memory[0x0][0x1]
+};
+
+#define CMIS_PAGE_SIZE 0x80
+
static void cmis_show_identifier(const __u8 *id)
{
sff8024_show_identifier(id, CMIS_ID_OFFSET);
@@ -326,8 +335,34 @@ static void cmis_show_vendor_info(const __u8 *id)
"CLEI code");
}
+static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
+ const __u8 *id)
+{
+ /* Lower Memory and Page 00h are always present.
+ *
+ * Offset into Upper Memory is between page size and twice the page
+ * size. Therefore, set the base address of each page to base address
+ * plus page size multiplied by the page number.
+ */
+ map->lower_memory = id;
+ map->page_00h = id;
+
+ /* Page 01h is only present when the module memory model is paged and
+ * not flat.
+ */
+ if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
+ CMIS_MEMORY_MODEL_MASK)
+ return;
+
+ map->page_01h = id + CMIS_PAGE_SIZE;
+}
+
void cmis_show_all_ioctl(const __u8 *id)
{
+ struct cmis_memory_map map = {};
+
+ cmis_memory_map_init_buf(&map, id);
+
cmis_show_identifier(id);
cmis_show_power_info(id);
cmis_show_connector(id);
@@ -340,10 +375,38 @@ void cmis_show_all_ioctl(const __u8 *id)
cmis_show_rev_compliance(id);
}
+static void
+cmis_memory_map_init_pages(struct cmis_memory_map *map,
+ const struct ethtool_module_eeprom *page_zero,
+ const struct ethtool_module_eeprom *page_one)
+{
+ /* Lower Memory and Page 00h are always present.
+ *
+ * Offset into Upper Memory is between page size and twice the page
+ * size. Therefore, set the base address of each page to its base
+ * address minus page size. For Page 00h, this is the address of the
+ * Lower Memory.
+ */
+ map->lower_memory = page_zero->data;
+ map->page_00h = page_zero->data;
+
+ /* Page 01h is only present when the module memory model is paged and
+ * not flat.
+ */
+ if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
+ CMIS_MEMORY_MODEL_MASK)
+ return;
+
+ map->page_01h = page_one->data - CMIS_PAGE_SIZE;
+}
+
void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
const struct ethtool_module_eeprom *page_one)
{
const __u8 *page_zero_data = page_zero->data;
+ struct cmis_memory_map map = {};
+
+ cmis_memory_map_init_pages(&map, page_zero, page_one);
cmis_show_identifier(page_zero_data);
cmis_show_power_info(page_zero_data);
diff --git a/cmis.h b/cmis.h
index 734b90f4ddb4..53cbb5f57127 100644
--- a/cmis.h
+++ b/cmis.h
@@ -4,6 +4,8 @@
/* Identifier and revision compliance (Page 0) */
#define CMIS_ID_OFFSET 0x00
#define CMIS_REV_COMPLIANCE_OFFSET 0x01
+#define CMIS_MEMORY_MODEL_OFFSET 0x02
+#define CMIS_MEMORY_MODEL_MASK 0x80
#define CMIS_MODULE_TYPE_OFFSET 0x55
#define CMIS_MT_MMF 0x01
--
2.35.1

View File

@ -1,394 +0,0 @@
From 6e6aed12948d2d191660252a4be9bb33dc283bed Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:14 +0300
Subject: [PATCH 15/35] cmis: Use memory map during parsing
Instead of passing one large buffer to the individual parsing functions,
use the memory map structure from the previous patch.
This has the added benefit of checking which optional pages are actually
available and it will also allow us to consolidate the IOCTL and netlink
parsing code paths.
Tested by making sure that the only differences in output in both the
IOCTL and netlink paths before and after the patch are in a few
registers in Page 01h that were previously parsed from Page 00h.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 175 +++++++++++++++++++++++++++++----------------------------
cmis.h | 1 -
2 files changed, 88 insertions(+), 88 deletions(-)
diff --git a/cmis.c b/cmis.c
index 8a6788416a00..2e01446b2315 100644
--- a/cmis.c
+++ b/cmis.c
@@ -22,19 +22,19 @@ struct cmis_memory_map {
#define CMIS_PAGE_SIZE 0x80
-static void cmis_show_identifier(const __u8 *id)
+static void cmis_show_identifier(const struct cmis_memory_map *map)
{
- sff8024_show_identifier(id, CMIS_ID_OFFSET);
+ sff8024_show_identifier(map->lower_memory, CMIS_ID_OFFSET);
}
-static void cmis_show_connector(const __u8 *id)
+static void cmis_show_connector(const struct cmis_memory_map *map)
{
- sff8024_show_connector(id, CMIS_CTOR_OFFSET);
+ sff8024_show_connector(map->page_00h, CMIS_CTOR_OFFSET);
}
-static void cmis_show_oui(const __u8 *id)
+static void cmis_show_oui(const struct cmis_memory_map *map)
{
- sff8024_show_oui(id, CMIS_VENDOR_OUI_OFFSET);
+ sff8024_show_oui(map->page_00h, CMIS_VENDOR_OUI_OFFSET);
}
/**
@@ -42,9 +42,9 @@ static void cmis_show_oui(const __u8 *id)
* [1] CMIS Rev. 3, pag. 45, section 1.7.2.1, Table 18
* [2] CMIS Rev. 4, pag. 81, section 8.2.1, Table 8-2
*/
-static void cmis_show_rev_compliance(const __u8 *id)
+static void cmis_show_rev_compliance(const struct cmis_memory_map *map)
{
- __u8 rev = id[CMIS_REV_COMPLIANCE_OFFSET];
+ __u8 rev = map->lower_memory[CMIS_REV_COMPLIANCE_OFFSET];
int major = (rev >> 4) & 0x0F;
int minor = rev & 0x0F;
@@ -58,17 +58,17 @@ static void cmis_show_rev_compliance(const __u8 *id)
* [2] CMIS Rev. 4, pag. 94, section 8.3.9, Table 8-18
* [3] QSFP-DD Hardware Rev 5.0, pag. 22, section 4.2.1
*/
-static void cmis_show_power_info(const __u8 *id)
+static void cmis_show_power_info(const struct cmis_memory_map *map)
{
float max_power = 0.0f;
__u8 base_power = 0;
__u8 power_class;
/* Get the power class (first 3 most significat bytes) */
- power_class = (id[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07;
+ power_class = (map->page_00h[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07;
/* Get the base power in multiples of 0.25W */
- base_power = id[CMIS_PWR_MAX_POWER_OFFSET];
+ base_power = map->page_00h[CMIS_PWR_MAX_POWER_OFFSET];
max_power = base_power * 0.25f;
printf("\t%-41s : %d\n", "Power class", power_class + 1);
@@ -83,20 +83,20 @@ static void cmis_show_power_info(const __u8 *id)
* [1] CMIS Rev. 3, pag. 59, section 1.7.3.10, Table 31
* [2] CMIS Rev. 4, pag. 94, section 8.3.10, Table 8-19
*/
-static void cmis_show_cbl_asm_len(const __u8 *id)
+static void cmis_show_cbl_asm_len(const struct cmis_memory_map *map)
{
static const char *fn = "Cable assembly length";
float mul = 1.0f;
float val = 0.0f;
/* Check if max length */
- if (id[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) {
+ if (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) {
printf("\t%-41s : > 6.3km\n", fn);
return;
}
/* Get the multiplier from the first two bits */
- switch (id[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
+ switch (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
case CMIS_MULTIPLIER_00:
mul = 0.1f;
break;
@@ -114,7 +114,7 @@ static void cmis_show_cbl_asm_len(const __u8 *id)
}
/* Get base value from first 6 bits and multiply by mul */
- val = (id[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
+ val = (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
val = (float)val * mul;
printf("\t%-41s : %0.2fm\n", fn, val);
}
@@ -126,14 +126,17 @@ static void cmis_show_cbl_asm_len(const __u8 *id)
* [1] CMIS Rev. 3, pag. 63, section 1.7.4.2, Table 39
* [2] CMIS Rev. 4, pag. 99, section 8.4.2, Table 8-27
*/
-static void cmis_print_smf_cbl_len(const __u8 *id)
+static void cmis_print_smf_cbl_len(const struct cmis_memory_map *map)
{
static const char *fn = "Length (SMF)";
float mul = 1.0f;
float val = 0.0f;
+ if (!map->page_01h)
+ return;
+
/* Get the multiplier from the first two bits */
- switch (id[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
+ switch (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
case CMIS_MULTIPLIER_00:
mul = 0.1f;
break;
@@ -145,7 +148,7 @@ static void cmis_print_smf_cbl_len(const __u8 *id)
}
/* Get base value from first 6 bits and multiply by mul */
- val = (id[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
+ val = (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
val = (float)val * mul;
printf("\t%-41s : %0.2fkm\n", fn, val);
}
@@ -155,21 +158,24 @@ static void cmis_print_smf_cbl_len(const __u8 *id)
* [1] CMIS Rev. 3, pag. 71, section 1.7.4.10, Table 46
* [2] CMIS Rev. 4, pag. 105, section 8.4.10, Table 8-34
*/
-static void cmis_show_sig_integrity(const __u8 *id)
+static void cmis_show_sig_integrity(const struct cmis_memory_map *map)
{
+ if (!map->page_01h)
+ return;
+
/* CDR Bypass control: 2nd bit from each byte */
printf("\t%-41s : ", "Tx CDR bypass control");
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_TX_OFFSET] & 0x02));
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x02));
printf("\t%-41s : ", "Rx CDR bypass control");
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_RX_OFFSET] & 0x02));
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x02));
/* CDR Implementation: 1st bit from each byte */
printf("\t%-41s : ", "Tx CDR");
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_TX_OFFSET] & 0x01));
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x01));
printf("\t%-41s : ", "Rx CDR");
- printf("%s\n", YESNO(id[CMIS_SIG_INTEG_RX_OFFSET] & 0x01));
+ printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x01));
}
/**
@@ -182,14 +188,14 @@ static void cmis_show_sig_integrity(const __u8 *id)
* --> pag. 98, section 8.4, Table 8-25
* --> page 100, section 8.4.3, 8.4.4
*/
-static void cmis_show_mit_compliance(const __u8 *id)
+static void cmis_show_mit_compliance(const struct cmis_memory_map *map)
{
static const char *cc = " (Copper cable,";
printf("\t%-41s : 0x%02x", "Transmitter technology",
- id[CMIS_MEDIA_INTF_TECH_OFFSET]);
+ map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]);
- switch (id[CMIS_MEDIA_INTF_TECH_OFFSET]) {
+ switch (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]) {
case CMIS_850_VCSEL:
printf(" (850 nm VCSEL)\n");
break;
@@ -240,22 +246,22 @@ static void cmis_show_mit_compliance(const __u8 *id)
break;
}
- if (id[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) {
+ if (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) {
printf("\t%-41s : %udb\n", "Attenuation at 5GHz",
- id[CMIS_COPPER_ATT_5GHZ]);
+ map->page_00h[CMIS_COPPER_ATT_5GHZ]);
printf("\t%-41s : %udb\n", "Attenuation at 7GHz",
- id[CMIS_COPPER_ATT_7GHZ]);
+ map->page_00h[CMIS_COPPER_ATT_7GHZ]);
printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
- id[CMIS_COPPER_ATT_12P9GHZ]);
+ map->page_00h[CMIS_COPPER_ATT_12P9GHZ]);
printf("\t%-41s : %udb\n", "Attenuation at 25.8GHz",
- id[CMIS_COPPER_ATT_25P8GHZ]);
- } else {
+ map->page_00h[CMIS_COPPER_ATT_25P8GHZ]);
+ } else if (map->page_01h) {
printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
- (((id[CMIS_NOM_WAVELENGTH_MSB] << 8) |
- id[CMIS_NOM_WAVELENGTH_LSB]) * 0.05));
+ (((map->page_01h[CMIS_NOM_WAVELENGTH_MSB] << 8) |
+ map->page_01h[CMIS_NOM_WAVELENGTH_LSB]) * 0.05));
printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
- (((id[CMIS_WAVELENGTH_TOL_MSB] << 8) |
- id[CMIS_WAVELENGTH_TOL_LSB]) * 0.005));
+ (((map->page_01h[CMIS_WAVELENGTH_TOL_MSB] << 8) |
+ map->page_01h[CMIS_WAVELENGTH_TOL_LSB]) * 0.005));
}
}
@@ -275,28 +281,16 @@ static void cmis_show_mit_compliance(const __u8 *id)
* [2] CMIS Rev. 4:
* --> pag. 84, section 8.2.4, Table 8-6
*/
-static void cmis_show_mod_lvl_monitors(const __u8 *id)
+static void cmis_show_mod_lvl_monitors(const struct cmis_memory_map *map)
{
+ const __u8 *id = map->lower_memory;
+
PRINT_TEMP("Module temperature",
OFFSET_TO_TEMP(CMIS_CURR_TEMP_OFFSET));
PRINT_VCC("Module voltage",
OFFSET_TO_U16(CMIS_CURR_VCC_OFFSET));
}
-static void cmis_show_link_len_from_page(const __u8 *page_one_data)
-{
- cmis_print_smf_cbl_len(page_one_data);
- sff_show_value_with_unit(page_one_data, CMIS_OM5_LEN_OFFSET,
- "Length (OM5)", 2, "m");
- sff_show_value_with_unit(page_one_data, CMIS_OM4_LEN_OFFSET,
- "Length (OM4)", 2, "m");
- sff_show_value_with_unit(page_one_data, CMIS_OM3_LEN_OFFSET,
- "Length (OM3 50/125um)", 2, "m");
- sff_show_value_with_unit(page_one_data, CMIS_OM2_LEN_OFFSET,
- "Length (OM2 50/125um)", 1, "m");
-}
-
-
/**
* Print relevant info about the maximum supported fiber media length
* for each type of fiber media at the maximum module-supported bit rate.
@@ -304,9 +298,19 @@ static void cmis_show_link_len_from_page(const __u8 *page_one_data)
* [1] CMIS Rev. 3, page 64, section 1.7.4.2, Table 39
* [2] CMIS Rev. 4, page 99, section 8.4.2, Table 8-27
*/
-static void cmis_show_link_len(const __u8 *id)
+static void cmis_show_link_len(const struct cmis_memory_map *map)
{
- cmis_show_link_len_from_page(id);
+ cmis_print_smf_cbl_len(map);
+ if (!map->page_01h)
+ return;
+ sff_show_value_with_unit(map->page_01h, CMIS_OM5_LEN_OFFSET,
+ "Length (OM5)", 2, "m");
+ sff_show_value_with_unit(map->page_01h, CMIS_OM4_LEN_OFFSET,
+ "Length (OM4)", 2, "m");
+ sff_show_value_with_unit(map->page_01h, CMIS_OM3_LEN_OFFSET,
+ "Length (OM3 50/125um)", 2, "m");
+ sff_show_value_with_unit(map->page_01h, CMIS_OM2_LEN_OFFSET,
+ "Length (OM2 50/125um)", 1, "m");
}
/**
@@ -314,25 +318,26 @@ static void cmis_show_link_len(const __u8 *id)
* [1] CMIS Rev. 3, page 56, section 1.7.3, Table 27
* [2] CMIS Rev. 4, page 91, section 8.2, Table 8-15
*/
-static void cmis_show_vendor_info(const __u8 *id)
+static void cmis_show_vendor_info(const struct cmis_memory_map *map)
{
- const char *clei = (const char *)(id + CMIS_CLEI_START_OFFSET);
+ const char *clei;
- sff_show_ascii(id, CMIS_VENDOR_NAME_START_OFFSET,
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_NAME_START_OFFSET,
CMIS_VENDOR_NAME_END_OFFSET, "Vendor name");
- cmis_show_oui(id);
- sff_show_ascii(id, CMIS_VENDOR_PN_START_OFFSET,
+ cmis_show_oui(map);
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_PN_START_OFFSET,
CMIS_VENDOR_PN_END_OFFSET, "Vendor PN");
- sff_show_ascii(id, CMIS_VENDOR_REV_START_OFFSET,
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_REV_START_OFFSET,
CMIS_VENDOR_REV_END_OFFSET, "Vendor rev");
- sff_show_ascii(id, CMIS_VENDOR_SN_START_OFFSET,
+ sff_show_ascii(map->page_00h, CMIS_VENDOR_SN_START_OFFSET,
CMIS_VENDOR_SN_END_OFFSET, "Vendor SN");
- sff_show_ascii(id, CMIS_DATE_YEAR_OFFSET,
+ sff_show_ascii(map->page_00h, CMIS_DATE_YEAR_OFFSET,
CMIS_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
+ clei = (const char *)(map->page_00h + CMIS_CLEI_START_OFFSET);
if (*clei && strncmp(clei, CMIS_CLEI_BLANK, CMIS_CLEI_LEN))
- sff_show_ascii(id, CMIS_CLEI_START_OFFSET, CMIS_CLEI_END_OFFSET,
- "CLEI code");
+ sff_show_ascii(map->page_00h, CMIS_CLEI_START_OFFSET,
+ CMIS_CLEI_END_OFFSET, "CLEI code");
}
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
@@ -363,16 +368,16 @@ void cmis_show_all_ioctl(const __u8 *id)
cmis_memory_map_init_buf(&map, id);
- cmis_show_identifier(id);
- cmis_show_power_info(id);
- cmis_show_connector(id);
- cmis_show_cbl_asm_len(id);
- cmis_show_sig_integrity(id);
- cmis_show_mit_compliance(id);
- cmis_show_mod_lvl_monitors(id);
- cmis_show_link_len(id);
- cmis_show_vendor_info(id);
- cmis_show_rev_compliance(id);
+ cmis_show_identifier(&map);
+ cmis_show_power_info(&map);
+ cmis_show_connector(&map);
+ cmis_show_cbl_asm_len(&map);
+ cmis_show_sig_integrity(&map);
+ cmis_show_mit_compliance(&map);
+ cmis_show_mod_lvl_monitors(&map);
+ cmis_show_link_len(&map);
+ cmis_show_vendor_info(&map);
+ cmis_show_rev_compliance(&map);
}
static void
@@ -403,22 +408,18 @@ cmis_memory_map_init_pages(struct cmis_memory_map *map,
void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
const struct ethtool_module_eeprom *page_one)
{
- const __u8 *page_zero_data = page_zero->data;
struct cmis_memory_map map = {};
cmis_memory_map_init_pages(&map, page_zero, page_one);
- cmis_show_identifier(page_zero_data);
- cmis_show_power_info(page_zero_data);
- cmis_show_connector(page_zero_data);
- cmis_show_cbl_asm_len(page_zero_data);
- cmis_show_sig_integrity(page_zero_data);
- cmis_show_mit_compliance(page_zero_data);
- cmis_show_mod_lvl_monitors(page_zero_data);
-
- if (page_one)
- cmis_show_link_len_from_page(page_one->data - 0x80);
-
- cmis_show_vendor_info(page_zero_data);
- cmis_show_rev_compliance(page_zero_data);
+ cmis_show_identifier(&map);
+ cmis_show_power_info(&map);
+ cmis_show_connector(&map);
+ cmis_show_cbl_asm_len(&map);
+ cmis_show_sig_integrity(&map);
+ cmis_show_mit_compliance(&map);
+ cmis_show_mod_lvl_monitors(&map);
+ cmis_show_link_len(&map);
+ cmis_show_vendor_info(&map);
+ cmis_show_rev_compliance(&map);
}
diff --git a/cmis.h b/cmis.h
index 53cbb5f57127..c878e3bc5afd 100644
--- a/cmis.h
+++ b/cmis.h
@@ -100,7 +100,6 @@
* that are unique to active modules and cable assemblies.
* GlobalOffset = 2 * 0x80 + LocalOffset
*/
-#define PAG01H_UPPER_OFFSET (0x02 * 0x80)
/* Supported Link Length (Page 1) */
#define CMIS_SMF_LEN_OFFSET 0x84
--
2.35.1

View File

@ -1,77 +0,0 @@
From 284886fbb4a85103cd82d061ebe4d1c93730b783 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:15 +0300
Subject: [PATCH 16/35] cmis: Consolidate code between IOCTL and netlink paths
Now that both the netlink and IOCTL paths use the same memory map
structure for parsing, the code can be easily consolidated.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 38 ++++++++++++++++----------------------
1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/cmis.c b/cmis.c
index 2e01446b2315..eb7791dd59df 100644
--- a/cmis.c
+++ b/cmis.c
@@ -340,6 +340,20 @@ static void cmis_show_vendor_info(const struct cmis_memory_map *map)
CMIS_CLEI_END_OFFSET, "CLEI code");
}
+static void cmis_show_all_common(const struct cmis_memory_map *map)
+{
+ cmis_show_identifier(map);
+ cmis_show_power_info(map);
+ cmis_show_connector(map);
+ cmis_show_cbl_asm_len(map);
+ cmis_show_sig_integrity(map);
+ cmis_show_mit_compliance(map);
+ cmis_show_mod_lvl_monitors(map);
+ cmis_show_link_len(map);
+ cmis_show_vendor_info(map);
+ cmis_show_rev_compliance(map);
+}
+
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
const __u8 *id)
{
@@ -367,17 +381,7 @@ void cmis_show_all_ioctl(const __u8 *id)
struct cmis_memory_map map = {};
cmis_memory_map_init_buf(&map, id);
-
- cmis_show_identifier(&map);
- cmis_show_power_info(&map);
- cmis_show_connector(&map);
- cmis_show_cbl_asm_len(&map);
- cmis_show_sig_integrity(&map);
- cmis_show_mit_compliance(&map);
- cmis_show_mod_lvl_monitors(&map);
- cmis_show_link_len(&map);
- cmis_show_vendor_info(&map);
- cmis_show_rev_compliance(&map);
+ cmis_show_all_common(&map);
}
static void
@@ -411,15 +415,5 @@ void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
struct cmis_memory_map map = {};
cmis_memory_map_init_pages(&map, page_zero, page_one);
-
- cmis_show_identifier(&map);
- cmis_show_power_info(&map);
- cmis_show_connector(&map);
- cmis_show_cbl_asm_len(&map);
- cmis_show_sig_integrity(&map);
- cmis_show_mit_compliance(&map);
- cmis_show_mod_lvl_monitors(&map);
- cmis_show_link_len(&map);
- cmis_show_vendor_info(&map);
- cmis_show_rev_compliance(&map);
+ cmis_show_all_common(&map);
}
--
2.35.1

View File

@ -1,97 +0,0 @@
From a8419e965891901217756254e0ed1a3351b2a3cb Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:16 +0300
Subject: [PATCH 17/35] sff-8636: Rename SFF-8636 parsing functions
Currently, there are two SFF-8636 parsing functions. sff8636_show_all()
and sff8636_show_all_paged(). The former is called from the IOCTL path
with a buffer containing EEPROM contents and the latter is called from
the netlink path with pointer to individual EEPROM pages.
Rename them with '_ioctl' and '_nl' suffixes to make the distinction
clear.
In subsequent patches, these two functions will only differ in the way
they initialize the SFF-8636 memory map for parsing, while the parsing
code itself will be shared between the two.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
ethtool.c | 4 ++--
internal.h | 6 +++---
netlink/module-eeprom.c | 2 +-
qsfp.c | 6 +++---
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 1b79e9f8d958..6c744ff84eb9 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4908,8 +4908,8 @@ static int do_getmodule(struct cmd_context *ctx)
break;
case ETH_MODULE_SFF_8436:
case ETH_MODULE_SFF_8636:
- sff8636_show_all(eeprom->data,
- modinfo.eeprom_len);
+ sff8636_show_all_ioctl(eeprom->data,
+ modinfo.eeprom_len);
break;
#endif
default:
diff --git a/internal.h b/internal.h
index 33e619b3ac53..7ca6066d4e12 100644
--- a/internal.h
+++ b/internal.h
@@ -390,9 +390,9 @@ void sff8079_show_all(const __u8 *id);
void sff8472_show_all(const __u8 *id);
/* QSFP Optics diagnostics */
-void sff8636_show_all(const __u8 *id, __u32 eeprom_len);
-void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_three);
+void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
+void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
+ const struct ethtool_module_eeprom *page_three);
/* FUJITSU Extended Socket network device */
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index fc4ef1a53aff..18b1abbe1252 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -328,7 +328,7 @@ static void decoder_print(void)
case SFF8024_ID_QSFP:
case SFF8024_ID_QSFP28:
case SFF8024_ID_QSFP_PLUS:
- sff8636_show_all_paged(page_zero, page_three);
+ sff8636_show_all_nl(page_zero, page_three);
break;
case SFF8024_ID_QSFP_DD:
case SFF8024_ID_DSFP:
diff --git a/qsfp.c b/qsfp.c
index 27fdd3bd1771..dc6407d3ef6f 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -853,7 +853,7 @@ static void sff8636_show_page_zero(const __u8 *id)
}
-void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
+void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
{
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
cmis_show_all_ioctl(id);
@@ -871,8 +871,8 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
}
}
-void sff8636_show_all_paged(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_three)
+void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
+ const struct ethtool_module_eeprom *page_three)
{
sff8636_show_identifier(page_zero->data);
sff8636_show_page_zero(page_zero->data);
--
2.35.1

View File

@ -1,137 +0,0 @@
From c77b5adfb3f94762a08554d1b4d75f6cbd8a6abe Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:17 +0300
Subject: [PATCH 18/35] sff-8636: Initialize SFF-8636 memory map
The SFF-8636 memory map [1] consists of Lower Memory and Upper Memory.
The content of the Lower Memory is fixed and can be addressed using an
offset between 0 and 127 (inclusive).
The Upper Memory is variable and optional and can be addressed by
specifying a page number and an offset between 128 and 255 (inclusive).
Create a structure describing this memory map and initialize it with
pointers to available pages.
In the IOCTL path, the structure holds pointers to regions of the
continuous buffer passed to user space via the 'ETHTOOL_GMODULEEEPROM'
command.
In the netlink path, the structure holds pointers to individual pages
passed to user space via the 'MODULE_EEPROM_GET' message.
This structure will later allow us to consolidate the IOCTL and netlink
parsing code paths and also easily support additional EEPROM pages, when
needed.
[1] SFF-8636 Rev. 2.10a, pag. 30, section 6.1, Figure 6-1
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/qsfp.c b/qsfp.c
index dc6407d3ef6f..80000d40f6e8 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -60,6 +60,15 @@
#include "qsfp.h"
#include "cmis.h"
+struct sff8636_memory_map {
+ const __u8 *lower_memory;
+ const __u8 *upper_memory[4];
+#define page_00h upper_memory[0x0]
+#define page_03h upper_memory[0x3]
+};
+
+#define SFF8636_PAGE_SIZE 0x80
+
#define MAX_DESC_SIZE 42
static struct sff8636_aw_flags {
@@ -853,13 +862,40 @@ static void sff8636_show_page_zero(const __u8 *id)
}
+static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
+ const __u8 *id, __u32 eeprom_len)
+{
+ /* Lower Memory and Page 00h are always present.
+ *
+ * Offset into Upper Memory is between page size and twice the page
+ * size. Therefore, set the base address of each page to base address
+ * plus page size multiplied by the page number.
+ */
+ map->lower_memory = id;
+ map->page_00h = id;
+
+ /* Page 03h is only present when the module memory model is paged and
+ * not flat and when we got a big enough buffer from the kernel.
+ */
+ if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
+ SFF8636_STATUS_PAGE_3_PRESENT ||
+ eeprom_len != ETH_MODULE_SFF_8636_MAX_LEN)
+ return;
+
+ map->page_03h = id + 3 * SFF8636_PAGE_SIZE;
+}
+
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
{
+ struct sff8636_memory_map map = {};
+
if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
cmis_show_all_ioctl(id);
return;
}
+ sff8636_memory_map_init_buf(&map, id, eeprom_len);
+
sff8636_show_identifier(id);
switch (id[SFF8636_ID_OFFSET]) {
case SFF8024_ID_QSFP:
@@ -871,9 +907,38 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
}
}
+static void
+sff8636_memory_map_init_pages(struct sff8636_memory_map *map,
+ const struct ethtool_module_eeprom *page_zero,
+ const struct ethtool_module_eeprom *page_three)
+{
+ /* Lower Memory and Page 00h are always present.
+ *
+ * Offset into Upper Memory is between page size and twice the page
+ * size. Therefore, set the base address of each page to its base
+ * address minus page size. For Page 00h, this is the address of the
+ * Lower Memory.
+ */
+ map->lower_memory = page_zero->data;
+ map->page_00h = page_zero->data;
+
+ /* Page 03h is only present when the module memory model is paged and
+ * not flat.
+ */
+ if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
+ SFF8636_STATUS_PAGE_3_PRESENT)
+ return;
+
+ map->page_03h = page_three->data - SFF8636_PAGE_SIZE;
+}
+
void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
const struct ethtool_module_eeprom *page_three)
{
+ struct sff8636_memory_map map = {};
+
+ sff8636_memory_map_init_pages(&map, page_zero, page_three);
+
sff8636_show_identifier(page_zero->data);
sff8636_show_page_zero(page_zero->data);
if (page_three)
--
2.35.1

View File

@ -1,607 +0,0 @@
From 85023fa5dd7e79ce46a92ab567b4b675c3145775 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:18 +0300
Subject: [PATCH 19/35] sff-8636: Use memory map during parsing
Instead of passing one large buffer to the individual parsing functions,
use the memory map structure from the previous patch.
This has the added benefit of checking which optional pages are actually
available and it will also allow us to consolidate the IOCTL and netlink
parsing code paths.
Tested by making sure that there are no differences in output in both
the IOCTL and netlink paths before and after the patch.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 368 +++++++++++++++++++++++++++++++--------------------------
1 file changed, 201 insertions(+), 167 deletions(-)
diff --git a/qsfp.c b/qsfp.c
index 80000d40f6e8..354b3b1ce9ff 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -205,20 +205,21 @@ static struct sff8636_aw_flags {
{ NULL, 0, 0 },
};
-static void sff8636_show_identifier(const __u8 *id)
+static void sff8636_show_identifier(const struct sff8636_memory_map *map)
{
- sff8024_show_identifier(id, SFF8636_ID_OFFSET);
+ sff8024_show_identifier(map->lower_memory, SFF8636_ID_OFFSET);
}
-static void sff8636_show_ext_identifier(const __u8 *id)
+static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map)
{
printf("\t%-41s : 0x%02x\n", "Extended identifier",
- id[SFF8636_EXT_ID_OFFSET]);
+ map->page_00h[SFF8636_EXT_ID_OFFSET]);
static const char *pfx =
"\tExtended identifier description :";
- switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_PWR_CLASS_MASK) {
+ switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
+ SFF8636_EXT_ID_PWR_CLASS_MASK) {
case SFF8636_EXT_ID_PWR_CLASS_1:
printf("%s 1.5W max. Power consumption\n", pfx);
break;
@@ -233,17 +234,18 @@ static void sff8636_show_ext_identifier(const __u8 *id)
break;
}
- if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
+ if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_TX_MASK)
printf("%s CDR present in TX,", pfx);
else
printf("%s No CDR in TX,", pfx);
- if (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
+ if (map->page_00h[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_CDR_RX_MASK)
printf(" CDR present in RX\n");
else
printf(" No CDR in RX\n");
- switch (id[SFF8636_EXT_ID_OFFSET] & SFF8636_EXT_ID_EPWR_CLASS_MASK) {
+ switch (map->page_00h[SFF8636_EXT_ID_OFFSET] &
+ SFF8636_EXT_ID_EPWR_CLASS_MASK) {
case SFF8636_EXT_ID_PWR_CLASS_LEGACY:
printf("%s", pfx);
break;
@@ -257,18 +259,19 @@ static void sff8636_show_ext_identifier(const __u8 *id)
printf("%s 5.0W max. Power consumption, ", pfx);
break;
}
- if (id[SFF8636_PWR_MODE_OFFSET] & SFF8636_HIGH_PWR_ENABLE)
+ if (map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
+ SFF8636_HIGH_PWR_ENABLE)
printf(" High Power Class (> 3.5 W) enabled\n");
else
printf(" High Power Class (> 3.5 W) not enabled\n");
}
-static void sff8636_show_connector(const __u8 *id)
+static void sff8636_show_connector(const struct sff8636_memory_map *map)
{
- sff8024_show_connector(id, SFF8636_CTOR_OFFSET);
+ sff8024_show_connector(map->page_00h, SFF8636_CTOR_OFFSET);
}
-static void sff8636_show_transceiver(const __u8 *id)
+static void sff8636_show_transceiver(const struct sff8636_memory_map *map)
{
static const char *pfx =
"\tTransceiver type :";
@@ -276,33 +279,41 @@ static void sff8636_show_transceiver(const __u8 *id)
printf("\t%-41s : 0x%02x 0x%02x 0x%02x " \
"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
"Transceiver codes",
- id[SFF8636_ETHERNET_COMP_OFFSET],
- id[SFF8636_SONET_COMP_OFFSET],
- id[SFF8636_SAS_COMP_OFFSET],
- id[SFF8636_GIGE_COMP_OFFSET],
- id[SFF8636_FC_LEN_OFFSET],
- id[SFF8636_FC_TECH_OFFSET],
- id[SFF8636_FC_TRANS_MEDIA_OFFSET],
- id[SFF8636_FC_SPEED_OFFSET]);
+ map->page_00h[SFF8636_ETHERNET_COMP_OFFSET],
+ map->page_00h[SFF8636_SONET_COMP_OFFSET],
+ map->page_00h[SFF8636_SAS_COMP_OFFSET],
+ map->page_00h[SFF8636_GIGE_COMP_OFFSET],
+ map->page_00h[SFF8636_FC_LEN_OFFSET],
+ map->page_00h[SFF8636_FC_TECH_OFFSET],
+ map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET],
+ map->page_00h[SFF8636_FC_SPEED_OFFSET]);
/* 10G/40G Ethernet Compliance Codes */
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LRM)
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_10G_LRM)
printf("%s 10G Ethernet: 10G Base-LRM\n", pfx);
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_LR)
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_10G_LR)
printf("%s 10G Ethernet: 10G Base-LR\n", pfx);
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_10G_SR)
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_10G_SR)
printf("%s 10G Ethernet: 10G Base-SR\n", pfx);
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_CR4)
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_40G_CR4)
printf("%s 40G Ethernet: 40G Base-CR4\n", pfx);
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_SR4)
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_40G_SR4)
printf("%s 40G Ethernet: 40G Base-SR4\n", pfx);
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_LR4)
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_40G_LR4)
printf("%s 40G Ethernet: 40G Base-LR4\n", pfx);
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_40G_ACTIVE)
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_40G_ACTIVE)
printf("%s 40G Ethernet: 40G Active Cable (XLPPI)\n", pfx);
/* Extended Specification Compliance Codes from SFF-8024 */
- if (id[SFF8636_ETHERNET_COMP_OFFSET] & SFF8636_ETHERNET_RSRVD) {
- switch (id[SFF8636_OPTION_1_OFFSET]) {
+ if (map->page_00h[SFF8636_ETHERNET_COMP_OFFSET] &
+ SFF8636_ETHERNET_RSRVD) {
+ switch (map->page_00h[SFF8636_OPTION_1_OFFSET]) {
case SFF8636_ETHERNET_UNSPECIFIED:
printf("%s (reserved or unknown)\n", pfx);
break;
@@ -493,113 +504,122 @@ static void sff8636_show_transceiver(const __u8 *id)
}
/* SONET Compliance Codes */
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_40G_OTN))
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] &
+ (SFF8636_SONET_40G_OTN))
printf("%s 40G OTN (OTU3B/OTU3C)\n", pfx);
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_LR))
printf("%s SONET: OC-48, long reach\n", pfx);
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_IR))
printf("%s SONET: OC-48, intermediate reach\n", pfx);
- if (id[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
+ if (map->page_00h[SFF8636_SONET_COMP_OFFSET] & (SFF8636_SONET_OC48_SR))
printf("%s SONET: OC-48, short reach\n", pfx);
/* SAS/SATA Compliance Codes */
- if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
+ if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_6G))
printf("%s SAS 6.0G\n", pfx);
- if (id[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
+ if (map->page_00h[SFF8636_SAS_COMP_OFFSET] & (SFF8636_SAS_3G))
printf("%s SAS 3.0G\n", pfx);
/* Ethernet Compliance Codes */
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_T)
printf("%s Ethernet: 1000BASE-T\n", pfx);
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_CX)
printf("%s Ethernet: 1000BASE-CX\n", pfx);
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_LX)
printf("%s Ethernet: 1000BASE-LX\n", pfx);
- if (id[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
+ if (map->page_00h[SFF8636_GIGE_COMP_OFFSET] & SFF8636_GIGE_1000_BASE_SX)
printf("%s Ethernet: 1000BASE-SX\n", pfx);
/* Fibre Channel link length */
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_VERY_LONG)
printf("%s FC: very long distance (V)\n", pfx);
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_SHORT)
printf("%s FC: short distance (S)\n", pfx);
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_INT)
printf("%s FC: intermediate distance (I)\n", pfx);
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_LONG)
printf("%s FC: long distance (L)\n", pfx);
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_LEN_MED)
printf("%s FC: medium distance (M)\n", pfx);
/* Fibre Channel transmitter technology */
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_LONG_LC)
printf("%s FC: Longwave laser (LC)\n", pfx);
- if (id[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
+ if (map->page_00h[SFF8636_FC_LEN_OFFSET] & SFF8636_FC_TECH_ELEC_INTER)
printf("%s FC: Electrical inter-enclosure (EL)\n", pfx);
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_ELEC_INTRA)
printf("%s FC: Electrical intra-enclosure (EL)\n", pfx);
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_WO_OFC)
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] &
+ SFF8636_FC_TECH_SHORT_WO_OFC)
printf("%s FC: Shortwave laser w/o OFC (SN)\n", pfx);
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_SHORT_W_OFC)
printf("%s FC: Shortwave laser with OFC (SL)\n", pfx);
- if (id[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
+ if (map->page_00h[SFF8636_FC_TECH_OFFSET] & SFF8636_FC_TECH_LONG_LL)
printf("%s FC: Longwave laser (LL)\n", pfx);
/* Fibre Channel transmission media */
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TW)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_TW)
printf("%s FC: Twin Axial Pair (TW)\n", pfx);
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TP)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_TP)
printf("%s FC: Twisted Pair (TP)\n", pfx);
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_MI)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_MI)
printf("%s FC: Miniature Coax (MI)\n", pfx);
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_TV)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_TV)
printf("%s FC: Video Coax (TV)\n", pfx);
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M6)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_M6)
printf("%s FC: Multimode, 62.5m (M6)\n", pfx);
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_M5)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_M5)
printf("%s FC: Multimode, 50m (M5)\n", pfx);
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_OM3)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_OM3)
printf("%s FC: Multimode, 50um (OM3)\n", pfx);
- if (id[SFF8636_FC_TRANS_MEDIA_OFFSET] & SFF8636_FC_TRANS_MEDIA_SM)
+ if (map->page_00h[SFF8636_FC_TRANS_MEDIA_OFFSET] &
+ SFF8636_FC_TRANS_MEDIA_SM)
printf("%s FC: Single Mode (SM)\n", pfx);
/* Fibre Channel speed */
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1200_MBPS)
printf("%s FC: 1200 MBytes/sec\n", pfx);
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_800_MBPS)
printf("%s FC: 800 MBytes/sec\n", pfx);
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_1600_MBPS)
printf("%s FC: 1600 MBytes/sec\n", pfx);
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_400_MBPS)
printf("%s FC: 400 MBytes/sec\n", pfx);
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_200_MBPS)
printf("%s FC: 200 MBytes/sec\n", pfx);
- if (id[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
+ if (map->page_00h[SFF8636_FC_SPEED_OFFSET] & SFF8636_FC_SPEED_100_MBPS)
printf("%s FC: 100 MBytes/sec\n", pfx);
}
-static void sff8636_show_encoding(const __u8 *id)
+static void sff8636_show_encoding(const struct sff8636_memory_map *map)
{
- sff8024_show_encoding(id, SFF8636_ENCODING_OFFSET, ETH_MODULE_SFF_8636);
+ sff8024_show_encoding(map->page_00h, SFF8636_ENCODING_OFFSET,
+ ETH_MODULE_SFF_8636);
}
-static void sff8636_show_rate_identifier(const __u8 *id)
+static void sff8636_show_rate_identifier(const struct sff8636_memory_map *map)
{
/* TODO: Need to fix rate select logic */
printf("\t%-41s : 0x%02x\n", "Rate identifier",
- id[SFF8636_EXT_RS_OFFSET]);
+ map->page_00h[SFF8636_EXT_RS_OFFSET]);
}
-static void sff8636_show_oui(const __u8 *id, int id_offset)
-{
- sff8024_show_oui(id, id_offset);
-}
-
-static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
+static void
+sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *map)
{
printf("\t%-41s : 0x%02x", "Transmitter technology",
- (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK));
+ map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
+ SFF8636_TRANS_TECH_MASK);
- switch (id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK) {
+ switch (map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
+ SFF8636_TRANS_TECH_MASK) {
case SFF8636_TRANS_850_VCSEL:
printf(" (850 nm VCSEL)\n");
break;
@@ -650,31 +670,26 @@ static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
break;
}
- if ((id[SFF8636_DEVICE_TECH_OFFSET] & SFF8636_TRANS_TECH_MASK)
- >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
+ if ((map->page_00h[SFF8636_DEVICE_TECH_OFFSET] &
+ SFF8636_TRANS_TECH_MASK) >= SFF8636_TRANS_COPPER_PAS_UNEQUAL) {
printf("\t%-41s : %udb\n", "Attenuation at 2.5GHz",
- id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
+ map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET]);
printf("\t%-41s : %udb\n", "Attenuation at 5.0GHz",
- id[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
+ map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]);
printf("\t%-41s : %udb\n", "Attenuation at 7.0GHz",
- id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
+ map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET]);
printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
- id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
+ map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]);
} else {
printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
- (((id[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
- id[SFF8636_WAVELEN_LOW_BYTE_OFFSET])*0.05));
+ (((map->page_00h[SFF8636_WAVELEN_HIGH_BYTE_OFFSET] << 8) |
+ map->page_00h[SFF8636_WAVELEN_LOW_BYTE_OFFSET]) * 0.05));
printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
- (((id[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
- id[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET])*0.005));
+ (((map->page_00h[SFF8636_WAVE_TOL_HIGH_BYTE_OFFSET] << 8) |
+ map->page_00h[SFF8636_WAVE_TOL_LOW_BYTE_OFFSET]) * 0.005));
}
}
-static void sff8636_show_revision_compliance(const __u8 *id)
-{
- sff_show_revision_compliance(id, SFF8636_REV_COMPLIANCE_OFFSET);
-}
-
/*
* 2-byte internal temperature conversions:
* First byte is a signed 8-bit integer, which is the temp decimal part
@@ -683,39 +698,65 @@ static void sff8636_show_revision_compliance(const __u8 *id)
#define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
-static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff_diags *sd)
+static void sff8636_dom_parse(const struct sff8636_memory_map *map,
+ struct sff_diags *sd)
{
+ const __u8 *id = map->lower_memory;
int i = 0;
/* Monitoring Thresholds for Alarms and Warnings */
sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(id, SFF8636_VCC_CURR);
- sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HALRM);
- sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LALRM);
- sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_HWARN);
- sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_VCC_LWARN);
-
sd->sfp_temp[MCURR] = SFF8636_OFFSET_TO_TEMP(SFF8636_TEMP_CURR);
- sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HALRM);
- sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LALRM);
- sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_HWARN);
- sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(page_three, SFF8636_TEMP_LWARN);
-
- sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HALRM);
- sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LALRM);
- sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_HWARN);
- sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_BIAS_LWARN);
-
- sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HALRM);
- sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LALRM);
- sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_HWARN);
- sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_TX_PWR_LWARN);
-
- sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HALRM);
- sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LALRM);
- sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_HWARN);
- sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(page_three, SFF8636_RX_PWR_LWARN);
-
+ if (!map->page_03h)
+ goto out;
+
+ sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_VCC_HALRM);
+ sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_VCC_LALRM);
+ sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_VCC_HWARN);
+ sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_VCC_LWARN);
+
+ sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TEMP_HALRM);
+ sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TEMP_LALRM);
+ sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TEMP_HWARN);
+ sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TEMP_LWARN);
+
+ sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_BIAS_HALRM);
+ sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_BIAS_LALRM);
+ sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_BIAS_HWARN);
+ sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_BIAS_LWARN);
+
+ sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_PWR_HALRM);
+ sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_PWR_LALRM);
+ sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_PWR_HWARN);
+ sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_TX_PWR_LWARN);
+
+ sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_RX_PWR_HALRM);
+ sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_RX_PWR_LALRM);
+ sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_RX_PWR_HWARN);
+ sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_03h,
+ SFF8636_RX_PWR_LWARN);
+
+out:
/* Channel Specific Data */
for (i = 0; i < MAX_CHANNEL_NUM; i++) {
u8 rx_power_offset, tx_bias_offset;
@@ -749,7 +790,7 @@ static void sff8636_dom_parse(const __u8 *id, const __u8 *page_three, struct sff
}
}
-static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eeprom_len)
+static void sff8636_show_dom(const struct sff8636_memory_map *map)
{
struct sff_diags sd = {0};
char *rx_power_string = NULL;
@@ -763,20 +804,15 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
* and thresholds
* If pagging support exists, then supports_alarms is marked as 1
*/
+ if (map->page_03h)
+ sd.supports_alarms = 1;
- if (eeprom_len == ETH_MODULE_SFF_8636_MAX_LEN) {
- if (!(id[SFF8636_STATUS_2_OFFSET] &
- SFF8636_STATUS_PAGE_3_PRESENT)) {
- sd.supports_alarms = 1;
- }
- }
+ sd.rx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
+ SFF8636_RX_PWR_TYPE_MASK;
+ sd.tx_power_type = map->page_00h[SFF8636_DIAG_TYPE_OFFSET] &
+ SFF8636_RX_PWR_TYPE_MASK;
- sd.rx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
- SFF8636_RX_PWR_TYPE_MASK;
- sd.tx_power_type = id[SFF8636_DIAG_TYPE_OFFSET] &
- SFF8636_RX_PWR_TYPE_MASK;
-
- sff8636_dom_parse(id, page_three, &sd);
+ sff8636_dom_parse(map, &sd);
PRINT_TEMP("Module temperature", sd.sfp_temp[MCURR]);
PRINT_VCC("Module voltage", sd.sfp_voltage[MCURR]);
@@ -819,7 +855,7 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
if (sd.supports_alarms) {
for (i = 0; sff8636_aw_flags[i].str; ++i) {
printf("\t%-41s : %s\n", sff8636_aw_flags[i].str,
- id[sff8636_aw_flags[i].offset]
+ map->lower_memory[sff8636_aw_flags[i].offset]
& sff8636_aw_flags[i].value ? "On" : "Off");
}
@@ -827,39 +863,39 @@ static void sff8636_show_dom(const __u8 *id, const __u8 *page_three, __u32 eepro
}
}
-static void sff8636_show_page_zero(const __u8 *id)
+static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
{
- sff8636_show_ext_identifier(id);
- sff8636_show_connector(id);
- sff8636_show_transceiver(id);
- sff8636_show_encoding(id);
- sff_show_value_with_unit(id, SFF8636_BR_NOMINAL_OFFSET,
- "BR, Nominal", 100, "Mbps");
- sff8636_show_rate_identifier(id);
- sff_show_value_with_unit(id, SFF8636_SM_LEN_OFFSET,
- "Length (SMF,km)", 1, "km");
- sff_show_value_with_unit(id, SFF8636_OM3_LEN_OFFSET,
- "Length (OM3 50um)", 2, "m");
- sff_show_value_with_unit(id, SFF8636_OM2_LEN_OFFSET,
- "Length (OM2 50um)", 1, "m");
- sff_show_value_with_unit(id, SFF8636_OM1_LEN_OFFSET,
- "Length (OM1 62.5um)", 1, "m");
- sff_show_value_with_unit(id, SFF8636_CBL_LEN_OFFSET,
- "Length (Copper or Active cable)", 1, "m");
- sff8636_show_wavelength_or_copper_compliance(id);
- sff_show_ascii(id, SFF8636_VENDOR_NAME_START_OFFSET,
+ sff8636_show_ext_identifier(map);
+ sff8636_show_connector(map);
+ sff8636_show_transceiver(map);
+ sff8636_show_encoding(map);
+ sff_show_value_with_unit(map->page_00h, SFF8636_BR_NOMINAL_OFFSET,
+ "BR, Nominal", 100, "Mbps");
+ sff8636_show_rate_identifier(map);
+ sff_show_value_with_unit(map->page_00h, SFF8636_SM_LEN_OFFSET,
+ "Length (SMF,km)", 1, "km");
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM3_LEN_OFFSET,
+ "Length (OM3 50um)", 2, "m");
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM2_LEN_OFFSET,
+ "Length (OM2 50um)", 1, "m");
+ sff_show_value_with_unit(map->page_00h, SFF8636_OM1_LEN_OFFSET,
+ "Length (OM1 62.5um)", 1, "m");
+ sff_show_value_with_unit(map->page_00h, SFF8636_CBL_LEN_OFFSET,
+ "Length (Copper or Active cable)", 1, "m");
+ sff8636_show_wavelength_or_copper_compliance(map);
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_NAME_START_OFFSET,
SFF8636_VENDOR_NAME_END_OFFSET, "Vendor name");
- sff8636_show_oui(id, SFF8636_VENDOR_OUI_OFFSET);
- sff_show_ascii(id, SFF8636_VENDOR_PN_START_OFFSET,
+ sff8024_show_oui(map->page_00h, SFF8636_VENDOR_OUI_OFFSET);
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_PN_START_OFFSET,
SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN");
- sff_show_ascii(id, SFF8636_VENDOR_REV_START_OFFSET,
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_REV_START_OFFSET,
SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev");
- sff_show_ascii(id, SFF8636_VENDOR_SN_START_OFFSET,
+ sff_show_ascii(map->page_00h, SFF8636_VENDOR_SN_START_OFFSET,
SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN");
- sff_show_ascii(id, SFF8636_DATE_YEAR_OFFSET,
+ sff_show_ascii(map->page_00h, SFF8636_DATE_YEAR_OFFSET,
SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
- sff8636_show_revision_compliance(id);
-
+ sff_show_revision_compliance(map->lower_memory,
+ SFF8636_REV_COMPLIANCE_OFFSET);
}
static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
@@ -896,13 +932,13 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
sff8636_memory_map_init_buf(&map, id, eeprom_len);
- sff8636_show_identifier(id);
- switch (id[SFF8636_ID_OFFSET]) {
+ sff8636_show_identifier(&map);
+ switch (map.lower_memory[SFF8636_ID_OFFSET]) {
case SFF8024_ID_QSFP:
case SFF8024_ID_QSFP_PLUS:
case SFF8024_ID_QSFP28:
- sff8636_show_page_zero(id);
- sff8636_show_dom(id, id + 3 * 0x80, eeprom_len);
+ sff8636_show_page_zero(&map);
+ sff8636_show_dom(&map);
break;
}
}
@@ -939,9 +975,7 @@ void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
sff8636_memory_map_init_pages(&map, page_zero, page_three);
- sff8636_show_identifier(page_zero->data);
- sff8636_show_page_zero(page_zero->data);
- if (page_three)
- sff8636_show_dom(page_zero->data, page_three->data - 0x80,
- ETH_MODULE_SFF_8636_MAX_LEN);
+ sff8636_show_identifier(&map);
+ sff8636_show_page_zero(&map);
+ sff8636_show_dom(&map);
}
--
2.35.1

View File

@ -1,73 +0,0 @@
From 2e122ad9aa2aa0259df1035e3ec2765d8e008394 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:19 +0300
Subject: [PATCH 20/35] sff-8636: Consolidate code between IOCTL and netlink
paths
Now that both the netlink and IOCTL paths use the same memory map
structure for parsing, the code can be easily consolidated.
Note that the switch-case statement is not necessary for the netlink
path, as the netlink code (i.e., netlink/module-eeprom.c) already
performed the check, but it is required for the IOCTL path.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/qsfp.c b/qsfp.c
index 354b3b1ce9ff..4aa49351e6b7 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -898,6 +898,19 @@ static void sff8636_show_page_zero(const struct sff8636_memory_map *map)
SFF8636_REV_COMPLIANCE_OFFSET);
}
+static void sff8636_show_all_common(const struct sff8636_memory_map *map)
+{
+ sff8636_show_identifier(map);
+ switch (map->lower_memory[SFF8636_ID_OFFSET]) {
+ case SFF8024_ID_QSFP:
+ case SFF8024_ID_QSFP_PLUS:
+ case SFF8024_ID_QSFP28:
+ sff8636_show_page_zero(map);
+ sff8636_show_dom(map);
+ break;
+ }
+}
+
static void sff8636_memory_map_init_buf(struct sff8636_memory_map *map,
const __u8 *id, __u32 eeprom_len)
{
@@ -931,16 +944,7 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
}
sff8636_memory_map_init_buf(&map, id, eeprom_len);
-
- sff8636_show_identifier(&map);
- switch (map.lower_memory[SFF8636_ID_OFFSET]) {
- case SFF8024_ID_QSFP:
- case SFF8024_ID_QSFP_PLUS:
- case SFF8024_ID_QSFP28:
- sff8636_show_page_zero(&map);
- sff8636_show_dom(&map);
- break;
- }
+ sff8636_show_all_common(&map);
}
static void
@@ -974,8 +978,5 @@ void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
struct sff8636_memory_map map = {};
sff8636_memory_map_init_pages(&map, page_zero, page_three);
-
- sff8636_show_identifier(&map);
- sff8636_show_page_zero(&map);
- sff8636_show_dom(&map);
+ sff8636_show_all_common(&map);
}
--
2.35.1

View File

@ -1,101 +0,0 @@
From 1f20fb8e8b94d049672e48388ae57f89e89e880b Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:20 +0300
Subject: [PATCH 21/35] sff-8079: Split SFF-8079 parsing function
SFF-8079, unlike CMIS and SFF-8636, only has a single page and therefore
its parsing function (i.e., sff8079_show_all()) is called from both the
IOCTL and netlink paths with a buffer pointing to that single page.
In future patches, the netlink code (i.e., netlink/module-eeprom.c) will
no longer call the SFF-8079 code with a buffer pointing to the first 128
bytes of the EEPROM. Instead, the SFF-8079 code will need to request the
needed EEPROM data, as will be done in CMIS and SFF-8636.
Therefore, as a preparation for this change, split the main parsing
function into IOCTL and netlink variants.
No functional changes intended.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
ethtool.c | 4 ++--
internal.h | 3 ++-
netlink/module-eeprom.c | 2 +-
sfpid.c | 12 +++++++++++-
4 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 6c744ff84eb9..5d4b5afbfd47 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4900,10 +4900,10 @@ static int do_getmodule(struct cmd_context *ctx)
switch (modinfo.type) {
#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
case ETH_MODULE_SFF_8079:
- sff8079_show_all(eeprom->data);
+ sff8079_show_all_ioctl(eeprom->data);
break;
case ETH_MODULE_SFF_8472:
- sff8079_show_all(eeprom->data);
+ sff8079_show_all_ioctl(eeprom->data);
sff8472_show_all(eeprom->data);
break;
case ETH_MODULE_SFF_8436:
diff --git a/internal.h b/internal.h
index 7ca6066d4e12..a77efd385698 100644
--- a/internal.h
+++ b/internal.h
@@ -384,7 +384,8 @@ int rxclass_rule_ins(struct cmd_context *ctx,
int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
/* Module EEPROM parsing code */
-void sff8079_show_all(const __u8 *id);
+void sff8079_show_all_ioctl(const __u8 *id);
+void sff8079_show_all_nl(const __u8 *id);
/* Optics diagnostics */
void sff8472_show_all(const __u8 *id);
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index 18b1abbe1252..101d5943c2bc 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -323,7 +323,7 @@ static void decoder_print(void)
switch (module_id) {
case SFF8024_ID_SFP:
- sff8079_show_all(page_zero->data);
+ sff8079_show_all_nl(page_zero->data);
break;
case SFF8024_ID_QSFP:
case SFF8024_ID_QSFP28:
diff --git a/sfpid.c b/sfpid.c
index da2b3f4df3d2..c214820226d1 100644
--- a/sfpid.c
+++ b/sfpid.c
@@ -396,7 +396,7 @@ static void sff8079_show_options(const __u8 *id)
printf("%s Power level 3 requirement\n", pfx);
}
-void sff8079_show_all(const __u8 *id)
+static void sff8079_show_all_common(const __u8 *id)
{
sff8079_show_identifier(id);
if (((id[0] == 0x02) || (id[0] == 0x03)) && (id[1] == 0x04)) {
@@ -439,3 +439,13 @@ void sff8079_show_all(const __u8 *id)
sff8079_show_ascii(id, 84, 91, "Date code");
}
}
+
+void sff8079_show_all_ioctl(const __u8 *id)
+{
+ sff8079_show_all_common(id);
+}
+
+void sff8079_show_all_nl(const __u8 *id)
+{
+ sff8079_show_all_common(id);
+}
--
2.35.1

View File

@ -1,174 +0,0 @@
From fdb457a0ebb57c99fb987d0e34b2549f10dd4161 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:21 +0300
Subject: [PATCH 22/35] netlink: eeprom: Export a function to request an EEPROM
page
The function will be used by the EEPROM parsing code (e.g., cmis.c) to
request a specific page for parsing.
All the data buffers used to store EEPROM page contents are stored on a
linked list that is flushed on exit. This relieves callers from the need
to explicitly free the requested pages.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
netlink/extapi.h | 11 +++++
netlink/module-eeprom.c | 105 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
diff --git a/netlink/extapi.h b/netlink/extapi.h
index 91bf02b5e3be..129e2931d01d 100644
--- a/netlink/extapi.h
+++ b/netlink/extapi.h
@@ -48,6 +48,9 @@ int nl_getmodule(struct cmd_context *ctx);
void nl_monitor_usage(void);
+int nl_get_eeprom_page(struct cmd_context *ctx,
+ struct ethtool_module_eeprom *request);
+
#else /* ETHTOOL_ENABLE_NETLINK */
static inline void netlink_run_handler(struct cmd_context *ctx __maybe_unused,
@@ -73,6 +76,14 @@ static inline void nl_monitor_usage(void)
{
}
+static inline int
+nl_get_eeprom_page(struct cmd_context *ctx __maybe_unused,
+ struct ethtool_module_eeprom *request __maybe_unused)
+{
+ fprintf(stderr, "Netlink not supported by ethtool.\n");
+ return -EOPNOTSUPP;
+}
+
#define nl_gset NULL
#define nl_sset NULL
#define nl_permaddr NULL
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index 101d5943c2bc..ee5508840157 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -341,6 +341,110 @@ static void decoder_print(void)
}
#endif
+static struct list_head eeprom_page_list = LIST_HEAD_INIT(eeprom_page_list);
+
+struct eeprom_page_entry {
+ struct list_head list; /* Member of eeprom_page_list */
+ void *data;
+};
+
+static int eeprom_page_list_add(void *data)
+{
+ struct eeprom_page_entry *entry;
+
+ entry = malloc(sizeof(*entry));
+ if (!entry)
+ return -ENOMEM;
+
+ entry->data = data;
+ list_add(&entry->list, &eeprom_page_list);
+
+ return 0;
+}
+
+static void eeprom_page_list_flush(void)
+{
+ struct eeprom_page_entry *entry;
+ struct list_head *head, *next;
+
+ list_for_each_safe(head, next, &eeprom_page_list) {
+ entry = (struct eeprom_page_entry *) head;
+ free(entry->data);
+ list_del(head);
+ free(entry);
+ }
+}
+
+static int get_eeprom_page_reply_cb(const struct nlmsghdr *nlhdr, void *data)
+{
+ const struct nlattr *tb[ETHTOOL_A_MODULE_EEPROM_DATA + 1] = {};
+ struct ethtool_module_eeprom *request = data;
+ DECLARE_ATTR_TB_INFO(tb);
+ u8 *eeprom_data;
+ int ret;
+
+ ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
+ if (ret < 0)
+ return ret;
+
+ if (!tb[ETHTOOL_A_MODULE_EEPROM_DATA])
+ return MNL_CB_ERROR;
+
+ eeprom_data = mnl_attr_get_payload(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
+ request->data = malloc(request->length);
+ if (!request->data)
+ return MNL_CB_ERROR;
+ memcpy(request->data, eeprom_data, request->length);
+
+ ret = eeprom_page_list_add(request->data);
+ if (ret < 0)
+ goto err_list_add;
+
+ return MNL_CB_OK;
+
+err_list_add:
+ free(request->data);
+ return MNL_CB_ERROR;
+}
+
+int nl_get_eeprom_page(struct cmd_context *ctx,
+ struct ethtool_module_eeprom *request)
+{
+ struct nl_context *nlctx = ctx->nlctx;
+ struct nl_socket *nlsock;
+ struct nl_msg_buff *msg;
+ int ret;
+
+ if (!request || request->i2c_address > ETH_I2C_MAX_ADDRESS)
+ return -EINVAL;
+
+ nlsock = nlctx->ethnl_socket;
+ msg = &nlsock->msgbuff;
+
+ ret = nlsock_prep_get_request(nlsock, ETHTOOL_MSG_MODULE_EEPROM_GET,
+ ETHTOOL_A_MODULE_EEPROM_HEADER, 0);
+ if (ret < 0)
+ return ret;
+
+ if (ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_LENGTH,
+ request->length) ||
+ ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_OFFSET,
+ request->offset) ||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_PAGE,
+ request->page) ||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_BANK,
+ request->bank) ||
+ ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS,
+ request->i2c_address))
+ return -EMSGSIZE;
+
+ ret = nlsock_sendmsg(nlsock, NULL);
+ if (ret < 0)
+ return ret;
+ return nlsock_process_reply(nlsock, get_eeprom_page_reply_cb,
+ (void *)request);
+}
+
int nl_getmodule(struct cmd_context *ctx)
{
struct cmd_params getmodule_cmd_params = {};
@@ -425,6 +529,7 @@ int nl_getmodule(struct cmd_context *ctx)
}
cleanup:
+ eeprom_page_list_flush();
cache_free();
return ret;
}
--
2.35.1

View File

@ -1,194 +0,0 @@
From 5f45f370e132f144cdbab9ea718393bd37ee23db Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:22 +0300
Subject: [PATCH 23/35] cmis: Request specific pages for parsing in netlink
path
In the netlink path, unlike the IOCTL path, user space requests specific
EEPROM pages from the kernel. The presence of optional and banked pages
is advertised via various bits in the EEPROM contents.
Currently, for CMIS, the Lower Memory, Page 00h and the optional Page
01h are requested by the netlink code (i.e., netlink/module-eeprom.c)
and passed to the CMIS code (i.e., cmis.c) as two arguments for parsing.
This is problematic for several reasons. First, this approach is not
very scaleable as CMIS supports a lot of optional and banked pages.
Passing them as separate arguments to the CMIS code is not going to
work.
Second, the knowledge of which optional and banked pages are available
is encapsulated in the CMIS parsing code. As such, the common netlink
code has no business of fetching optional and banked pages that might be
invalid.
Instead, pass the command context to the CMIS parsing function and allow
it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
message.
Tested by making sure that the output of 'ethtool -m' does not change
before and after the patch.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 60 ++++++++++++++++++++++++++++++++---------
cmis.h | 3 +--
netlink/module-eeprom.c | 7 +++--
3 files changed, 51 insertions(+), 19 deletions(-)
diff --git a/cmis.c b/cmis.c
index eb7791dd59df..4798fd4c7d68 100644
--- a/cmis.c
+++ b/cmis.c
@@ -9,9 +9,11 @@
#include <stdio.h>
#include <math.h>
+#include <errno.h>
#include "internal.h"
#include "sff-common.h"
#include "cmis.h"
+#include "netlink/extapi.h"
struct cmis_memory_map {
const __u8 *lower_memory;
@@ -21,6 +23,7 @@ struct cmis_memory_map {
};
#define CMIS_PAGE_SIZE 0x80
+#define CMIS_I2C_ADDRESS 0x50
static void cmis_show_identifier(const struct cmis_memory_map *map)
{
@@ -384,36 +387,67 @@ void cmis_show_all_ioctl(const __u8 *id)
cmis_show_all_common(&map);
}
-static void
-cmis_memory_map_init_pages(struct cmis_memory_map *map,
- const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_one)
+static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
+ u8 page, u32 offset)
{
+ request->offset = offset;
+ request->length = CMIS_PAGE_SIZE;
+ request->page = page;
+ request->bank = bank;
+ request->i2c_address = CMIS_I2C_ADDRESS;
+ request->data = NULL;
+}
+
+static int
+cmis_memory_map_init_pages(struct cmd_context *ctx,
+ struct cmis_memory_map *map)
+{
+ struct ethtool_module_eeprom request;
+ int ret;
+
/* Lower Memory and Page 00h are always present.
*
* Offset into Upper Memory is between page size and twice the page
* size. Therefore, set the base address of each page to its base
- * address minus page size. For Page 00h, this is the address of the
- * Lower Memory.
+ * address minus page size.
*/
- map->lower_memory = page_zero->data;
- map->page_00h = page_zero->data;
+ cmis_request_init(&request, 0, 0x0, 0);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->lower_memory = request.data;
+
+ cmis_request_init(&request, 0, 0x0, CMIS_PAGE_SIZE);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->page_00h = request.data - CMIS_PAGE_SIZE;
/* Page 01h is only present when the module memory model is paged and
* not flat.
*/
if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
CMIS_MEMORY_MODEL_MASK)
- return;
+ return 0;
+
+ cmis_request_init(&request, 0, 0x1, CMIS_PAGE_SIZE);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->page_01h = request.data - CMIS_PAGE_SIZE;
- map->page_01h = page_one->data - CMIS_PAGE_SIZE;
+ return 0;
}
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_one)
+int cmis_show_all_nl(struct cmd_context *ctx)
{
struct cmis_memory_map map = {};
+ int ret;
- cmis_memory_map_init_pages(&map, page_zero, page_one);
+ ret = cmis_memory_map_init_pages(ctx, &map);
+ if (ret < 0)
+ return ret;
cmis_show_all_common(&map);
+
+ return 0;
}
diff --git a/cmis.h b/cmis.h
index c878e3bc5afd..911491dc5c8f 100644
--- a/cmis.h
+++ b/cmis.h
@@ -123,7 +123,6 @@
void cmis_show_all_ioctl(const __u8 *id);
-void cmis_show_all_nl(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_one);
+int cmis_show_all_nl(struct cmd_context *ctx);
#endif /* CMIS_H__ */
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index ee5508840157..a8e2662e0b8c 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -314,11 +314,10 @@ static int decoder_prefetch(struct nl_context *nlctx)
return page_fetch(nlctx, &request);
}
-static void decoder_print(void)
+static void decoder_print(struct cmd_context *ctx)
{
struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
- struct ethtool_module_eeprom *page_one = cache_get(1, 0, ETH_I2C_ADDRESS_LOW);
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
switch (module_id) {
@@ -332,7 +331,7 @@ static void decoder_print(void)
break;
case SFF8024_ID_QSFP_DD:
case SFF8024_ID_DSFP:
- cmis_show_all_nl(page_zero, page_one);
+ cmis_show_all_nl(ctx);
break;
default:
dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
@@ -524,7 +523,7 @@ int nl_getmodule(struct cmd_context *ctx)
ret = decoder_prefetch(nlctx);
if (ret)
goto cleanup;
- decoder_print();
+ decoder_print(ctx);
#endif
}
--
2.35.1

View File

@ -1,181 +0,0 @@
From fdae2732b25090f9d41e192a5dd47a45a6516a94 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:23 +0300
Subject: [PATCH 24/35] sff-8636: Request specific pages for parsing in netlink
path
In the netlink path, unlike the IOCTL path, user space requests specific
EEPROM pages from the kernel. The presence of optional pages is
advertised via various bits in the EEPROM contents.
Currently, for SFF-8636, the Lower Memory, Page 00h and the optional
Page 03h are requested by the netlink code (i.e.,
netlink/module-eeprom.c) and passed to the SFF-8636 code (i.e., qsfp.c)
as two arguments for parsing.
This is problematic for several reasons. First, this approach is not
very scaleable as SFF-8636 supports a lot of optional pages. Passing
them as separate arguments to the SFF-8636 code is not going to work.
Second, the knowledge of which optional pages are available is
encapsulated in the SFF-8636 parsing code. As such, the common netlink
code has no business of fetching optional pages that might be invalid.
Instead, pass the command context to the SFF-8636 parsing function and
allow it to fetch only valid pages via the 'MODULE_EEPROM_GET' netlink
message.
Tested by making sure that the output of 'ethtool -m' does not change
before and after the patch.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
internal.h | 3 +--
netlink/module-eeprom.c | 3 +--
qsfp.c | 60 ++++++++++++++++++++++++++++++++---------
3 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/internal.h b/internal.h
index a77efd385698..2407d3c223fa 100644
--- a/internal.h
+++ b/internal.h
@@ -392,8 +392,7 @@ void sff8472_show_all(const __u8 *id);
/* QSFP Optics diagnostics */
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_three);
+int sff8636_show_all_nl(struct cmd_context *ctx);
/* FUJITSU Extended Socket network device */
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index a8e2662e0b8c..f04f8e134223 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -316,7 +316,6 @@ static int decoder_prefetch(struct nl_context *nlctx)
static void decoder_print(struct cmd_context *ctx)
{
- struct ethtool_module_eeprom *page_three = cache_get(3, 0, ETH_I2C_ADDRESS_LOW);
struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
@@ -327,7 +326,7 @@ static void decoder_print(struct cmd_context *ctx)
case SFF8024_ID_QSFP:
case SFF8024_ID_QSFP28:
case SFF8024_ID_QSFP_PLUS:
- sff8636_show_all_nl(page_zero, page_three);
+ sff8636_show_all_nl(ctx);
break;
case SFF8024_ID_QSFP_DD:
case SFF8024_ID_DSFP:
diff --git a/qsfp.c b/qsfp.c
index 4aa49351e6b7..e7c2f51cd9c6 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -55,10 +55,12 @@
**/
#include <stdio.h>
#include <math.h>
+#include <errno.h>
#include "internal.h"
#include "sff-common.h"
#include "qsfp.h"
#include "cmis.h"
+#include "netlink/extapi.h"
struct sff8636_memory_map {
const __u8 *lower_memory;
@@ -68,6 +70,7 @@ struct sff8636_memory_map {
};
#define SFF8636_PAGE_SIZE 0x80
+#define SFF8636_I2C_ADDRESS 0x50
#define MAX_DESC_SIZE 42
@@ -947,36 +950,67 @@ void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len)
sff8636_show_all_common(&map);
}
-static void
-sff8636_memory_map_init_pages(struct sff8636_memory_map *map,
- const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_three)
+static void sff8636_request_init(struct ethtool_module_eeprom *request, u8 page,
+ u32 offset)
+{
+ request->offset = offset;
+ request->length = SFF8636_PAGE_SIZE;
+ request->page = page;
+ request->bank = 0;
+ request->i2c_address = SFF8636_I2C_ADDRESS;
+ request->data = NULL;
+}
+
+static int
+sff8636_memory_map_init_pages(struct cmd_context *ctx,
+ struct sff8636_memory_map *map)
{
+ struct ethtool_module_eeprom request;
+ int ret;
+
/* Lower Memory and Page 00h are always present.
*
* Offset into Upper Memory is between page size and twice the page
* size. Therefore, set the base address of each page to its base
- * address minus page size. For Page 00h, this is the address of the
- * Lower Memory.
+ * address minus page size.
*/
- map->lower_memory = page_zero->data;
- map->page_00h = page_zero->data;
+ sff8636_request_init(&request, 0x0, 0);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->lower_memory = request.data;
+
+ sff8636_request_init(&request, 0x0, SFF8636_PAGE_SIZE);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->page_00h = request.data - SFF8636_PAGE_SIZE;
/* Page 03h is only present when the module memory model is paged and
* not flat.
*/
if (map->lower_memory[SFF8636_STATUS_2_OFFSET] &
SFF8636_STATUS_PAGE_3_PRESENT)
- return;
+ return 0;
- map->page_03h = page_three->data - SFF8636_PAGE_SIZE;
+ sff8636_request_init(&request, 0x3, SFF8636_PAGE_SIZE);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->page_03h = request.data - SFF8636_PAGE_SIZE;
+
+ return 0;
}
-void sff8636_show_all_nl(const struct ethtool_module_eeprom *page_zero,
- const struct ethtool_module_eeprom *page_three)
+int sff8636_show_all_nl(struct cmd_context *ctx)
{
struct sff8636_memory_map map = {};
+ int ret;
- sff8636_memory_map_init_pages(&map, page_zero, page_three);
+ ret = sff8636_memory_map_init_pages(ctx, &map);
+ if (ret < 0)
+ return ret;
sff8636_show_all_common(&map);
+
+ return 0;
}
--
2.35.1

View File

@ -1,92 +0,0 @@
From bda06d81f41bb1cde16a319728d479cda4b9f295 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:24 +0300
Subject: [PATCH 25/35] sff-8079: Request specific pages for parsing in netlink
path
Convert the SFF-8079 code to request the required EEPROM contents in the
netlink path as was done for CMIS and SFF-8636. It will allow us to
remove standard-specific code from the netlink code (i.e.,
netlink/module-eeprom.c).
In addition, in the future, it will allow the netlink path to support
parsing of SFF-8472.
Tested by making sure that the output of 'ethtool -m' does not change
before and after the patch.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
internal.h | 2 +-
netlink/module-eeprom.c | 2 +-
sfpid.c | 20 ++++++++++++++++++--
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/internal.h b/internal.h
index 2407d3c223fa..0d9d816ab563 100644
--- a/internal.h
+++ b/internal.h
@@ -385,7 +385,7 @@ int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
/* Module EEPROM parsing code */
void sff8079_show_all_ioctl(const __u8 *id);
-void sff8079_show_all_nl(const __u8 *id);
+int sff8079_show_all_nl(struct cmd_context *ctx);
/* Optics diagnostics */
void sff8472_show_all(const __u8 *id);
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index f04f8e134223..6d76b8a96461 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -321,7 +321,7 @@ static void decoder_print(struct cmd_context *ctx)
switch (module_id) {
case SFF8024_ID_SFP:
- sff8079_show_all_nl(page_zero->data);
+ sff8079_show_all_nl(ctx);
break;
case SFF8024_ID_QSFP:
case SFF8024_ID_QSFP28:
diff --git a/sfpid.c b/sfpid.c
index c214820226d1..621d1e86c278 100644
--- a/sfpid.c
+++ b/sfpid.c
@@ -8,8 +8,13 @@
*/
#include <stdio.h>
+#include <errno.h>
#include "internal.h"
#include "sff-common.h"
+#include "netlink/extapi.h"
+
+#define SFF8079_PAGE_SIZE 0x80
+#define SFF8079_I2C_ADDRESS_LOW 0x50
static void sff8079_show_identifier(const __u8 *id)
{
@@ -445,7 +450,18 @@ void sff8079_show_all_ioctl(const __u8 *id)
sff8079_show_all_common(id);
}
-void sff8079_show_all_nl(const __u8 *id)
+int sff8079_show_all_nl(struct cmd_context *ctx)
{
- sff8079_show_all_common(id);
+ struct ethtool_module_eeprom request = {
+ .length = SFF8079_PAGE_SIZE,
+ .i2c_address = SFF8079_I2C_ADDRESS_LOW,
+ };
+ int ret;
+
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ sff8079_show_all_common(request.data);
+
+ return 0;
}
--
2.35.1

View File

@ -1,428 +0,0 @@
From b6005ecf2ce2aaeb86995fa50df97e7384f46f99 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 12 Oct 2021 16:25:25 +0300
Subject: [PATCH 26/35] netlink: eeprom: Defer page requests to individual
parsers
The individual EEPROM parsers (e.g., CMIS, SFF-8636) now request the
EEPROM pages they intend to parse and populate their memory maps before
parsing them.
Therefore, there is no need for the common netlink code to request
potentially invalid pages and pass them as blobs to these parsers.
Instead, only query the SFF-8024 Identifier Value which is located at
I2C address 0x50, byte 0 and dispatch to the relevant EEPROM parser.
Tested by making sure that the output of 'ethtool -m' does not change
for SFF-8079, SFF-8636 and CMIS before and after the patch.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
netlink/module-eeprom.c | 347 +++++++---------------------------------
1 file changed, 59 insertions(+), 288 deletions(-)
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index 6d76b8a96461..f359aeec4ddf 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -19,7 +19,6 @@
#include "parser.h"
#define ETH_I2C_ADDRESS_LOW 0x50
-#define ETH_I2C_ADDRESS_HIGH 0x51
#define ETH_I2C_MAX_ADDRESS 0x7F
struct cmd_params {
@@ -78,267 +77,6 @@ static const struct param_parser getmodule_params[] = {
{}
};
-struct page_entry {
- struct list_head link;
- struct ethtool_module_eeprom *page;
-};
-
-static struct list_head page_list = LIST_HEAD_INIT(page_list);
-
-static int cache_add(struct ethtool_module_eeprom *page)
-{
- struct page_entry *list_element;
-
- if (!page)
- return -1;
- list_element = malloc(sizeof(*list_element));
- if (!list_element)
- return -ENOMEM;
- list_element->page = page;
-
- list_add(&list_element->link, &page_list);
- return 0;
-}
-
-static void page_free(struct ethtool_module_eeprom *page)
-{
- free(page->data);
- free(page);
-}
-
-static void cache_del(struct ethtool_module_eeprom *page)
-{
- struct ethtool_module_eeprom *entry;
- struct list_head *head, *next;
-
- list_for_each_safe(head, next, &page_list) {
- entry = ((struct page_entry *)head)->page;
- if (entry == page) {
- list_del(head);
- free(head);
- page_free(entry);
- break;
- }
- }
-}
-
-static void cache_free(void)
-{
- struct ethtool_module_eeprom *entry;
- struct list_head *head, *next;
-
- list_for_each_safe(head, next, &page_list) {
- entry = ((struct page_entry *)head)->page;
- list_del(head);
- free(head);
- page_free(entry);
- }
-}
-
-static struct ethtool_module_eeprom *page_join(struct ethtool_module_eeprom *page_a,
- struct ethtool_module_eeprom *page_b)
-{
- struct ethtool_module_eeprom *joined_page;
- u32 total_length;
-
- if (!page_a || !page_b ||
- page_a->page != page_b->page ||
- page_a->bank != page_b->bank ||
- page_a->i2c_address != page_b->i2c_address)
- return NULL;
-
- total_length = page_a->length + page_b->length;
- joined_page = calloc(1, sizeof(*joined_page));
- joined_page->data = calloc(1, total_length);
- joined_page->page = page_a->page;
- joined_page->bank = page_a->bank;
- joined_page->length = total_length;
- joined_page->i2c_address = page_a->i2c_address;
-
- if (page_a->offset < page_b->offset) {
- memcpy(joined_page->data, page_a->data, page_a->length);
- memcpy(joined_page->data + page_a->length, page_b->data, page_b->length);
- joined_page->offset = page_a->offset;
- } else {
- memcpy(joined_page->data, page_b->data, page_b->length);
- memcpy(joined_page->data + page_b->length, page_a->data, page_a->length);
- joined_page->offset = page_b->offset;
- }
-
- return joined_page;
-}
-
-static struct ethtool_module_eeprom *cache_get(u32 page, u32 bank, u8 i2c_address)
-{
- struct ethtool_module_eeprom *entry;
- struct list_head *head, *next;
-
- list_for_each_safe(head, next, &page_list) {
- entry = ((struct page_entry *)head)->page;
- if (entry->page == page && entry->bank == bank &&
- entry->i2c_address == i2c_address)
- return entry;
- }
-
- return NULL;
-}
-
-static int getmodule_page_fetch_reply_cb(const struct nlmsghdr *nlhdr,
- void *data)
-{
- const struct nlattr *tb[ETHTOOL_A_MODULE_EEPROM_DATA + 1] = {};
- DECLARE_ATTR_TB_INFO(tb);
- struct ethtool_module_eeprom *lower_page;
- struct ethtool_module_eeprom *response;
- struct ethtool_module_eeprom *request;
- struct ethtool_module_eeprom *joined;
- u8 *eeprom_data;
- int ret;
-
- ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
- if (ret < 0)
- return ret;
-
- if (!tb[ETHTOOL_A_MODULE_EEPROM_DATA]) {
- fprintf(stderr, "Malformed netlink message (getmodule)\n");
- return MNL_CB_ERROR;
- }
-
- response = calloc(1, sizeof(*response));
- if (!response)
- return -ENOMEM;
-
- request = (struct ethtool_module_eeprom *)data;
- response->offset = request->offset;
- response->page = request->page;
- response->bank = request->bank;
- response->i2c_address = request->i2c_address;
- response->length = mnl_attr_get_payload_len(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
- eeprom_data = mnl_attr_get_payload(tb[ETHTOOL_A_MODULE_EEPROM_DATA]);
-
- response->data = malloc(response->length);
- if (!response->data) {
- free(response);
- return -ENOMEM;
- }
- memcpy(response->data, eeprom_data, response->length);
-
- if (!request->page) {
- lower_page = cache_get(request->page, request->bank, response->i2c_address);
- if (lower_page) {
- joined = page_join(lower_page, response);
- page_free(response);
- cache_del(lower_page);
- return cache_add(joined);
- }
- }
-
- return cache_add(response);
-}
-
-static int page_fetch(struct nl_context *nlctx, const struct ethtool_module_eeprom *request)
-{
- struct nl_socket *nlsock = nlctx->ethnl_socket;
- struct nl_msg_buff *msg = &nlsock->msgbuff;
- struct ethtool_module_eeprom *page;
- int ret;
-
- if (!request || request->i2c_address > ETH_I2C_MAX_ADDRESS)
- return -EINVAL;
-
- /* Satisfy request right away, if region is already in cache */
- page = cache_get(request->page, request->bank, request->i2c_address);
- if (page && page->offset <= request->offset &&
- page->offset + page->length >= request->offset + request->length) {
- return 0;
- }
-
- ret = nlsock_prep_get_request(nlsock, ETHTOOL_MSG_MODULE_EEPROM_GET,
- ETHTOOL_A_MODULE_EEPROM_HEADER, 0);
- if (ret < 0)
- return ret;
-
- if (ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_LENGTH, request->length) ||
- ethnla_put_u32(msg, ETHTOOL_A_MODULE_EEPROM_OFFSET, request->offset) ||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_PAGE, request->page) ||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_BANK, request->bank) ||
- ethnla_put_u8(msg, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, request->i2c_address))
- return -EMSGSIZE;
-
- ret = nlsock_sendmsg(nlsock, NULL);
- if (ret < 0)
- return ret;
- ret = nlsock_process_reply(nlsock, getmodule_page_fetch_reply_cb, (void *)request);
- if (ret < 0)
- return ret;
-
- return nlsock_process_reply(nlsock, nomsg_reply_cb, NULL);
-}
-
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
-static int decoder_prefetch(struct nl_context *nlctx)
-{
- struct ethtool_module_eeprom *page_zero_lower = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
- struct ethtool_module_eeprom request = {0};
- u8 module_id = page_zero_lower->data[0];
- int err = 0;
-
- /* Fetch rest of page 00 */
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
- request.offset = 128;
- request.length = 128;
- err = page_fetch(nlctx, &request);
- if (err)
- return err;
-
- switch (module_id) {
- case SFF8024_ID_QSFP:
- case SFF8024_ID_QSFP28:
- case SFF8024_ID_QSFP_PLUS:
- memset(&request, 0, sizeof(request));
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
- request.offset = 128;
- request.length = 128;
- request.page = 3;
- break;
- case SFF8024_ID_QSFP_DD:
- case SFF8024_ID_DSFP:
- memset(&request, 0, sizeof(request));
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
- request.offset = 128;
- request.length = 128;
- request.page = 1;
- break;
- }
-
- return page_fetch(nlctx, &request);
-}
-
-static void decoder_print(struct cmd_context *ctx)
-{
- struct ethtool_module_eeprom *page_zero = cache_get(0, 0, ETH_I2C_ADDRESS_LOW);
- u8 module_id = page_zero->data[SFF8636_ID_OFFSET];
-
- switch (module_id) {
- case SFF8024_ID_SFP:
- sff8079_show_all_nl(ctx);
- break;
- case SFF8024_ID_QSFP:
- case SFF8024_ID_QSFP28:
- case SFF8024_ID_QSFP_PLUS:
- sff8636_show_all_nl(ctx);
- break;
- case SFF8024_ID_QSFP_DD:
- case SFF8024_ID_DSFP:
- cmis_show_all_nl(ctx);
- break;
- default:
- dump_hex(stdout, page_zero->data, page_zero->length, page_zero->offset);
- break;
- }
-}
-#endif
-
static struct list_head eeprom_page_list = LIST_HEAD_INIT(eeprom_page_list);
struct eeprom_page_entry {
@@ -443,14 +181,64 @@ int nl_get_eeprom_page(struct cmd_context *ctx,
(void *)request);
}
+static int eeprom_dump_hex(struct cmd_context *ctx)
+{
+ struct ethtool_module_eeprom request = {
+ .length = 128,
+ .i2c_address = ETH_I2C_ADDRESS_LOW,
+ };
+ int ret;
+
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+
+ dump_hex(stdout, request.data, request.length, request.offset);
+
+ return 0;
+}
+
+static int eeprom_parse(struct cmd_context *ctx)
+{
+ struct ethtool_module_eeprom request = {
+ .length = 1,
+ .i2c_address = ETH_I2C_ADDRESS_LOW,
+ };
+ int ret;
+
+ /* Fetch the SFF-8024 Identifier Value. For all supported standards, it
+ * is located at I2C address 0x50, byte 0. See section 4.1 in SFF-8024,
+ * revision 4.9.
+ */
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+
+ switch (request.data[0]) {
+#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
+ case SFF8024_ID_SFP:
+ return sff8079_show_all_nl(ctx);
+ case SFF8024_ID_QSFP:
+ case SFF8024_ID_QSFP28:
+ case SFF8024_ID_QSFP_PLUS:
+ return sff8636_show_all_nl(ctx);
+ case SFF8024_ID_QSFP_DD:
+ case SFF8024_ID_DSFP:
+ return cmis_show_all_nl(ctx);
+#endif
+ default:
+ /* If we cannot recognize the memory map, default to dumping
+ * the first 128 bytes in hex.
+ */
+ return eeprom_dump_hex(ctx);
+ }
+}
+
int nl_getmodule(struct cmd_context *ctx)
{
struct cmd_params getmodule_cmd_params = {};
struct ethtool_module_eeprom request = {0};
- struct ethtool_module_eeprom *reply_page;
struct nl_context *nlctx = ctx->nlctx;
- u32 dump_length;
- u8 *eeprom_data;
int ret;
if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_EEPROM_GET, false))
@@ -479,12 +267,6 @@ int nl_getmodule(struct cmd_context *ctx)
return -EOPNOTSUPP;
}
- request.i2c_address = ETH_I2C_ADDRESS_LOW;
- request.length = 128;
- ret = page_fetch(nlctx, &request);
- if (ret)
- goto cleanup;
-
#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
if (getmodule_cmd_params.page || getmodule_cmd_params.bank ||
getmodule_cmd_params.offset || getmodule_cmd_params.length)
@@ -501,33 +283,22 @@ int nl_getmodule(struct cmd_context *ctx)
request.offset = 128;
if (getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) {
- ret = page_fetch(nlctx, &request);
+ ret = nl_get_eeprom_page(ctx, &request);
if (ret < 0)
goto cleanup;
- reply_page = cache_get(request.page, request.bank, request.i2c_address);
- if (!reply_page) {
- ret = -EINVAL;
- goto cleanup;
- }
- eeprom_data = reply_page->data + (request.offset - reply_page->offset);
- dump_length = reply_page->length < request.length ? reply_page->length
- : request.length;
if (getmodule_cmd_params.dump_raw)
- fwrite(eeprom_data, 1, request.length, stdout);
+ fwrite(request.data, 1, request.length, stdout);
else
- dump_hex(stdout, eeprom_data, dump_length, request.offset);
+ dump_hex(stdout, request.data, request.length,
+ request.offset);
} else {
-#ifdef ETHTOOL_ENABLE_PRETTY_DUMP
- ret = decoder_prefetch(nlctx);
- if (ret)
+ ret = eeprom_parse(ctx);
+ if (ret < 0)
goto cleanup;
- decoder_print(ctx);
-#endif
}
cleanup:
eeprom_page_list_flush();
- cache_free();
return ret;
}
--
2.35.1

View File

@ -1,84 +0,0 @@
From 37093971b0f645542c4bff603f41f807e8023bd3 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:40:55 +0200
Subject: [PATCH 27/35] sff-8636: Use an SFF-8636 specific define for maximum
number of channels
'MAX_CHANNEL_NUM' is defined in the common SFF code as 4 and used to set
the size of the per-channel diagnostics array in the common 'sff_diags'
structure.
The CMIS parsing code is also going to use the structure, but it can
have up to 32 channels, unlike SFF-8636 that only has 4.
Therefore, set 'MAX_CHANNEL_NUM' to 32 and change the SFF-8636 code to
use an SFF-8636 specific define instead of the common 'MAX_CHANNEL_NUM'.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 9 +++++----
sff-common.h | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/qsfp.c b/qsfp.c
index e7c2f51cd9c6..58c4c4775e9b 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -71,6 +71,7 @@ struct sff8636_memory_map {
#define SFF8636_PAGE_SIZE 0x80
#define SFF8636_I2C_ADDRESS 0x50
+#define SFF8636_MAX_CHANNEL_NUM 4
#define MAX_DESC_SIZE 42
@@ -761,7 +762,7 @@ static void sff8636_dom_parse(const struct sff8636_memory_map *map,
out:
/* Channel Specific Data */
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
u8 rx_power_offset, tx_bias_offset;
u8 tx_power_offset;
@@ -832,13 +833,13 @@ static void sff8636_show_dom(const struct sff8636_memory_map *map)
printf("\t%-41s : %s\n", "Alarm/warning flags implemented",
(sd.supports_alarms ? "Yes" : "No"));
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)",
"Laser tx bias current", i+1);
PRINT_BIAS(power_string, sd.scd[i].bias_cur);
}
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
snprintf(power_string, MAX_DESC_SIZE, "%s (Channel %d)",
"Transmit avg optical power", i+1);
PRINT_xX_PWR(power_string, sd.scd[i].tx_power);
@@ -849,7 +850,7 @@ static void sff8636_show_dom(const struct sff8636_memory_map *map)
else
rx_power_string = "Rcvr signal avg optical power";
- for (i = 0; i < MAX_CHANNEL_NUM; i++) {
+ for (i = 0; i < SFF8636_MAX_CHANNEL_NUM; i++) {
snprintf(power_string, MAX_DESC_SIZE, "%s(Channel %d)",
rx_power_string, i+1);
PRINT_xX_PWR(power_string, sd.scd[i].rx_power);
diff --git a/sff-common.h b/sff-common.h
index 2183f41ff9c9..aab306e0b74f 100644
--- a/sff-common.h
+++ b/sff-common.h
@@ -160,7 +160,7 @@ struct sff_channel_diags {
/* Module Monitoring Fields */
struct sff_diags {
-#define MAX_CHANNEL_NUM 4
+#define MAX_CHANNEL_NUM 32
#define LWARN 0
#define HWARN 1
#define LALRM 2
--
2.35.1

View File

@ -1,45 +0,0 @@
From 2dcf6b9dc1c1874705b9e71e13e00dde9f7f576c Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:40:56 +0200
Subject: [PATCH 28/35] sff-common: Move OFFSET_TO_U16_PTR() to common header
file
The define is also useful for CMIS, so move it from SFF-8636 to the
common header file.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 1 -
sff-common.h | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/qsfp.c b/qsfp.c
index 58c4c4775e9b..b3c9e1516af9 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -700,7 +700,6 @@ sff8636_show_wavelength_or_copper_compliance(const struct sff8636_memory_map *ma
* Second byte are 1/256th of degree, which are added to the dec part.
*/
#define SFF8636_OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
-#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
static void sff8636_dom_parse(const struct sff8636_memory_map *map,
struct sff_diags *sd)
diff --git a/sff-common.h b/sff-common.h
index aab306e0b74f..9e323008ba19 100644
--- a/sff-common.h
+++ b/sff-common.h
@@ -126,8 +126,8 @@
#define SFF8024_ENCODING_PAM4 0x08
/* Most common case: 16-bit unsigned integer in a certain unit */
-#define OFFSET_TO_U16(offset) \
- (id[offset] << 8 | id[(offset) + 1])
+#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
+#define OFFSET_TO_U16(offset) OFFSET_TO_U16_PTR(id, offset)
# define PRINT_xX_PWR(string, var) \
printf("\t%-41s : %.4f mW / %.2f dBm\n", (string), \
--
2.35.1

View File

@ -1,59 +0,0 @@
From 86853162d53b47cd0f6bcb926810aa0fd68b8898 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:40:57 +0200
Subject: [PATCH 29/35] cmis: Initialize Page 02h in memory map
Page 02h stores module and lane thresholds that are going to be parsed
and displayed in subsequent patches.
Request it via the 'MODULE_EEPROM_GET' netlink message and initialize it
in the memory map.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/cmis.c b/cmis.c
index 4798fd4c7d68..55b9d1b959cd 100644
--- a/cmis.c
+++ b/cmis.c
@@ -17,9 +17,10 @@
struct cmis_memory_map {
const __u8 *lower_memory;
- const __u8 *upper_memory[1][2]; /* Bank, Page */
+ const __u8 *upper_memory[1][3]; /* Bank, Page */
#define page_00h upper_memory[0x0][0x0]
#define page_01h upper_memory[0x0][0x1]
+#define page_02h upper_memory[0x0][0x2]
};
#define CMIS_PAGE_SIZE 0x80
@@ -423,8 +424,8 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
return ret;
map->page_00h = request.data - CMIS_PAGE_SIZE;
- /* Page 01h is only present when the module memory model is paged and
- * not flat.
+ /* Pages 01h and 02h are only present when the module memory model is
+ * paged and not flat.
*/
if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
CMIS_MEMORY_MODEL_MASK)
@@ -436,6 +437,12 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
return ret;
map->page_01h = request.data - CMIS_PAGE_SIZE;
+ cmis_request_init(&request, 0, 0x2, CMIS_PAGE_SIZE);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->page_02h = request.data - CMIS_PAGE_SIZE;
+
return 0;
}
--
2.35.1

View File

@ -1,122 +0,0 @@
From 21367ae2b8ebbe5173cbed22dfa51680a3fe48d2 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:40:58 +0200
Subject: [PATCH 30/35] cmis: Initialize Banked Page 11h in memory map
Banked Page 11h stores, among other things, lane-specific flags and
monitors that are going to be parsed and displayed in subsequent
patches.
Request it via the 'MODULE_EEPROM_GET' netlink message and initialize it
in the memory map.
Only initialize it in supported Banks.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
cmis.h | 7 +++++++
2 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/cmis.c b/cmis.c
index 55b9d1b959cd..83ced4d253ae 100644
--- a/cmis.c
+++ b/cmis.c
@@ -15,9 +15,17 @@
#include "cmis.h"
#include "netlink/extapi.h"
+/* The maximum number of supported Banks. Relevant documents:
+ * [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40
+ */
+#define CMIS_MAX_BANKS 4
+
+/* We are not parsing further than Page 11h. */
+#define CMIS_MAX_PAGES 18
+
struct cmis_memory_map {
const __u8 *lower_memory;
- const __u8 *upper_memory[1][3]; /* Bank, Page */
+ const __u8 *upper_memory[CMIS_MAX_BANKS][CMIS_MAX_PAGES];
#define page_00h upper_memory[0x0][0x0]
#define page_01h upper_memory[0x0][0x1]
#define page_02h upper_memory[0x0][0x2]
@@ -399,12 +407,33 @@ static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
request->data = NULL;
}
+static int cmis_num_banks_get(const struct cmis_memory_map *map,
+ int *p_num_banks)
+{
+ switch (map->page_01h[CMIS_PAGES_ADVER_OFFSET] &
+ CMIS_BANKS_SUPPORTED_MASK) {
+ case CMIS_BANK_0_SUPPORTED:
+ *p_num_banks = 1;
+ break;
+ case CMIS_BANK_0_1_SUPPORTED:
+ *p_num_banks = 2;
+ break;
+ case CMIS_BANK_0_3_SUPPORTED:
+ *p_num_banks = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int
cmis_memory_map_init_pages(struct cmd_context *ctx,
struct cmis_memory_map *map)
{
struct ethtool_module_eeprom request;
- int ret;
+ int num_banks, i, ret;
/* Lower Memory and Page 00h are always present.
*
@@ -443,6 +472,22 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
return ret;
map->page_02h = request.data - CMIS_PAGE_SIZE;
+ /* Bank 0 of Page 11h provides lane-specific registers for the first 8
+ * lanes, and each additional Banks provides support for an additional
+ * 8 lanes. Only initialize supported Banks.
+ */
+ ret = cmis_num_banks_get(map, &num_banks);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < num_banks; i++) {
+ cmis_request_init(&request, i, 0x11, CMIS_PAGE_SIZE);
+ ret = nl_get_eeprom_page(ctx, &request);
+ if (ret < 0)
+ return ret;
+ map->upper_memory[i][0x11] = request.data - CMIS_PAGE_SIZE;
+ }
+
return 0;
}
diff --git a/cmis.h b/cmis.h
index 911491dc5c8f..8d90a04756ad 100644
--- a/cmis.h
+++ b/cmis.h
@@ -114,6 +114,13 @@
#define CMIS_WAVELENGTH_TOL_MSB 0x8C
#define CMIS_WAVELENGTH_TOL_LSB 0x8D
+/* Supported Pages Advertising (Page 1) */
+#define CMIS_PAGES_ADVER_OFFSET 0x8E
+#define CMIS_BANKS_SUPPORTED_MASK 0x03
+#define CMIS_BANK_0_SUPPORTED 0x00
+#define CMIS_BANK_0_1_SUPPORTED 0x01
+#define CMIS_BANK_0_3_SUPPORTED 0x02
+
/* Signal integrity controls */
#define CMIS_SIG_INTEG_TX_OFFSET 0xA1
#define CMIS_SIG_INTEG_RX_OFFSET 0xA2
--
2.35.1

View File

@ -1,631 +0,0 @@
From 086662c0b884c2b2e44ec472566d56c68a4330e0 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:40:59 +0200
Subject: [PATCH 31/35] cmis: Parse and print diagnostic information
Like SFF-8636, CMIS has module-level monitors such as temperature and
voltage and channel-level monitors such as Tx optical power.
These monitors have thresholds and flags that are set when the monitors
cross the thresholds.
Print and parse these values in a similar fashion to SFF-8636.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 466 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
cmis.h | 79 ++++++++++
2 files changed, 518 insertions(+), 27 deletions(-)
diff --git a/cmis.c b/cmis.c
index 83ced4d253ae..d7b7097139b3 100644
--- a/cmis.c
+++ b/cmis.c
@@ -19,6 +19,8 @@
* [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40
*/
#define CMIS_MAX_BANKS 4
+#define CMIS_CHANNELS_PER_BANK 8
+#define CMIS_MAX_CHANNEL_NUM (CMIS_MAX_BANKS * CMIS_CHANNELS_PER_BANK)
/* We are not parsing further than Page 11h. */
#define CMIS_MAX_PAGES 18
@@ -34,6 +36,80 @@ struct cmis_memory_map {
#define CMIS_PAGE_SIZE 0x80
#define CMIS_I2C_ADDRESS 0x50
+static struct {
+ const char *str;
+ int offset;
+ __u8 value; /* Alarm is on if (offset & value) != 0. */
+} cmis_aw_mod_flags[] = {
+ { "Module temperature high alarm",
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HALARM_STATUS },
+ { "Module temperature low alarm",
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LALARM_STATUS },
+ { "Module temperature high warning",
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HWARN_STATUS },
+ { "Module temperature low warning",
+ CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LWARN_STATUS },
+
+ { "Module voltage high alarm",
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_HALARM_STATUS },
+ { "Module voltage low alarm",
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_LALARM_STATUS },
+ { "Module voltage high warning",
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_HWARN_STATUS },
+ { "Module voltage low warning",
+ CMIS_VCC_AW_OFFSET, CMIS_VCC_LWARN_STATUS },
+
+ { NULL, 0, 0 },
+};
+
+static struct {
+ const char *fmt_str;
+ int offset;
+ int adver_offset; /* In Page 01h. */
+ __u8 adver_value; /* Supported if (offset & value) != 0. */
+} cmis_aw_chan_flags[] = {
+ { "Laser bias current high alarm (Chan %d)",
+ CMIS_TX_BIAS_AW_HALARM_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
+ { "Laser bias current low alarm (Chan %d)",
+ CMIS_TX_BIAS_AW_LALARM_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
+ { "Laser bias current high warning (Chan %d)",
+ CMIS_TX_BIAS_AW_HWARN_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
+ { "Laser bias current low warning (Chan %d)",
+ CMIS_TX_BIAS_AW_LWARN_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
+
+ { "Laser tx power high alarm (Channel %d)",
+ CMIS_TX_PWR_AW_HALARM_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
+ { "Laser tx power low alarm (Channel %d)",
+ CMIS_TX_PWR_AW_LALARM_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
+ { "Laser tx power high warning (Channel %d)",
+ CMIS_TX_PWR_AW_HWARN_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
+ { "Laser tx power low warning (Channel %d)",
+ CMIS_TX_PWR_AW_LWARN_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
+
+ { "Laser rx power high alarm (Channel %d)",
+ CMIS_RX_PWR_AW_HALARM_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
+ { "Laser rx power low alarm (Channel %d)",
+ CMIS_RX_PWR_AW_LALARM_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
+ { "Laser rx power high warning (Channel %d)",
+ CMIS_RX_PWR_AW_HWARN_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
+ { "Laser rx power low warning (Channel %d)",
+ CMIS_RX_PWR_AW_LWARN_OFFSET,
+ CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
+
+ { NULL, 0, 0, 0 },
+};
+
static void cmis_show_identifier(const struct cmis_memory_map *map)
{
sff8024_show_identifier(map->lower_memory, CMIS_ID_OFFSET);
@@ -277,32 +353,6 @@ static void cmis_show_mit_compliance(const struct cmis_memory_map *map)
}
}
-/*
- * 2-byte internal temperature conversions:
- * First byte is a signed 8-bit integer, which is the temp decimal part
- * Second byte is a multiple of 1/256th of a degree, which is added to
- * the dec part.
- */
-#define OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
-
-/**
- * Print relevant module level monitoring values. Relevant documents:
- * [1] CMIS Rev. 3:
- * --> pag. 50, section 1.7.2.4, Table 22
- *
- * [2] CMIS Rev. 4:
- * --> pag. 84, section 8.2.4, Table 8-6
- */
-static void cmis_show_mod_lvl_monitors(const struct cmis_memory_map *map)
-{
- const __u8 *id = map->lower_memory;
-
- PRINT_TEMP("Module temperature",
- OFFSET_TO_TEMP(CMIS_CURR_TEMP_OFFSET));
- PRINT_VCC("Module voltage",
- OFFSET_TO_U16(CMIS_CURR_VCC_OFFSET));
-}
-
/**
* Print relevant info about the maximum supported fiber media length
* for each type of fiber media at the maximum module-supported bit rate.
@@ -352,6 +402,368 @@ static void cmis_show_vendor_info(const struct cmis_memory_map *map)
CMIS_CLEI_END_OFFSET, "CLEI code");
}
+static void cmis_parse_dom_power_type(const struct cmis_memory_map *map,
+ struct sff_diags *sd)
+{
+ sd->rx_power_type = map->page_01h[CMIS_DIAG_TYPE_OFFSET] &
+ CMIS_RX_PWR_TYPE_MASK;
+ sd->tx_power_type = map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
+ CMIS_TX_PWR_MON_MASK;
+}
+
+static void cmis_parse_dom_mod_lvl_monitors(const struct cmis_memory_map *map,
+ struct sff_diags *sd)
+{
+ sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(map->lower_memory,
+ CMIS_CURR_VCC_OFFSET);
+ sd->sfp_temp[MCURR] = (__s16)OFFSET_TO_U16_PTR(map->lower_memory,
+ CMIS_CURR_TEMP_OFFSET);
+}
+
+static void cmis_parse_dom_mod_lvl_thresh(const struct cmis_memory_map *map,
+ struct sff_diags *sd)
+{
+ /* Page is not present in IOCTL path. */
+ if (!map->page_02h)
+ return;
+ sd->supports_alarms = 1;
+
+ sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_VCC_HALRM_OFFSET);
+ sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_VCC_LALRM_OFFSET);
+ sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_VCC_HWARN_OFFSET);
+ sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_VCC_LWARN_OFFSET);
+
+ sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TEMP_HALRM_OFFSET);
+ sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TEMP_LALRM_OFFSET);
+ sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TEMP_HWARN_OFFSET);
+ sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TEMP_LWARN_OFFSET);
+}
+
+static __u8 cmis_tx_bias_mul(const struct cmis_memory_map *map)
+{
+ switch (map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
+ CMIS_TX_BIAS_MUL_MASK) {
+ case CMIS_TX_BIAS_MUL_1:
+ return 0;
+ case CMIS_TX_BIAS_MUL_2:
+ return 1;
+ case CMIS_TX_BIAS_MUL_4:
+ return 2;
+ }
+
+ return 0;
+}
+
+static void
+cmis_parse_dom_chan_lvl_monitors_bank(const struct cmis_memory_map *map,
+ struct sff_diags *sd, int bank)
+{
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
+ int i;
+
+ if (!page_11h)
+ return;
+
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
+ __u8 tx_bias_offset, rx_power_offset, tx_power_offset;
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
+ __u8 bias_mul = cmis_tx_bias_mul(map);
+
+ tx_bias_offset = CMIS_TX_BIAS_OFFSET + i * sizeof(__u16);
+ rx_power_offset = CMIS_RX_PWR_OFFSET + i * sizeof(__u16);
+ tx_power_offset = CMIS_TX_PWR_OFFSET + i * sizeof(__u16);
+
+ sd->scd[chan].bias_cur = OFFSET_TO_U16_PTR(page_11h,
+ tx_bias_offset);
+ sd->scd[chan].bias_cur >>= bias_mul;
+ sd->scd[chan].rx_power = OFFSET_TO_U16_PTR(page_11h,
+ rx_power_offset);
+ sd->scd[chan].tx_power = OFFSET_TO_U16_PTR(page_11h,
+ tx_power_offset);
+ }
+}
+
+static void cmis_parse_dom_chan_lvl_monitors(const struct cmis_memory_map *map,
+ struct sff_diags *sd)
+{
+ int i;
+
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
+ cmis_parse_dom_chan_lvl_monitors_bank(map, sd, i);
+}
+
+static void cmis_parse_dom_chan_lvl_thresh(const struct cmis_memory_map *map,
+ struct sff_diags *sd)
+{
+ __u8 bias_mul = cmis_tx_bias_mul(map);
+
+ if (!map->page_02h)
+ return;
+
+ sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_BIAS_HALRM_OFFSET);
+ sd->bias_cur[HALRM] >>= bias_mul;
+ sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_BIAS_LALRM_OFFSET);
+ sd->bias_cur[LALRM] >>= bias_mul;
+ sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_BIAS_HWARN_OFFSET);
+ sd->bias_cur[HWARN] >>= bias_mul;
+ sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_BIAS_LWARN_OFFSET);
+ sd->bias_cur[LWARN] >>= bias_mul;
+
+ sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_PWR_HALRM_OFFSET);
+ sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_PWR_LALRM_OFFSET);
+ sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_PWR_HWARN_OFFSET);
+ sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_TX_PWR_LWARN_OFFSET);
+
+ sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_RX_PWR_HALRM_OFFSET);
+ sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_RX_PWR_LALRM_OFFSET);
+ sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_RX_PWR_HWARN_OFFSET);
+ sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
+ CMIS_RX_PWR_LWARN_OFFSET);
+}
+
+static void cmis_parse_dom(const struct cmis_memory_map *map,
+ struct sff_diags *sd)
+{
+ cmis_parse_dom_power_type(map, sd);
+ cmis_parse_dom_mod_lvl_monitors(map, sd);
+ cmis_parse_dom_mod_lvl_thresh(map, sd);
+ cmis_parse_dom_chan_lvl_monitors(map, sd);
+ cmis_parse_dom_chan_lvl_thresh(map, sd);
+}
+
+/* Print module-level monitoring values. Relevant documents:
+ * [1] CMIS Rev. 5, page 110, section 8.2.5, Table 8-9
+ */
+static void cmis_show_dom_mod_lvl_monitors(const struct sff_diags *sd)
+{
+ PRINT_TEMP("Module temperature", sd->sfp_temp[MCURR]);
+ PRINT_VCC("Module voltage", sd->sfp_voltage[MCURR]);
+}
+
+/* Print channel Tx laser bias current. Relevant documents:
+ * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
+ */
+static void
+cmis_show_dom_chan_lvl_tx_bias_bank(const struct cmis_memory_map *map,
+ const struct sff_diags *sd, int bank)
+{
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
+ int i;
+
+ if (!page_11h)
+ return;
+
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
+ char fmt_str[80];
+
+ snprintf(fmt_str, 80, "%s (Channel %d)",
+ "Laser tx bias current", chan + 1);
+ PRINT_BIAS(fmt_str, sd->scd[chan].bias_cur);
+ }
+}
+
+static void cmis_show_dom_chan_lvl_tx_bias(const struct cmis_memory_map *map,
+ const struct sff_diags *sd)
+{
+ int i;
+
+ if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
+ CMIS_TX_BIAS_MON_MASK))
+ return;
+
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
+ cmis_show_dom_chan_lvl_tx_bias_bank(map, sd, i);
+}
+
+/* Print channel Tx average optical power. Relevant documents:
+ * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
+ */
+static void
+cmis_show_dom_chan_lvl_tx_power_bank(const struct cmis_memory_map *map,
+ const struct sff_diags *sd, int bank)
+{
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
+ int i;
+
+ if (!page_11h)
+ return;
+
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
+ char fmt_str[80];
+
+ snprintf(fmt_str, 80, "%s (Channel %d)",
+ "Transmit avg optical power", chan + 1);
+ PRINT_xX_PWR(fmt_str, sd->scd[chan].tx_power);
+ }
+}
+
+static void cmis_show_dom_chan_lvl_tx_power(const struct cmis_memory_map *map,
+ const struct sff_diags *sd)
+{
+ int i;
+
+ if (!sd->tx_power_type)
+ return;
+
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
+ cmis_show_dom_chan_lvl_tx_power_bank(map, sd, i);
+}
+
+/* Print channel Rx input optical power. Relevant documents:
+ * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
+ */
+static void
+cmis_show_dom_chan_lvl_rx_power_bank(const struct cmis_memory_map *map,
+ const struct sff_diags *sd, int bank)
+{
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
+ int i;
+
+ if (!page_11h)
+ return;
+
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
+ char *rx_power_str;
+ char fmt_str[80];
+
+ if (!sd->rx_power_type)
+ rx_power_str = "Receiver signal OMA";
+ else
+ rx_power_str = "Rcvr signal avg optical power";
+
+ snprintf(fmt_str, 80, "%s (Channel %d)", rx_power_str,
+ chan + 1);
+ PRINT_xX_PWR(fmt_str, sd->scd[chan].rx_power);
+ }
+}
+
+static void cmis_show_dom_chan_lvl_rx_power(const struct cmis_memory_map *map,
+ const struct sff_diags *sd)
+{
+ int i;
+
+ if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] & CMIS_RX_PWR_MON_MASK))
+ return;
+
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
+ cmis_show_dom_chan_lvl_rx_power_bank(map, sd, i);
+}
+
+static void cmis_show_dom_chan_lvl_monitors(const struct cmis_memory_map *map,
+ const struct sff_diags *sd)
+{
+ cmis_show_dom_chan_lvl_tx_bias(map, sd);
+ cmis_show_dom_chan_lvl_tx_power(map, sd);
+ cmis_show_dom_chan_lvl_rx_power(map, sd);
+}
+
+/* Print module-level flags. Relevant documents:
+ * [1] CMIS Rev. 5, page 109, section 8.2.4, Table 8-8
+ */
+static void cmis_show_dom_mod_lvl_flags(const struct cmis_memory_map *map)
+{
+ int i;
+
+ for (i = 0; cmis_aw_mod_flags[i].str; i++) {
+ printf("\t%-41s : %s\n", cmis_aw_mod_flags[i].str,
+ map->lower_memory[cmis_aw_mod_flags[i].offset] &
+ cmis_aw_mod_flags[i].value ? "On" : "Off");
+ }
+}
+
+/* Print channel-level flags. Relevant documents:
+ * [1] CMIS Rev. 5, page 162, section 8.9.3, Table 8-77
+ * [1] CMIS Rev. 5, page 164, section 8.9.3, Table 8-78
+ */
+static void cmis_show_dom_chan_lvl_flags_chan(const struct cmis_memory_map *map,
+ int bank, int chan)
+{
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
+ int i;
+
+ for (i = 0; cmis_aw_chan_flags[i].fmt_str; i++) {
+ char str[80];
+
+ if (!(map->page_01h[cmis_aw_chan_flags[i].adver_offset] &
+ cmis_aw_chan_flags[i].adver_value))
+ continue;
+
+ snprintf(str, 80, cmis_aw_chan_flags[i].fmt_str, chan + 1);
+ printf("\t%-41s : %s\n", str,
+ page_11h[cmis_aw_chan_flags[i].offset] & chan ?
+ "On" : "Off");
+ }
+}
+
+static void
+cmis_show_dom_chan_lvl_flags_bank(const struct cmis_memory_map *map,
+ int bank)
+{
+ const __u8 *page_11h = map->upper_memory[bank][0x11];
+ int i;
+
+ if (!page_11h)
+ return;
+
+ for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
+ int chan = bank * CMIS_CHANNELS_PER_BANK + i;
+
+ cmis_show_dom_chan_lvl_flags_chan(map, bank, chan);
+ }
+}
+
+static void cmis_show_dom_chan_lvl_flags(const struct cmis_memory_map *map)
+{
+ int i;
+
+ for (i = 0; i < CMIS_MAX_BANKS; i++)
+ cmis_show_dom_chan_lvl_flags_bank(map, i);
+}
+
+
+static void cmis_show_dom(const struct cmis_memory_map *map)
+{
+ struct sff_diags sd = {};
+
+ /* Diagnostic information is only relevant when the module memory
+ * model is paged and not flat.
+ */
+ if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
+ CMIS_MEMORY_MODEL_MASK)
+ return;
+
+ cmis_parse_dom(map, &sd);
+
+ cmis_show_dom_mod_lvl_monitors(&sd);
+ cmis_show_dom_chan_lvl_monitors(map, &sd);
+ cmis_show_dom_mod_lvl_flags(map);
+ cmis_show_dom_chan_lvl_flags(map);
+ if (sd.supports_alarms)
+ sff_show_thresholds(sd);
+}
+
static void cmis_show_all_common(const struct cmis_memory_map *map)
{
cmis_show_identifier(map);
@@ -360,10 +772,10 @@ static void cmis_show_all_common(const struct cmis_memory_map *map)
cmis_show_cbl_asm_len(map);
cmis_show_sig_integrity(map);
cmis_show_mit_compliance(map);
- cmis_show_mod_lvl_monitors(map);
cmis_show_link_len(map);
cmis_show_vendor_info(map);
cmis_show_rev_compliance(map);
+ cmis_show_dom(map);
}
static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
diff --git a/cmis.h b/cmis.h
index 8d90a04756ad..310697b0ef32 100644
--- a/cmis.h
+++ b/cmis.h
@@ -7,6 +7,18 @@
#define CMIS_MEMORY_MODEL_OFFSET 0x02
#define CMIS_MEMORY_MODEL_MASK 0x80
+/* Module Flags (Page 0) */
+#define CMIS_VCC_AW_OFFSET 0x09
+#define CMIS_VCC_LWARN_STATUS 0x80
+#define CMIS_VCC_HWARN_STATUS 0x40
+#define CMIS_VCC_LALARM_STATUS 0x20
+#define CMIS_VCC_HALARM_STATUS 0x10
+#define CMIS_TEMP_AW_OFFSET 0x09
+#define CMIS_TEMP_LWARN_STATUS 0x08
+#define CMIS_TEMP_HWARN_STATUS 0x04
+#define CMIS_TEMP_LALARM_STATUS 0x02
+#define CMIS_TEMP_HALARM_STATUS 0x01
+
#define CMIS_MODULE_TYPE_OFFSET 0x55
#define CMIS_MT_MMF 0x01
#define CMIS_MT_SMF 0x02
@@ -121,10 +133,77 @@
#define CMIS_BANK_0_1_SUPPORTED 0x01
#define CMIS_BANK_0_3_SUPPORTED 0x02
+/* Module Characteristics Advertising (Page 1) */
+#define CMIS_DIAG_TYPE_OFFSET 0x97
+#define CMIS_RX_PWR_TYPE_MASK 0x10
+
+/* Supported Monitors Advertisement (Page 1) */
+#define CMIS_DIAG_CHAN_ADVER_OFFSET 0xA0
+#define CMIS_TX_BIAS_MON_MASK 0x01
+#define CMIS_TX_PWR_MON_MASK 0x02
+#define CMIS_RX_PWR_MON_MASK 0x04
+#define CMIS_TX_BIAS_MUL_MASK 0x18
+#define CMIS_TX_BIAS_MUL_1 0x00
+#define CMIS_TX_BIAS_MUL_2 0x08
+#define CMIS_TX_BIAS_MUL_4 0x10
+
/* Signal integrity controls */
#define CMIS_SIG_INTEG_TX_OFFSET 0xA1
#define CMIS_SIG_INTEG_RX_OFFSET 0xA2
+/*-----------------------------------------------------------------------
+ * Upper Memory Page 0x02: Optional Page that informs about module-defined
+ * thresholds for module-level and lane-specific threshold crossing monitors.
+ */
+
+/* Module-Level Monitor Thresholds (Page 2) */
+#define CMIS_TEMP_HALRM_OFFSET 0x80
+#define CMIS_TEMP_LALRM_OFFSET 0x82
+#define CMIS_TEMP_HWARN_OFFSET 0x84
+#define CMIS_TEMP_LWARN_OFFSET 0x86
+#define CMIS_VCC_HALRM_OFFSET 0x88
+#define CMIS_VCC_LALRM_OFFSET 0x8A
+#define CMIS_VCC_HWARN_OFFSET 0x8C
+#define CMIS_VCC_LWARN_OFFSET 0x8E
+
+/* Lane-Related Monitor Thresholds (Page 2) */
+#define CMIS_TX_PWR_HALRM_OFFSET 0xB0
+#define CMIS_TX_PWR_LALRM_OFFSET 0xB2
+#define CMIS_TX_PWR_HWARN_OFFSET 0xB4
+#define CMIS_TX_PWR_LWARN_OFFSET 0xB6
+#define CMIS_TX_BIAS_HALRM_OFFSET 0xB8
+#define CMIS_TX_BIAS_LALRM_OFFSET 0xBA
+#define CMIS_TX_BIAS_HWARN_OFFSET 0xBC
+#define CMIS_TX_BIAS_LWARN_OFFSET 0xBE
+#define CMIS_RX_PWR_HALRM_OFFSET 0xC0
+#define CMIS_RX_PWR_LALRM_OFFSET 0xC2
+#define CMIS_RX_PWR_HWARN_OFFSET 0xC4
+#define CMIS_RX_PWR_LWARN_OFFSET 0xC6
+
+/*-----------------------------------------------------------------------
+ * Upper Memory Page 0x11: Optional Page that contains lane dynamic status
+ * bytes.
+ */
+
+/* Media Lane-Specific Flags (Page 0x11) */
+#define CMIS_TX_PWR_AW_HALARM_OFFSET 0x8B
+#define CMIS_TX_PWR_AW_LALARM_OFFSET 0x8C
+#define CMIS_TX_PWR_AW_HWARN_OFFSET 0x8D
+#define CMIS_TX_PWR_AW_LWARN_OFFSET 0x8E
+#define CMIS_TX_BIAS_AW_HALARM_OFFSET 0x8F
+#define CMIS_TX_BIAS_AW_LALARM_OFFSET 0x90
+#define CMIS_TX_BIAS_AW_HWARN_OFFSET 0x91
+#define CMIS_TX_BIAS_AW_LWARN_OFFSET 0x92
+#define CMIS_RX_PWR_AW_HALARM_OFFSET 0x95
+#define CMIS_RX_PWR_AW_LALARM_OFFSET 0x96
+#define CMIS_RX_PWR_AW_HWARN_OFFSET 0x97
+#define CMIS_RX_PWR_AW_LWARN_OFFSET 0x98
+
+/* Media Lane-Specific Monitors (Page 0x11) */
+#define CMIS_TX_PWR_OFFSET 0x9A
+#define CMIS_TX_BIAS_OFFSET 0xAA
+#define CMIS_RX_PWR_OFFSET 0xBA
+
#define YESNO(x) (((x) != 0) ? "Yes" : "No")
#define ONOFF(x) (((x) != 0) ? "On" : "Off")
--
2.35.1

View File

@ -1,155 +0,0 @@
From 4a86034f138e1a96e54047b8036b0a4425e99944 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:41:00 +0200
Subject: [PATCH 32/35] cmis: Print Module State and Fault Cause
Print the CMIS Module State when dumping EEPROM contents via the '-m'
option. It can be used, for example, to test module power mode settings.
Example output:
# ethtool -m swp11
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
...
Module State : 0x03 (ModuleReady)
# ethtool --set-module swp11 power-mode-policy auto
# ethtool -m swp11
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
...
Module State : 0x01 (ModuleLowPwr)
In case the module is in fault state, print the CMIS Module Fault Cause.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmis.h | 16 ++++++++++++++
2 files changed, 86 insertions(+)
diff --git a/cmis.c b/cmis.c
index d7b7097139b3..a32cc9f8b1f6 100644
--- a/cmis.c
+++ b/cmis.c
@@ -402,6 +402,74 @@ static void cmis_show_vendor_info(const struct cmis_memory_map *map)
CMIS_CLEI_END_OFFSET, "CLEI code");
}
+/* Print the current Module State. Relevant documents:
+ * [1] CMIS Rev. 5, pag. 57, section 6.3.2.2, Figure 6-3
+ * [2] CMIS Rev. 5, pag. 60, section 6.3.2.3, Figure 6-4
+ * [3] CMIS Rev. 5, pag. 107, section 8.2.2, Table 8-6
+ */
+static void cmis_show_mod_state(const struct cmis_memory_map *map)
+{
+ __u8 mod_state;
+
+ mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] &
+ CMIS_MODULE_STATE_MASK) >> 1;
+ printf("\t%-41s : 0x%02x", "Module State", mod_state);
+ switch (mod_state) {
+ case CMIS_MODULE_STATE_MODULE_LOW_PWR:
+ printf(" (ModuleLowPwr)\n");
+ break;
+ case CMIS_MODULE_STATE_MODULE_PWR_UP:
+ printf(" (ModulePwrUp)\n");
+ break;
+ case CMIS_MODULE_STATE_MODULE_READY:
+ printf(" (ModuleReady)\n");
+ break;
+ case CMIS_MODULE_STATE_MODULE_PWR_DN:
+ printf(" (ModulePwrDn)\n");
+ break;
+ case CMIS_MODULE_STATE_MODULE_FAULT:
+ printf(" (ModuleFault)\n");
+ break;
+ default:
+ printf(" (reserved or unknown)\n");
+ break;
+ }
+}
+
+/* Print the Module Fault Information. Relevant documents:
+ * [1] CMIS Rev. 5, pag. 64, section 6.3.2.12
+ * [2] CMIS Rev. 5, pag. 115, section 8.2.10, Table 8-15
+ */
+static void cmis_show_mod_fault_cause(const struct cmis_memory_map *map)
+{
+ __u8 mod_state, fault_cause;
+
+ mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] &
+ CMIS_MODULE_STATE_MASK) >> 1;
+ if (mod_state != CMIS_MODULE_STATE_MODULE_FAULT)
+ return;
+
+ fault_cause = map->lower_memory[CMIS_MODULE_FAULT_OFFSET];
+ printf("\t%-41s : 0x%02x", "Module Fault Cause", fault_cause);
+ switch (fault_cause) {
+ case CMIS_MODULE_FAULT_NO_FAULT:
+ printf(" (No fault detected / not supported)\n");
+ break;
+ case CMIS_MODULE_FAULT_TEC_RUNAWAY:
+ printf(" (TEC runaway)\n");
+ break;
+ case CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED:
+ printf(" (Data memory corrupted)\n");
+ break;
+ case CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED:
+ printf(" (Program memory corrupted)\n");
+ break;
+ default:
+ printf(" (reserved or unknown)\n");
+ break;
+ }
+}
+
static void cmis_parse_dom_power_type(const struct cmis_memory_map *map,
struct sff_diags *sd)
{
@@ -775,6 +843,8 @@ static void cmis_show_all_common(const struct cmis_memory_map *map)
cmis_show_link_len(map);
cmis_show_vendor_info(map);
cmis_show_rev_compliance(map);
+ cmis_show_mod_state(map);
+ cmis_show_mod_fault_cause(map);
cmis_show_dom(map);
}
diff --git a/cmis.h b/cmis.h
index 310697b0ef32..2c67ad5640ab 100644
--- a/cmis.h
+++ b/cmis.h
@@ -7,6 +7,15 @@
#define CMIS_MEMORY_MODEL_OFFSET 0x02
#define CMIS_MEMORY_MODEL_MASK 0x80
+/* Global Status Information (Page 0) */
+#define CMIS_MODULE_STATE_OFFSET 0x03
+#define CMIS_MODULE_STATE_MASK 0x0E
+#define CMIS_MODULE_STATE_MODULE_LOW_PWR 0x01
+#define CMIS_MODULE_STATE_MODULE_PWR_UP 0x02
+#define CMIS_MODULE_STATE_MODULE_READY 0x03
+#define CMIS_MODULE_STATE_MODULE_PWR_DN 0x04
+#define CMIS_MODULE_STATE_MODULE_FAULT 0x05
+
/* Module Flags (Page 0) */
#define CMIS_VCC_AW_OFFSET 0x09
#define CMIS_VCC_LWARN_STATUS 0x80
@@ -27,6 +36,13 @@
#define CMIS_CURR_TEMP_OFFSET 0x0E
#define CMIS_CURR_VCC_OFFSET 0x10
+/* Module Fault Information (Page 0) */
+#define CMIS_MODULE_FAULT_OFFSET 0x29
+#define CMIS_MODULE_FAULT_NO_FAULT 0x00
+#define CMIS_MODULE_FAULT_TEC_RUNAWAY 0x01
+#define CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED 0x02
+#define CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED 0x03
+
#define CMIS_CTOR_OFFSET 0xCB
/* Vendor related information (Page 0) */
--
2.35.1

View File

@ -1,196 +0,0 @@
From 0b45f392c6c92e9823d6332622d7a45e7a36365e Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:41:01 +0200
Subject: [PATCH 33/35] cmis: Print Module-Level Controls
Print the CMIS Module-Level Controls when dumping EEPROM contents via
the '-m' option. It can be used to understand low power mode enforcement
by the host.
Example output:
# ethtool -m swp11
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
...
Module State : 0x03 (ModuleReady)
LowPwrAllowRequestHW : Off
LowPwrRequestSW : Off
...
Transmit avg optical power (Channel 1) : 1.3222 mW / 1.21 dBm
Transmit avg optical power (Channel 2) : 1.2666 mW / 1.03 dBm
Transmit avg optical power (Channel 3) : 1.2860 mW / 1.09 dBm
Transmit avg optical power (Channel 4) : 1.2988 mW / 1.14 dBm
Transmit avg optical power (Channel 5) : 1.2828 mW / 1.08 dBm
Transmit avg optical power (Channel 6) : 1.2913 mW / 1.11 dBm
Transmit avg optical power (Channel 7) : 1.2636 mW / 1.02 dBm
Transmit avg optical power (Channel 8) : 1.3408 mW / 1.27 dBm
Transmit avg optical power (Channel 9) : 1.3222 mW / 1.21 dBm
Transmit avg optical power (Channel 10) : 1.2666 mW / 1.03 dBm
Transmit avg optical power (Channel 11) : 1.2860 mW / 1.09 dBm
Transmit avg optical power (Channel 12) : 1.2988 mW / 1.14 dBm
Transmit avg optical power (Channel 13) : 1.2828 mW / 1.08 dBm
Transmit avg optical power (Channel 14) : 1.2913 mW / 1.11 dBm
Transmit avg optical power (Channel 15) : 1.2636 mW / 1.02 dBm
Transmit avg optical power (Channel 16) : 1.3408 mW / 1.27 dBm
Rcvr signal avg optical power (Channel 1) : 1.1351 mW / 0.55 dBm
Rcvr signal avg optical power (Channel 2) : 1.1603 mW / 0.65 dBm
Rcvr signal avg optical power (Channel 3) : 1.1529 mW / 0.62 dBm
Rcvr signal avg optical power (Channel 4) : 1.1670 mW / 0.67 dBm
Rcvr signal avg optical power (Channel 5) : 1.1759 mW / 0.70 dBm
Rcvr signal avg optical power (Channel 6) : 1.1744 mW / 0.70 dBm
Rcvr signal avg optical power (Channel 7) : 1.1188 mW / 0.49 dBm
Rcvr signal avg optical power (Channel 8) : 1.1640 mW / 0.66 dBm
Rcvr signal avg optical power (Channel 9) : 1.1351 mW / 0.55 dBm
Rcvr signal avg optical power (Channel 10) : 1.1603 mW / 0.65 dBm
Rcvr signal avg optical power (Channel 11) : 1.1529 mW / 0.62 dBm
Rcvr signal avg optical power (Channel 12) : 1.1670 mW / 0.67 dBm
Rcvr signal avg optical power (Channel 13) : 1.1759 mW / 0.70 dBm
Rcvr signal avg optical power (Channel 14) : 1.1744 mW / 0.70 dBm
Rcvr signal avg optical power (Channel 15) : 1.1188 mW / 0.49 dBm
Rcvr signal avg optical power (Channel 16) : 1.1640 mW / 0.66 dBm
# ethtool --set-module swp11 power-mode-policy auto
# ethtool -m swp11
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
...
Module State : 0x01 (ModuleLowPwr)
LowPwrAllowRequestHW : Off
LowPwrRequestSW : On
...
Transmit avg optical power (Channel 1) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 2) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 3) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 4) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 5) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 6) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 7) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 8) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 9) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 10) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 11) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 12) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 13) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 14) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 15) : 0.0001 mW / -40.00 dBm
Transmit avg optical power (Channel 16) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 1) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 2) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 3) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 4) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 5) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 6) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 7) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 8) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 9) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 10) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 11) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 12) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 13) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 14) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 15) : 0.0001 mW / -40.00 dBm
Rcvr signal avg optical power (Channel 16) : 0.0001 mW / -40.00 dBm
# ethtool --set-module swp11 power-mode-policy high
# ethtool -m swp11
Identifier : 0x18 (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))
...
Module State : 0x03 (ModuleReady)
LowPwrAllowRequestHW : Off
LowPwrRequestSW : Off
...
Transmit avg optical power (Channel 1) : 1.3690 mW / 1.36 dBm
Transmit avg optical power (Channel 2) : 1.3036 mW / 1.15 dBm
Transmit avg optical power (Channel 3) : 1.3358 mW / 1.26 dBm
Transmit avg optical power (Channel 4) : 1.3509 mW / 1.31 dBm
Transmit avg optical power (Channel 5) : 1.3193 mW / 1.20 dBm
Transmit avg optical power (Channel 6) : 1.3314 mW / 1.24 dBm
Transmit avg optical power (Channel 7) : 1.3042 mW / 1.15 dBm
Transmit avg optical power (Channel 8) : 1.3919 mW / 1.44 dBm
Transmit avg optical power (Channel 9) : 1.3690 mW / 1.36 dBm
Transmit avg optical power (Channel 10) : 1.3036 mW / 1.15 dBm
Transmit avg optical power (Channel 11) : 1.3358 mW / 1.26 dBm
Transmit avg optical power (Channel 12) : 1.3509 mW / 1.31 dBm
Transmit avg optical power (Channel 13) : 1.3193 mW / 1.20 dBm
Transmit avg optical power (Channel 14) : 1.3314 mW / 1.24 dBm
Transmit avg optical power (Channel 15) : 1.3042 mW / 1.15 dBm
Transmit avg optical power (Channel 16) : 1.3919 mW / 1.44 dBm
Rcvr signal avg optical power (Channel 1) : 1.1299 mW / 0.53 dBm
Rcvr signal avg optical power (Channel 2) : 1.1566 mW / 0.63 dBm
Rcvr signal avg optical power (Channel 3) : 1.1484 mW / 0.60 dBm
Rcvr signal avg optical power (Channel 4) : 1.1655 mW / 0.67 dBm
Rcvr signal avg optical power (Channel 5) : 1.1751 mW / 0.70 dBm
Rcvr signal avg optical power (Channel 6) : 1.1595 mW / 0.64 dBm
Rcvr signal avg optical power (Channel 7) : 1.1158 mW / 0.48 dBm
Rcvr signal avg optical power (Channel 8) : 1.1595 mW / 0.64 dBm
Rcvr signal avg optical power (Channel 9) : 1.1299 mW / 0.53 dBm
Rcvr signal avg optical power (Channel 10) : 1.1566 mW / 0.63 dBm
Rcvr signal avg optical power (Channel 11) : 1.1484 mW / 0.60 dBm
Rcvr signal avg optical power (Channel 12) : 1.1655 mW / 0.67 dBm
Rcvr signal avg optical power (Channel 13) : 1.1751 mW / 0.70 dBm
Rcvr signal avg optical power (Channel 14) : 1.1595 mW / 0.64 dBm
Rcvr signal avg optical power (Channel 15) : 1.1158 mW / 0.48 dBm
Rcvr signal avg optical power (Channel 16) : 1.1595 mW / 0.64 dBm
In the above example, the LowPwrRequestHW signal is ignored and low
power mode is controlled via software only.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
cmis.c | 15 +++++++++++++++
cmis.h | 5 +++++
2 files changed, 20 insertions(+)
diff --git a/cmis.c b/cmis.c
index a32cc9f8b1f6..d0b62728e998 100644
--- a/cmis.c
+++ b/cmis.c
@@ -470,6 +470,20 @@ static void cmis_show_mod_fault_cause(const struct cmis_memory_map *map)
}
}
+/* Print the current Module-Level Controls. Relevant documents:
+ * [1] CMIS Rev. 5, pag. 58, section 6.3.2.2, Table 6-12
+ * [2] CMIS Rev. 5, pag. 111, section 8.2.6, Table 8-10
+ */
+static void cmis_show_mod_lvl_controls(const struct cmis_memory_map *map)
+{
+ printf("\t%-41s : ", "LowPwrAllowRequestHW");
+ printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] &
+ CMIS_LOW_PWR_ALLOW_REQUEST_HW_MASK));
+ printf("\t%-41s : ", "LowPwrRequestSW");
+ printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] &
+ CMIS_LOW_PWR_REQUEST_SW_MASK));
+}
+
static void cmis_parse_dom_power_type(const struct cmis_memory_map *map,
struct sff_diags *sd)
{
@@ -845,6 +859,7 @@ static void cmis_show_all_common(const struct cmis_memory_map *map)
cmis_show_rev_compliance(map);
cmis_show_mod_state(map);
cmis_show_mod_fault_cause(map);
+ cmis_show_mod_lvl_controls(map);
cmis_show_dom(map);
}
diff --git a/cmis.h b/cmis.h
index 2c67ad5640ab..46797081f13c 100644
--- a/cmis.h
+++ b/cmis.h
@@ -36,6 +36,11 @@
#define CMIS_CURR_TEMP_OFFSET 0x0E
#define CMIS_CURR_VCC_OFFSET 0x10
+/* Module Global Controls (Page 0) */
+#define CMIS_MODULE_CONTROL_OFFSET 0x1A
+#define CMIS_LOW_PWR_ALLOW_REQUEST_HW_MASK 0x40
+#define CMIS_LOW_PWR_REQUEST_SW_MASK 0x10
+
/* Module Fault Information (Page 0) */
#define CMIS_MODULE_FAULT_OFFSET 0x29
#define CMIS_MODULE_FAULT_NO_FAULT 0x00
--
2.35.1

View File

@ -1,108 +0,0 @@
From 48391fa16592b47d37ef63466111c751a10c3e56 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Tue, 23 Nov 2021 19:41:02 +0200
Subject: [PATCH 34/35] sff-8636: Print Power set and Power override bits
Print the SFF-8636 Power set and Power override bits when dumping EEPROM
contents via the '-m' option. They can be used to understand low power
mode enforcement by the host.
The 'SFF8636_LOW_PWR_MODE' define is renamed to 'SFF8636_LOW_PWR_SET' to
reflect its naming in the standard for QSFP+/QSFP28.
Example output:
# ethtool -m swp13
Identifier : 0x11 (QSFP28)
...
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) enabled
Power set : Off
Power override : On
...
Transmit avg optical power (Channel 1) : 0.7633 mW / -1.17 dBm
Transmit avg optical power (Channel 2) : 0.7649 mW / -1.16 dBm
Transmit avg optical power (Channel 3) : 0.7696 mW / -1.14 dBm
Transmit avg optical power (Channel 4) : 0.7739 mW / -1.11 dBm
Rcvr signal avg optical power(Channel 1) : 0.9240 mW / -0.34 dBm
Rcvr signal avg optical power(Channel 2) : 0.9129 mW / -0.40 dBm
Rcvr signal avg optical power(Channel 3) : 0.9194 mW / -0.36 dBm
Rcvr signal avg optical power(Channel 4) : 0.8708 mW / -0.60 dBm
# ethtool --set-module swp13 power-mode-policy auto
# ethtool -m swp13
Identifier : 0x11 (QSFP28)
...
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) not enabled
Power set : On
Power override : On
...
Transmit avg optical power (Channel 1) : 0.0000 mW / -inf dBm
Transmit avg optical power (Channel 2) : 0.0000 mW / -inf dBm
Transmit avg optical power (Channel 3) : 0.0000 mW / -inf dBm
Transmit avg optical power (Channel 4) : 0.0000 mW / -inf dBm
Rcvr signal avg optical power(Channel 1) : 0.0000 mW / -inf dBm
Rcvr signal avg optical power(Channel 2) : 0.0000 mW / -inf dBm
Rcvr signal avg optical power(Channel 3) : 0.0000 mW / -inf dBm
Rcvr signal avg optical power(Channel 4) : 0.0000 mW / -inf dBm
# ethtool --set-module swp13 power-mode-policy high
# ethtool -m swp13
Identifier : 0x11 (QSFP28)
...
Extended identifier description : 5.0W max. Power consumption, High Power Class (> 3.5 W) enabled
Power set : Off
Power override : On
...
Transmit avg optical power (Channel 1) : 0.7733 mW / -1.12 dBm
Transmit avg optical power (Channel 2) : 0.7754 mW / -1.10 dBm
Transmit avg optical power (Channel 3) : 0.7885 mW / -1.03 dBm
Transmit avg optical power (Channel 4) : 0.7886 mW / -1.03 dBm
Rcvr signal avg optical power(Channel 1) : 0.9248 mW / -0.34 dBm
Rcvr signal avg optical power(Channel 2) : 0.9129 mW / -0.40 dBm
Rcvr signal avg optical power(Channel 3) : 0.9187 mW / -0.37 dBm
Rcvr signal avg optical power(Channel 4) : 0.8785 mW / -0.56 dBm
In the above example, the LPMode signal is ignored (Power override is
always on) and low power mode is controlled via software only.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
qsfp.c | 6 ++++++
qsfp.h | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/qsfp.c b/qsfp.c
index b3c9e1516af9..57aac86bd5f6 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -268,6 +268,12 @@ static void sff8636_show_ext_identifier(const struct sff8636_memory_map *map)
printf(" High Power Class (> 3.5 W) enabled\n");
else
printf(" High Power Class (> 3.5 W) not enabled\n");
+ printf("\t%-41s : ", "Power set");
+ printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
+ SFF8636_LOW_PWR_SET));
+ printf("\t%-41s : ", "Power override");
+ printf("%s\n", ONOFF(map->lower_memory[SFF8636_PWR_MODE_OFFSET] &
+ SFF8636_PWR_OVERRIDE));
}
static void sff8636_show_connector(const struct sff8636_memory_map *map)
diff --git a/qsfp.h b/qsfp.h
index 1d8f24b5cbc2..aabf09fdc623 100644
--- a/qsfp.h
+++ b/qsfp.h
@@ -180,7 +180,7 @@
#define SFF8636_PWR_MODE_OFFSET 0x5D
#define SFF8636_HIGH_PWR_ENABLE (1 << 2)
-#define SFF8636_LOW_PWR_MODE (1 << 1)
+#define SFF8636_LOW_PWR_SET (1 << 1)
#define SFF8636_PWR_OVERRIDE (1 << 0)
#define SFF8636_TX_APP_SELECT_4_OFFSET 0x5E
--
2.35.1

View File

@ -1,107 +0,0 @@
From 206cd00caf9b71ae20f897075b4bd261e923e563 Mon Sep 17 00:00:00 2001
From: Ivan Vecera <ivecera@redhat.com>
Date: Tue, 31 May 2022 20:55:03 +0200
Subject: [PATCH 35/35] sff-8079/8472: Fix missing sff-8472 output in netlink
path
Commit 25b64c66f58d ("ethtool: Add netlink handler for
getmodule (-m)") provided a netlink variant for getmodule
but also introduced a regression as netlink output is different
from ioctl output that provides information from A2h page
via sff8472_show_all().
To fix this the netlink path should check a presence of A2h page
by value of bit 6 in byte 92 of page A0h and if it is set then
get A2h page and call sff8472_show_all().
Fixes: 25b64c66f58d ("ethtool: Add netlink handler for getmodule (-m)")
Tested-by: Daniel Juarez <djuarezg@cern.ch>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Co-authored-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
sfpid.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 46 insertions(+), 8 deletions(-)
diff --git a/sfpid.c b/sfpid.c
index 621d1e86c278..1bc45c183770 100644
--- a/sfpid.c
+++ b/sfpid.c
@@ -13,8 +13,9 @@
#include "sff-common.h"
#include "netlink/extapi.h"
-#define SFF8079_PAGE_SIZE 0x80
-#define SFF8079_I2C_ADDRESS_LOW 0x50
+#define SFF8079_PAGE_SIZE 0x80
+#define SFF8079_I2C_ADDRESS_LOW 0x50
+#define SFF8079_I2C_ADDRESS_HIGH 0x51
static void sff8079_show_identifier(const __u8 *id)
{
@@ -450,18 +451,55 @@ void sff8079_show_all_ioctl(const __u8 *id)
sff8079_show_all_common(id);
}
-int sff8079_show_all_nl(struct cmd_context *ctx)
+static int sff8079_get_eeprom_page(struct cmd_context *ctx, u8 i2c_address,
+ __u8 *buf)
{
struct ethtool_module_eeprom request = {
.length = SFF8079_PAGE_SIZE,
- .i2c_address = SFF8079_I2C_ADDRESS_LOW,
+ .i2c_address = i2c_address,
};
int ret;
ret = nl_get_eeprom_page(ctx, &request);
- if (ret < 0)
- return ret;
- sff8079_show_all_common(request.data);
+ if (!ret)
+ memcpy(buf, request.data, SFF8079_PAGE_SIZE);
+
+ return ret;
+}
+
+int sff8079_show_all_nl(struct cmd_context *ctx)
+{
+ u8 *buf;
+ int ret;
+
+ /* The SFF-8472 parser expects a single buffer that contains the
+ * concatenation of the first 256 bytes from addresses A0h and A2h,
+ * respectively.
+ */
+ buf = calloc(1, ETH_MODULE_SFF_8472_LEN);
+ if (!buf)
+ return -ENOMEM;
+
+ /* Read A0h page */
+ ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_LOW, buf);
+ if (ret)
+ goto out;
+
+ sff8079_show_all_common(buf);
+
+ /* Finish if A2h page is not present */
+ if (!(buf[92] & (1 << 6)))
+ goto out;
+
+ /* Read A2h page */
+ ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_HIGH,
+ buf + ETH_MODULE_SFF_8079_LEN);
+ if (ret)
+ goto out;
+
+ sff8472_show_all(buf);
+out:
+ free(buf);
- return 0;
+ return ret;
}
--
2.35.1

View File

@ -1,50 +1,19 @@
Name: ethtool
Epoch: 2
Version: 5.13
Release: 2%{?dist}
Summary: Settings tool for Ethernet NICs
License: GPLv2
Group: Applications/System
URL: https://www.kernel.org/pub/software/network/%{name}/
Source0: https://www.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.xz
BuildRequires: libmnl-devel
Conflicts: filesystem < 3
Patch1: 0001-sff-8636-Fix-parsing-of-Page-03h-in-IOCTL-path.patch
Patch2: 0002-cmis-Fix-invalid-memory-access-in-IOCTL-path.patch
Patch3: 0003-netlink-eeprom-Fallback-to-IOCTL-when-a-complete-hex.patch
Patch4: 0004-ethtool-Fix-compilation-warning-when-pretty-dump-is-.patch
Patch5: 0005-netlink-eeprom-Fix-compilation-when-pretty-dump-is-d.patch
Patch6: 0006-cmis-Fix-CLEI-code-parsing.patch
Patch7: 0007-cmis-Fix-wrong-define-name.patch
Patch8: 0008-cmis-Correct-comment.patch
Patch9: 0009-sff-8636-Remove-incorrect-comment.patch
Patch10: 0010-sff-8636-Fix-incorrect-function-name.patch
Patch11: 0011-sff-8636-Convert-if-statement-to-switch-case.patch
Patch12: 0012-sff-8636-Remove-extra-blank-lines.patch
Patch13: 0013-cmis-Rename-CMIS-parsing-functions.patch
Patch14: 0014-cmis-Initialize-CMIS-memory-map.patch
Patch15: 0015-cmis-Use-memory-map-during-parsing.patch
Patch16: 0016-cmis-Consolidate-code-between-IOCTL-and-netlink-path.patch
Patch17: 0017-sff-8636-Rename-SFF-8636-parsing-functions.patch
Patch18: 0018-sff-8636-Initialize-SFF-8636-memory-map.patch
Patch19: 0019-sff-8636-Use-memory-map-during-parsing.patch
Patch20: 0020-sff-8636-Consolidate-code-between-IOCTL-and-netlink-.patch
Patch21: 0021-sff-8079-Split-SFF-8079-parsing-function.patch
Patch22: 0022-netlink-eeprom-Export-a-function-to-request-an-EEPRO.patch
Patch23: 0023-cmis-Request-specific-pages-for-parsing-in-netlink-p.patch
Patch24: 0024-sff-8636-Request-specific-pages-for-parsing-in-netli.patch
Patch25: 0025-sff-8079-Request-specific-pages-for-parsing-in-netli.patch
Patch26: 0026-netlink-eeprom-Defer-page-requests-to-individual-par.patch
Patch27: 0027-sff-8636-Use-an-SFF-8636-specific-define-for-maximum.patch
Patch28: 0028-sff-common-Move-OFFSET_TO_U16_PTR-to-common-header-f.patch
Patch29: 0029-cmis-Initialize-Page-02h-in-memory-map.patch
Patch30: 0030-cmis-Initialize-Banked-Page-11h-in-memory-map.patch
Patch31: 0031-cmis-Parse-and-print-diagnostic-information.patch
Patch32: 0032-cmis-Print-Module-State-and-Fault-Cause.patch
Patch33: 0033-cmis-Print-Module-Level-Controls.patch
Patch34: 0034-sff-8636-Print-Power-set-and-Power-override-bits.patch
Patch35: 0035-sff-8079-8472-Fix-missing-sff-8472-output-in-netlink.patch
Summary: Settings tool for Ethernet NICs
Name: ethtool
Epoch: 2
Version: 6.11
Release: 4%{?dist}
# {json_print,qsfp,sff-common}.{c,h} are GPL-2.0-or-later, rest is GPL-2.0-only
License: GPL-2.0-only AND GPL-2.0-or-later
URL: https://www.kernel.org/pub/software/network/%{name}/
Source0: https://www.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.xz
Source1: https://www.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.sign
Source2: https://keys.openpgp.org/vks/v1/by-fingerprint/D2CB120AB45957B721CD9596F4554567B91DE934
BuildRequires: gnupg2, xz
BuildRequires: gcc
BuildRequires: libmnl-devel
BuildRequires: make
Conflicts: filesystem < 3
%description
This utility allows querying and changing settings such as speed,
@ -52,90 +21,167 @@ port, auto-negotiation, PCI locations and checksum offload on many
network devices, especially of Ethernet devices.
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
xzcat '%{SOURCE0}' | %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data=-
%autosetup
%build
%configure
make %{?_smp_mflags}
%make_build
%install
make DESTDIR=%{buildroot} INSTALL='install -p' install
%make_install
%check
make check
%files
%license COPYING LICENSE
%doc AUTHORS ChangeLog* NEWS README
%{_sbindir}/%{name}
%dir %{_datadir}/bash-completion/
%dir %{_datadir}/bash-completion/completions/
%{_datadir}/bash-completion/completions/%{name}
%{_mandir}/man8/%{name}.8*
%{_datadir}/bash-completion/completions/ethtool
%changelog
* Thu Jun 02 2022 Ivan Vecera <ivecera@redhat.com> - 2:5.13-2
- Module (SFP/QSFP/CMIS) related bugfixes
* Mon Dec 9 2024 Ivan Vecera <ivecera@redhat.com> - 2:6.11-4
- Fixed gating
* Thu Nov 18 2021 Ivan Vecera <ivecera@redhat.com> - 2:5.13-1
- Updated to upstream v5.13
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 2:6.11-3
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018
* Thu Jun 03 2021 Ivan Vecera <ivecera@redhat.com> - 2:5.8-7
- Added support for lanes
* Wed Oct 9 2024 Ivan Vecera <ivecera@redhat.com> - 2:6.11-2
- Fixed gating (RHEL-56323)
* Thu Mar 11 2021 Ivan Vecera <ivecera@redhat.com> - 2:5.8-6
- Added support for pause frame statistics
* Wed Oct 9 2024 Ivan Vecera <ivecera@redhat.com> - 2:6.11-1
- Upgrade to 6.11 (RHEL-56323)
* Thu Nov 12 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-5
- Fixed a regression
* Wed Sep 25 2024 Ivan Vecera <ivecera@redhat.com> - 2:6.10-1
- Upgrade to 6.10 (RHEL-56323)
* Fri Nov 06 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-4
- Added support for extended link state reporting
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 2:6.7-2
- Bump release for June 2024 mass rebuild
* Fri Sep 25 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-3
- Fixed memory leak
* Mon Jan 29 2024 Robert Scheck <robert@fedoraproject.org> - 2:6.7-1
- Upgrade to 6.7 (#2260796)
* Thu Sep 24 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-2
- Add post-5.8 bugfixes
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2:6.6-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Tue Sep 15 2020 Ivan Vecera <ivecera@redhat.com> - 2:5.8-1
- Update to 5.8 (#1878826)
* Fri Jan 19 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2:6.6-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu May 16 2019 Ivan Vecera <ivecera@redhat.com> - 2:5.0-2
- Added support for 200Gbps (50Gbps/lane) link mode
* Sat Nov 25 2023 Robert Scheck <robert@fedoraproject.org> - 2:6.6-1
- Upgrade to 6.6 (#2251292)
* Wed Mar 13 2019 Ivan Vecera <ivecera@redhat.com> - 2:5.0-1
- Update to 5.0 (#1688299)
* Wed Sep 13 2023 Robert Scheck <robert@fedoraproject.org> - 2:6.5-1
- Upgrade to 6.5 (#2238637)
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 2:6.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Sun Jul 02 2023 Robert Scheck <robert@fedoraproject.org> - 2:6.4-1
- Upgrade to 6.4 (#2219094)
* Mon May 15 2023 Robert Scheck <robert@fedoraproject.org> - 2:6.3-1
- Upgrade to 6.3 (#2203915)
* Wed Feb 22 2023 Robert Scheck <robert@fedoraproject.org> - 2:6.2-1
- Upgrade to 6.2 (#2172201)
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 2:6.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Tue Dec 20 2022 Robert Scheck <robert@fedoraproject.org> - 2:6.1-1
- Upgrade to 6.1 (#2155096)
* Tue Oct 11 2022 Robert Scheck <robert@fedoraproject.org> - 2:6.0-1
- Upgrade to 6.0 (#2133539)
* Tue Aug 23 2022 Robert Scheck <robert@fedoraproject.org> - 2:5.19-1
- Upgrade to 5.19 (#2120144)
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 2:5.18-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Sat Jun 25 2022 Robert Scheck <robert@fedoraproject.org> - 2:5.18-1
- Upgrade to 5.18 (#2096472)
* Mon Apr 04 2022 Robert Scheck <robert@fedoraproject.org> - 2:5.17-1
- Upgrade to 5.17 (#2071467)
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 2:5.16-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Wed Jan 19 2022 Robert Scheck <robert@fedoraproject.org> - 2:5.16-1
- Upgrade to 5.16 (#2042199)
* Wed Nov 10 2021 Robert Scheck <robert@fedoraproject.org> - 2:5.15-1
- Upgrade to 5.15 (#2021677)
* Mon Sep 13 2021 Robert Scheck <robert@fedoraproject.org> - 2:5.14-1
- Upgrade to 5.14 (#2003485)
* Wed Jul 21 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2:5.13-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Fri Jul 09 2021 Robert Scheck <robert@fedoraproject.org> - 2:5.13-1
- Upgrade to 5.13 (#1980586)
* Mon May 03 2021 Robert Scheck <robert@fedoraproject.org> - 2:5.12-1
- Upgrade to 5.12 (#1956130)
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2:5.10-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Mon Dec 21 2020 Robert Scheck <robert@fedoraproject.org> - 2:5.10-1
- Upgrade to 5.10 (#1908443)
* Fri Oct 16 2020 Robert Scheck <robert@fedoraproject.org> - 2:5.9-1
- Upgrade to 5.9 (#1888821)
* Tue Aug 04 2020 Robert Scheck <robert@fedoraproject.org> - 2:5.8-1
- Upgrade to 5.8 (#1866010)
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2:5.7-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Jun 05 2020 Robert Scheck <robert@fedoraproject.org> - 2:5.7-1
- Upgrade to 5.7 (#1844204)
* Tue May 12 2020 Robert Scheck <robert@fedoraproject.org> - 2:5.6-1
- Upgrade to 5.6 (#1834893)
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2:5.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Sun Jan 12 2020 Robert Scheck <robert@fedoraproject.org> - 2:5.4-1
- Upgrade to 5.4 (#1789949)
* Thu Sep 26 2019 Robert Scheck <robert@fedoraproject.org> - 2:5.3-1
- Upgrade to 5.3 (#1754625)
* Sat Aug 17 2019 Robert Scheck <robert@fedoraproject.org> - 2:5.2-1
- Upgrade to 5.2 (#1742322)
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2:5.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon May 20 2019 Robert Scheck <robert@fedoraproject.org> - 2:5.1-1
- Upgrade to 5.1 (#1711442)
* Sun Apr 28 2019 Robert Scheck <robert@fedoraproject.org> - 2:5.0-1
- Upgrade to 5.0 (#1622263)
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.17-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2:4.17-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Sat Jun 16 2018 Robert Scheck <robert@fedoraproject.org> - 2:4.17-1
- Update to 4.17 (#1591987)
* Sat Apr 14 2018 Robert Scheck <robert@fedoraproject.org> - 2:4.16-1
- Update to 4.16 (#1567447)

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

2
sources Normal file
View File

@ -0,0 +1,2 @@
SHA512 (ethtool-6.11.tar.sign) = 9a0ea5a1ab140a69bc13e844e2e919101ea0e3994a503b49ba5009e83ba4609d047c823dbc58b172ca0488591be066f43b66f1eea7597532930a83dddcc5e556
SHA512 (ethtool-6.11.tar.xz) = 77f649e1082a164e3627bcb21db1215a89d9a0e984f86516bb05879685aee76b034f6a9e19a499dcdd82883fa003f628b70d27ca8272064df27fe9de67c7a9a7